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 }