001 package org.apache.fulcrum.jetty.impl;
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.Startable;
023 import org.apache.avalon.framework.activity.Initializable;
024 import org.apache.avalon.framework.logger.AbstractLogEnabled;
025 import org.apache.avalon.framework.logger.LogEnabled;
026 import org.apache.avalon.framework.configuration.ConfigurationException;
027 import org.apache.avalon.framework.configuration.Configuration;
028 import org.apache.avalon.framework.configuration.Reconfigurable;
029 import org.apache.avalon.framework.context.Contextualizable;
030 import org.apache.avalon.framework.context.Context;
031 import org.apache.avalon.framework.context.ContextException;
032 import org.apache.fulcrum.jetty.JettyService;
033
034 import org.mortbay.jetty.Server;
035 import org.mortbay.xml.XmlConfiguration;
036
037 import java.io.File;
038 import java.io.InputStream;
039 import java.io.IOException;
040 import java.io.FileInputStream;
041
042 /**
043 * Starts an instance of the Spring Service Framework as Avalon service.
044 *
045 * @author <a href="mailto:siegfried.goeschl@it20one.at">Siegfried Goeschl</a>
046 */
047
048 public class JettyServiceImpl
049 extends AbstractLogEnabled
050 implements LogEnabled, Startable, Contextualizable, Initializable, Reconfigurable, JettyService
051 {
052 /** the Jetty server instance */
053 private Server server;
054
055 /** the location of the Jetty XML configuration files */
056 private String[] configurationLocations;
057
058 /** the working directory of the service */
059 private File serviceApplicationDir;
060
061 /////////////////////////////////////////////////////////////////////////
062 // Avalon Lifecycle Implementation
063 /////////////////////////////////////////////////////////////////////////
064
065 /**
066 * Constructor
067 */
068 public JettyServiceImpl()
069 {
070 // nothing to do
071 }
072
073 public void contextualize(Context context) throws ContextException
074 {
075 this.serviceApplicationDir = (File) context.get("context-root");
076 }
077
078 /**
079 * @see org.apache.avalon.framework.configuration.Configurable#configure(org.apache.avalon.framework.configuration.Configuration)
080 */
081 public void configure(Configuration configuration) throws ConfigurationException
082 {
083 // parse the 'configurations'
084
085 Configuration[] configurationsList = configuration.getChild("configurations").getChildren("configuration");
086 this.configurationLocations = new String[configurationsList.length];
087
088 for(int i=0; i<this.configurationLocations.length; i++)
089 {
090 this.configurationLocations[i] = configurationsList[i].getValue();
091 }
092
093 if(this.configurationLocations.length == 0)
094 {
095 String msg = "No configuration files for the Jetty are defined";
096 throw new ConfigurationException(msg);
097 }
098
099 // parse the 'properties'
100
101 Configuration[] propertiesConfiguration = configuration.getChild("properties", true).getChildren("property");
102
103 for( int i=0; i<propertiesConfiguration.length; i++ )
104 {
105 String key = propertiesConfiguration[i].getAttribute("name");
106 String value = propertiesConfiguration[i].getValue();
107 this.getLogger().info("Setting the system property '" + key + "'==>'" + value + "'");
108 System.setProperty( key, value );
109 }
110 }
111
112 /**
113 * @see org.apache.avalon.framework.activity.Initializable#initialize()
114 */
115 public void initialize() throws Exception
116 {
117 // locate the serviceConfiguration file and initialize Jetty server
118
119 Server currServer = new Server();
120
121 for(int i=0; i<this.configurationLocations.length; i++)
122 {
123 String currConfigurationLocation = this.configurationLocations[i];
124 this.getLogger().info("Loading the Jetty serviceConfiguration file : " + currConfigurationLocation);
125 InputStream is = this.locate(this.serviceApplicationDir, currConfigurationLocation);
126 XmlConfiguration configuration = new XmlConfiguration(is);
127 configuration.configure(currServer);
128 is.close();
129 }
130
131 this.server = currServer;
132 }
133
134 /**
135 * @see org.apache.avalon.framework.activity.Startable#start()
136 */
137 public void start() throws Exception
138 {
139 this.getServer().start();
140 }
141
142 /**
143 * @see org.apache.avalon.framework.activity.Startable#stop()
144 */
145 public void stop() throws Exception
146 {
147 this.getServer().stop();
148 }
149
150 /**
151 * @see org.apache.avalon.framework.configuration.Reconfigurable#reconfigure(org.apache.avalon.framework.configuration.Configuration)
152 */
153 public void reconfigure(Configuration configuration) throws ConfigurationException
154 {
155 if(configuration != null)
156 {
157 this.configure(configuration);
158 }
159
160 try
161 {
162 this.initialize();
163 }
164 catch(Exception e)
165 {
166 String msg = "Initializing the new server failed";
167 throw new ConfigurationException(msg, e);
168 }
169 }
170
171 /////////////////////////////////////////////////////////////////////////
172 // Service Interface Implementation
173 /////////////////////////////////////////////////////////////////////////
174
175 public Server getServer()
176 {
177 return this.server;
178 }
179
180 /////////////////////////////////////////////////////////////////////////
181 // Service Implementation
182 /////////////////////////////////////////////////////////////////////////
183
184 /**
185 * Locate the configuration file using the file system or a classpath.
186 *
187 * @param applicationDir the directory where to start the search
188 * @param location the location of the source to be loaded
189 * @return the input stream of the resource
190 * @exception IOException the operation failed
191 */
192 private InputStream locate( File applicationDir, String location ) throws IOException
193 {
194 if( ( location == null ) || ( location.length() == 0 ) )
195 {
196 throw new IllegalArgumentException("location is null or empty");
197 }
198
199 File file = null;
200 InputStream is = null;
201
202 // try to load a relative location with the given root dir
203 // e.g. "jetty.xml" located in the current working directory
204
205 if( !location.startsWith("/") )
206 {
207 file = new File( applicationDir, location );
208
209 this.getLogger().debug("Looking for " + location + " in the application directory");
210
211 if( file.exists() )
212 {
213 is = new FileInputStream( file );
214 this.getLogger().debug("Found " + location + " as " + file.getAbsolutePath() );
215 }
216 }
217
218 // try to load an absolute location as file
219 // e.g. "/foo/jetty.xml" from the root of the file system
220
221 if( ( is == null ) && (location.startsWith("/")) )
222 {
223 file = new File( location );
224
225 this.getLogger().debug("Looking for " + location + " as absolute file location");
226
227 if( file.isAbsolute() && file.exists() )
228 {
229 is = new FileInputStream( file );
230 this.getLogger().debug("Found " + location + " as " + file.getAbsolutePath() );
231 }
232 }
233
234 // try to load an absolute location through the classpath
235 // e.g. "/jetty.xml" located in the classpath
236
237 if( ( is == null ) && (location.startsWith("/")) )
238 {
239 this.getLogger().debug("Looking for " + location + " using the class loader");
240 is = getClass().getResourceAsStream( location );
241
242 if( is != null )
243 {
244 this.getLogger().debug("Successfully located " + location);
245 }
246 }
247
248 if( is == null )
249 {
250 this.getLogger().warn("Unable to find any resource with the name '" + location + "'");
251 }
252
253 return is;
254 }
255 }