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    }