1 //========================================================================
2 //Copyright 2006-2007 Sabre Holdings.
3 //------------------------------------------------------------------------
4 //Licensed under the Apache License, Version 2.0 (the "License");
5 //you may not use this file except in compliance with the License.
6 //You may obtain a copy of the License at
7 //http://www.apache.org/licenses/LICENSE-2.0
8 //Unless required by applicable law or agreed to in writing, software
9 //distributed under the License is distributed on an "AS IS" BASIS,
10 //WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 //See the License for the specific language governing permissions and
12 //limitations under the License.
13 //========================================================================
15 package org
.mortbay
.jetty
.ant
;
18 import java
.util
.ArrayList
;
19 import java
.util
.Iterator
;
20 import java
.util
.List
;
22 import org
.apache
.tools
.ant
.BuildException
;
23 import org
.apache
.tools
.ant
.Task
;
24 import org
.apache
.tools
.ant
.taskdefs
.Property
;
25 import org
.mortbay
.jetty
.RequestLog
;
26 import org
.mortbay
.jetty
.ant
.types
.Connectors
;
27 import org
.mortbay
.jetty
.ant
.types
.SystemProperties
;
28 import org
.mortbay
.jetty
.ant
.types
.UserRealms
;
29 import org
.mortbay
.jetty
.ant
.types
.WebApp
;
30 import org
.mortbay
.jetty
.ant
.utils
.ServerProxy
;
31 import org
.mortbay
.jetty
.ant
.utils
.TaskLog
;
32 import org
.mortbay
.util
.Scanner
;
35 * Ant task for running a Jetty server.
37 * @author Jakub Pawlowicz
39 public class JettyRunTask
extends Task
42 /** Temporary files directory. */
43 private File tempDirectory
;
45 /** List of web applications to be deployed. */
46 private List webapps
= new ArrayList();
48 /** Location of jetty.xml file. */
49 private File jettyXml
;
51 /** List of server connectors. */
52 private Connectors connectors
= null;
54 /** Server request logger object. */
55 private RequestLog requestLog
;
57 /** List of user realms. */
58 private UserRealms userRealms
;
60 /** List of system properties to be set. */
61 private SystemProperties systemProperties
;
64 * Creates a new <code>WebApp</code> Ant object.
66 * @return a WebApp object.
68 public void addWebApp(WebApp webapp
)
74 * Adds a new Ant's connector tag object if it have not been created yet.
76 public void addConnectors(Connectors connectors
)
78 if (this.connectors
!= null)
80 throw new BuildException("Only one <connectors> tag is allowed!");
83 this.connectors
= connectors
;
87 * @return a new Ant's connector tag object if it have not been created yet.
89 public void addUserRealms(UserRealms realms
)
91 if (this.userRealms
!= null)
93 throw new BuildException("Only one <userRealms> tag is allowed!");
96 this.userRealms
= realms
;
99 public void addSystemProperties(SystemProperties systemProperties
)
101 if (this.systemProperties
!= null)
103 throw new BuildException("Only one <systemProperties> tag is allowed!");
106 this.systemProperties
= systemProperties
;
109 public File
getTempDirectory()
111 return tempDirectory
;
114 public void setTempDirectory(File tempDirectory
)
116 this.tempDirectory
= tempDirectory
;
119 public File
getJettyXml()
124 public void setJettyXml(File jettyXml
)
126 this.jettyXml
= jettyXml
;
129 public void setRequestLog(String className
)
133 this.requestLog
= (RequestLog
) Class
.forName(className
).newInstance();
135 catch (InstantiationException e
)
137 throw new BuildException("Request logger instantiation exception: " + e
);
139 catch (IllegalAccessException e
)
141 throw new BuildException("Request logger instantiation exception: " + e
);
143 catch (ClassNotFoundException e
)
145 throw new BuildException("Unknown request logger class: " + className
);
149 public String
getRequestLog()
151 if (requestLog
!= null)
153 return requestLog
.getClass().getName();
160 * Executes this Ant task. The build flow is being stopped until Jetty
163 * @throws BuildException
165 public void execute() throws BuildException
167 TaskLog
.setTask(this);
168 TaskLog
.log("Configuring Jetty for project: " + getProject().getName());
169 WebApplicationProxyImpl
.setBaseTempDirectory(tempDirectory
);
170 setSystemProperties();
172 List connectorsList
= (connectors
!= null ? connectors
.getConnectors()
173 : Connectors
.DEFAULT_CONNECTORS
);
174 List userRealmsList
= (userRealms
!= null ? userRealms
.getUserRealms() : new ArrayList());
175 ServerProxy server
= new ServerProxyImpl(connectorsList
, userRealmsList
, requestLog
,
178 Iterator iterator
= webapps
.iterator();
179 while (iterator
.hasNext())
181 WebApp webAppConfiguration
= (WebApp
) iterator
.next();
182 WebApplicationProxyImpl webApp
= new WebApplicationProxyImpl(webAppConfiguration
184 webApp
.setSourceDirectory(webAppConfiguration
.getWarFile());
185 webApp
.setContextPath(webAppConfiguration
.getContextPath());
186 webApp
.setWebXml(webAppConfiguration
.getWebXmlFile());
187 webApp
.setJettyEnvXml(webAppConfiguration
.getJettyEnvXml());
188 webApp
.setClassPathFiles(webAppConfiguration
.getClassPathFiles());
189 webApp
.setLibrariesConfiguration(webAppConfiguration
.getLibrariesConfiguration());
190 webApp
.setExtraScanTargetsConfiguration(webAppConfiguration
191 .getScanTargetsConfiguration());
192 webApp
.setContextHandlers(webAppConfiguration
.getContextHandlers());
194 server
.addWebApplication(webApp
, webAppConfiguration
.getScanIntervalSeconds());
201 * Starts a new thread which scans project files and automatically reloads a
202 * container on any changes.
204 * @param scanIntervalSeconds
209 static void startScanner(final WebApplicationProxyImpl webApp
, int scanIntervalSeconds
)
211 List scanList
= new ArrayList();
212 scanList
.add(webApp
.getWebXmlFile());
213 scanList
.addAll(webApp
.getLibraries());
214 scanList
.addAll(webApp
.getExtraScanTargets());
216 Scanner
.Listener changeListener
= new Scanner
.BulkListener()
219 public void filesChanged(List changedFiles
)
221 if (hasAnyFileChanged(changedFiles
))
226 webApp
.applyConfiguration();
237 * Checks if any file in this particular application has changed.
238 * This is not that easy, because some applications may use the same
239 * class'es directory.
241 * @param changedFiles list of changed files.
242 * @return true if any of passed files has changed, false otherwise.
244 private boolean hasAnyFileChanged(List changedFiles
)
246 Iterator changes
= changedFiles
.iterator();
247 while (changes
.hasNext())
249 String className
= (String
) changes
.next();
250 if (webApp
.isFileScanned(className
))
260 TaskLog
.log("Web application '" + webApp
.getName() + "': starting scanner at interval of "
261 + scanIntervalSeconds
+ " seconds.");
263 Scanner scanner
= new Scanner();
264 scanner
.setScanInterval(scanIntervalSeconds
);
265 scanner
.addListener(changeListener
);
266 scanner
.setScanDirs(scanList
);
267 scanner
.setReportExistingFilesOnStartup(false);
272 * Sets the system properties.
274 private void setSystemProperties()
276 if (systemProperties
!= null)
278 Iterator propertiesIterator
= systemProperties
.getSystemProperties().iterator();
279 while (propertiesIterator
.hasNext())
281 Property property
= ((Property
) propertiesIterator
.next());
282 SystemProperties
.setIfNotSetAlready(property
);