001 package org.apache.fulcrum.spring;
002
003 /*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements. See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership. The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License. You may obtain a copy of the License at
011 *
012 * http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied. See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022 import org.apache.avalon.framework.activity.Disposable;
023 import org.apache.avalon.framework.activity.Initializable;
024 import org.apache.avalon.framework.logger.AbstractLogEnabled;
025 import org.apache.avalon.framework.service.ServiceException;
026 import org.apache.avalon.framework.service.ServiceManager;
027 import org.apache.avalon.framework.configuration.Configurable;
028 import org.apache.avalon.framework.configuration.ConfigurationException;
029 import org.apache.avalon.framework.configuration.Configuration;
030 import org.springframework.context.support.AbstractApplicationContext;
031 import org.springframework.context.support.FileSystemXmlApplicationContext;
032
033 /**
034 * Starts an instance of the Spring Service Framework as Avalon service.
035 *
036 * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a>
037 */
038
039 public class SpringFrameworkServiceImpl
040 extends AbstractLogEnabled
041 implements SpringFrameworkService, Configurable, Initializable, Disposable, ServiceManager
042 {
043 /** the list of configuration files passed to the Spring container */
044 private String[] configLocations;
045
046 /** the Spring service container */
047 private AbstractApplicationContext ctx;
048
049 /** ServiceManager facade to lookup Spring services */
050 private BeanFactoryServiceManager beanFactoryServiceManager;
051
052 /////////////////////////////////////////////////////////////////////////
053 // Avalon Service Lifecycle Implementation
054 /////////////////////////////////////////////////////////////////////////
055
056 /**
057 * Constructor
058 */
059 public SpringFrameworkServiceImpl()
060 {
061 this.configLocations = new String[0];
062 }
063
064 /**
065 * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
066 */
067 public void configure(Configuration configuration) throws ConfigurationException
068 {
069
070 // parse the 'configLocations' to passed to Spring
071
072 Configuration[] configLocationConfigurationList = configuration.getChild("configurations").getChildren("configuration");
073 this.configLocations = new String[configLocationConfigurationList.length];
074
075 for(int i=0; i<configLocations.length; i++)
076 {
077 this.configLocations[i] = configLocationConfigurationList[i].getValue();
078 }
079
080 if(this.configLocations.length == 0)
081 {
082 String msg = "No configuration files for the Spring container are defined";
083 throw new ConfigurationException(msg);
084 }
085 }
086
087 /**
088 * @see org.apache.avalon.framework.activity.Initializable#initialize()
089 */
090 public void initialize() throws Exception
091 {
092 this.ctx = new FileSystemXmlApplicationContext(this.configLocations);
093 this.beanFactoryServiceManager = new BeanFactoryServiceManager(ctx);
094 }
095
096 /**
097 * @see org.apache.avalon.framework.activity.Disposable#dispose()
098 */
099 public void dispose()
100 {
101 if(this.ctx != null)
102 {
103 try
104 {
105 this.ctx.close();
106 }
107 catch(Exception e)
108 {
109 String msg = "Failed to dispose the Spring service";
110 this.getLogger().error(msg, e);
111 }
112 finally
113 {
114 this.ctx = null;
115 }
116 }
117
118 this.beanFactoryServiceManager = null;
119 }
120
121 /////////////////////////////////////////////////////////////////////////
122 // Service interface implementation
123 /////////////////////////////////////////////////////////////////////////
124
125 /** @see SpringFrameworkService#getAbstractApplicationContext() */
126 public AbstractApplicationContext getAbstractApplicationContext()
127 {
128 return this.ctx;
129 }
130
131 /** @see org.apache.avalon.framework.service.ServiceManager#lookup(String) */
132 public Object lookup(String key) throws ServiceException
133 {
134 if(this.beanFactoryServiceManager == null)
135 {
136 throw new RuntimeException("The SpringFrameworkService is not yet initialized");
137 }
138
139 return this.beanFactoryServiceManager.lookup(key);
140 }
141
142 /** @see org.apache.avalon.framework.service.ServiceManager#hasService(String) */
143 public boolean hasService(String key)
144 {
145 if(this.beanFactoryServiceManager == null)
146 {
147 throw new RuntimeException("The SpringFrameworkService is not yet initialized");
148 }
149
150 return this.beanFactoryServiceManager.hasService(key);
151 }
152
153 /** @see org.apache.avalon.framework.service.ServiceManager#release(Object) */
154 public void release(Object o)
155 {
156 if(this.beanFactoryServiceManager == null)
157 {
158 throw new RuntimeException("The SpringFrameworkService is not yet initialized");
159 }
160
161 this.beanFactoryServiceManager.release(o);
162 }
163 }