CQ-3581 jetty-osgi contribution from Hugues Malphettes of intalio
git-svn-id: svn+ssh://dev.eclipse.org/svnroot/rt/org.eclipse.jetty/jetty/trunk@1023 7e9141cc-0065-0410-87d8-b60c137991c4
This commit is contained in:
parent
b170e765f3
commit
ebdc841479
|
@ -0,0 +1,19 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Jetty-OSGi-Jasper integration
|
||||
Fragment-Host: org.eclipse.jetty.osgi.boot
|
||||
Bundle-SymbolicName: org.eclipse.jetty.osgi.boot.jasper;singleton:=true
|
||||
Bundle-Version: 7.0.1.qualifier
|
||||
Bundle-Vendor: Intalio Inc
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
Require-Bundle: org.mortbay.jetty.jsp-2.1;bundle-version="[7.0,8)",
|
||||
org.mortbay.jetty.jsp-2.1-glassfish;bundle-version="9.1.1"
|
||||
Import-Package: javax.el;version="2.1",
|
||||
javax.servlet.jsp;version="2.1",
|
||||
javax.servlet.jsp.el;version="2.1",
|
||||
javax.servlet.jsp.jstl.core;version="2.1",
|
||||
javax.servlet.jsp.jstl.fmt;version="2.1",
|
||||
javax.servlet.jsp.jstl.sql;version="2.1",
|
||||
javax.servlet.jsp.jstl.tlv;version="2.1",
|
||||
javax.servlet.jsp.resources;version="2.1",
|
||||
javax.servlet.jsp.tagext;version="2.1"
|
|
@ -0,0 +1,187 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.boot.jasper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.servlet.jsp.JspContext;
|
||||
|
||||
import org.apache.jasper.Constants;
|
||||
import org.apache.jasper.compiler.Localizer;
|
||||
import org.apache.jasper.compiler.TldLocationsCache;
|
||||
import org.apache.jasper.xmlparser.ParserUtils;
|
||||
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper;
|
||||
import org.eclipse.jetty.osgi.boot.utils.WebappRegistrationCustomizer;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.xml.sax.EntityResolver;
|
||||
import org.xml.sax.InputSource;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Fix various shortcomings with the way jasper parses the tld files.
|
||||
*/
|
||||
public class WebappRegistrationCustomizerImpl implements WebappRegistrationCustomizer
|
||||
{
|
||||
|
||||
public WebappRegistrationCustomizerImpl()
|
||||
{
|
||||
fixupDtdResolution();
|
||||
try
|
||||
{
|
||||
Class<?> cl = getClass().getClassLoader().loadClass(
|
||||
"org.apache.jasper.servlet.JspServlet");
|
||||
System.err.println("found the jsp servlet: " + cl.getName());
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: right now only the jetty-jsp bundle is scanned for common taglibs. Should support a way to plug more bundles that contain taglibs.
|
||||
*
|
||||
* The jasper TldScanner expects a URLClassloader to parse a jar for the /META-INF/*.tld it may contain. We place the bundles that we know contain such
|
||||
* tag-libraries. Please note that it will work if and only if the bundle is a jar (!) Currently we just hardcode the bundle that contains the jstl
|
||||
* implemenation.
|
||||
*
|
||||
* A workaround when the tld cannot be parsed with this method is to copy and paste it inside the WEB-INF of the webapplication where it is used.
|
||||
*
|
||||
* Support only 2 types of packaging for the bundle: - the bundle is a jar (recommended for runtime.) - the bundle is a folder and contain jars in the root
|
||||
* and/or in the lib folder (nice for PDE developement situations) Unsupported: the bundle is a jar that embeds more jars.
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public URL[] getJarsWithTlds(BundleFileLocatorHelper locatorHelper) throws Exception
|
||||
{
|
||||
Bundle jasperBundler = FrameworkUtil.getBundle(TldLocationsCache.class);
|
||||
File jasperLocation = locatorHelper.getBundleInstallLocation(jasperBundler);
|
||||
if (jasperLocation.isDirectory())
|
||||
{
|
||||
// try to find the jar files inside this folder
|
||||
ArrayList<URL> urls = new ArrayList<URL>();
|
||||
for (File f : jasperLocation.listFiles())
|
||||
{
|
||||
if (f.getName().endsWith(".jar") && f.isFile())
|
||||
{
|
||||
urls.add(f.toURI().toURL());
|
||||
}
|
||||
else if (f.isDirectory() && f.getName().equals("lib"))
|
||||
{
|
||||
for (File f2 : jasperLocation.listFiles())
|
||||
{
|
||||
if (f2.getName().endsWith(".jar") && f2.isFile())
|
||||
{
|
||||
urls.add(f2.toURI().toURL());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return urls.toArray(new URL[urls.size()]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new URL[] { jasperLocation.toURI().toURL() };
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Jasper resolves the dtd when it parses a taglib descriptor.
|
||||
* It uses this code to do that: ParserUtils.getClass().getResourceAsStream(resourcePath); where
|
||||
* resourcePath is for example: /javax/servlet/jsp/resources/web-jsptaglibrary_1_2.dtd Unfortunately,
|
||||
* the dtd file is not in the exact same classloader as
|
||||
* ParserUtils class and the dtds are packaged in 2 separate bundles.
|
||||
* OSGi does not look in the dependencies' classloader when a resource is searched.
|
||||
* <p>
|
||||
* The workaround consists of setting the entity resolver. That is a patch
|
||||
* added to the version of glassfish-jasper-jetty. IT is also present in the latest
|
||||
* version of glassfish jasper. Could not use introspection to set new value
|
||||
* on a static friendly field :(
|
||||
* </p>
|
||||
*/
|
||||
void fixupDtdResolution()
|
||||
{
|
||||
try
|
||||
{
|
||||
ParserUtils.setEntityResolver(new MyFixedupEntityResolver());
|
||||
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Instead of using the ParserUtil's classloader, we use a class that is indeed next to the resource for sure.
|
||||
*/
|
||||
static class MyFixedupEntityResolver implements EntityResolver
|
||||
{
|
||||
/**
|
||||
* Same values than in ParserUtils...
|
||||
*/
|
||||
static final String[] CACHED_DTD_PUBLIC_IDS =
|
||||
{ Constants.TAGLIB_DTD_PUBLIC_ID_11, Constants.TAGLIB_DTD_PUBLIC_ID_12,
|
||||
Constants.WEBAPP_DTD_PUBLIC_ID_22, Constants.WEBAPP_DTD_PUBLIC_ID_23, };
|
||||
|
||||
static final String[] CACHED_DTD_RESOURCE_PATHS =
|
||||
{ Constants.TAGLIB_DTD_RESOURCE_PATH_11,
|
||||
Constants.TAGLIB_DTD_RESOURCE_PATH_12,
|
||||
Constants.WEBAPP_DTD_RESOURCE_PATH_22,
|
||||
Constants.WEBAPP_DTD_RESOURCE_PATH_23, };
|
||||
|
||||
// static final String[] CACHED_SCHEMA_RESOURCE_PATHS = {
|
||||
// Constants.TAGLIB_SCHEMA_RESOURCE_PATH_20,
|
||||
// Constants.TAGLIB_SCHEMA_RESOURCE_PATH_21,
|
||||
// Constants.WEBAPP_SCHEMA_RESOURCE_PATH_24,
|
||||
// Constants.WEBAPP_SCHEMA_RESOURCE_PATH_25,
|
||||
// };
|
||||
public InputSource resolveEntity(String publicId, String systemId) throws SAXException
|
||||
{
|
||||
for (int i = 0; i < CACHED_DTD_PUBLIC_IDS.length; i++)
|
||||
{
|
||||
String cachedDtdPublicId = CACHED_DTD_PUBLIC_IDS[i];
|
||||
if (cachedDtdPublicId.equals(publicId))
|
||||
{
|
||||
String resourcePath = CACHED_DTD_RESOURCE_PATHS[i];
|
||||
InputStream input = null;
|
||||
input = JspContext.class.getResourceAsStream(resourcePath);
|
||||
if (input == null)
|
||||
{
|
||||
// if that failed try again with the original code:
|
||||
// although it is likely not changed.
|
||||
input = this.getClass().getResourceAsStream(resourcePath);
|
||||
}
|
||||
if (input == null)
|
||||
{
|
||||
throw new SAXException(Localizer.getMessage("jsp.error.internal.filenotfound",resourcePath));
|
||||
}
|
||||
InputSource isrc = new InputSource(input);
|
||||
return isrc;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,47 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Jetty OSGi bootstrap
|
||||
Bundle-SymbolicName: org.eclipse.jetty.osgi.boot;singleton:=true
|
||||
Bundle-Version: 7.0.1.qualifier
|
||||
Bundle-Activator: org.eclipse.jetty.osgi.boot.JettyBootstrapActivator
|
||||
Import-Package: javax.mail;resolution:=optional,
|
||||
javax.mail.event;resolution:=optional,
|
||||
javax.mail.internet;resolution:=optional,
|
||||
javax.mail.search;resolution:=optional,
|
||||
javax.mail.util;resolution:=optional,
|
||||
javax.naming;resolution:=optional,
|
||||
javax.naming.directory;resolution:=optional,
|
||||
javax.security.auth;resolution:=optional,
|
||||
javax.security.auth.callback;resolution:=optional,
|
||||
javax.security.auth.login;resolution:=optional,
|
||||
javax.security.auth.spi;resolution:=optional,
|
||||
javax.servlet,
|
||||
javax.servlet.http,
|
||||
javax.transaction;version="1.1.0";resolution:=optional,
|
||||
javax.transaction.xa;version="1.1.0";resolution:=optional,
|
||||
org.osgi.framework,
|
||||
org.osgi.service.cm;version="1.2.0",
|
||||
org.osgi.service.startlevel;version="1.0",
|
||||
org.xml.sax
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
Require-Bundle: org.eclipse.jetty.ajp;bundle-version="[7.0,8)";resolution:=optional,
|
||||
org.eclipse.jetty.annotations;bundle-version="[7.0,8)";resolution:=optional,
|
||||
org.eclipse.jetty.client;bundle-version="[7.0,8)";resolution:=optional,
|
||||
org.eclipse.jetty.continuation;bundle-version="[7.0,8)";resolution:=optional,
|
||||
org.eclipse.jetty.deploy;bundle-version="[7.0,8)",
|
||||
org.eclipse.jetty.http;bundle-version="[7.0,8)",
|
||||
org.eclipse.jetty.io;bundle-version="[7.0,8)",
|
||||
org.eclipse.jetty.jmx;bundle-version="[7.0,8)";resolution:=optional,
|
||||
org.eclipse.jetty.jndi;bundle-version="[7.0,8)";resolution:=optional,
|
||||
org.eclipse.jetty.plus;bundle-version="[7.0,8.0)";resolution:=optional,
|
||||
org.eclipse.jetty.rewrite;bundle-version="[7.0,8)";resolution:=optional,
|
||||
org.eclipse.jetty.security;bundle-version="[7.0,8)";resolution:=optional,
|
||||
org.eclipse.jetty.server;bundle-version="[7.0,8)",
|
||||
org.eclipse.jetty.servlet;bundle-version="[7.0,8)",
|
||||
org.eclipse.jetty.servlets;bundle-version="[7.0,8)";resolution:=optional,
|
||||
org.eclipse.jetty.util;bundle-version="[7.0,8)",
|
||||
org.eclipse.jetty.webapp;bundle-version="[7.0,8)",
|
||||
org.eclipse.jetty.xml;bundle-version="[7.0,8)"
|
||||
Export-Package: org.eclipse.jetty.osgi.boot,
|
||||
org.eclipse.jetty.osgi.boot.utils
|
||||
Bundle-ActivationPolicy: lazy
|
|
@ -0,0 +1,15 @@
|
|||
source.. = src/main/java/
|
||||
output.. = target/classes/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
jettyhome/
|
||||
bin.excludes = jettyhome/logs/2009_09_21.request.log,\
|
||||
jettyhome/lib/atomikos-util-3.5.8.jar,\
|
||||
jettyhome/lib/transactions-3.5.8.jar,\
|
||||
jettyhome/lib/transactions-api-3.5.8.jar,\
|
||||
jettyhome/lib/transactions-jdbc-3.5.8.jar,\
|
||||
jettyhome/lib/transactions-jta-3.5.8.jar,\
|
||||
jettyhome/lib/ext/derby-10.4.1.3.jar,\
|
||||
jettyhome/lib/ext/derbytools-10.4.1.3.jar
|
||||
src.includes = META-INF/,\
|
||||
jettyhome/
|
|
@ -0,0 +1,2 @@
|
|||
Default locations for standard context definitions.
|
||||
Those applications are unlikely to have access to the OSGi framework currently.
|
|
@ -0,0 +1,2 @@
|
|||
This folder contains the default jetty configurations file for the server.
|
||||
In production, it is likely to be a different folder outside of the jetty's bootstrap plugin.
|
|
@ -0,0 +1,72 @@
|
|||
#
|
||||
# This is a sample properties file for the org.mortbay.jetty.security.JDBCUserRealm
|
||||
# implemtation of the UserRealm interface. This allows Jetty users authentication
|
||||
# to work from a database.
|
||||
#
|
||||
# +-------+ +------------+ +-------+
|
||||
# | users | | user_roles | | roles |
|
||||
# +-------+ +------------+ +-------+
|
||||
# | id | /| user_id |\ | id |
|
||||
# | user -------| role_id |------- role |
|
||||
# | pwd | \| |/ | |
|
||||
# +-------+ +------------+ +-------+
|
||||
#
|
||||
#
|
||||
# 'cachetime' is a time in seconds to cache positive database
|
||||
# lookups in internal hash table. Set to 0 to disable caching.
|
||||
#
|
||||
#
|
||||
# For MySQL:
|
||||
# create a MYSQL user called "jetty" with password "jetty"
|
||||
#
|
||||
# Create the tables:
|
||||
# create table users
|
||||
# (
|
||||
# id integer primary key,
|
||||
# username varchar(100) not null unique key,
|
||||
# pwd varchar(20) not null
|
||||
# );
|
||||
#
|
||||
# create table roles
|
||||
# (
|
||||
# id integer primary key,
|
||||
# role varchar(100) not null unique key
|
||||
# );
|
||||
#
|
||||
# create table user_roles
|
||||
# (
|
||||
# user_id integer not null,
|
||||
# role_id integer not null,
|
||||
# unique key (user_id, role_id),
|
||||
# index(user_id)
|
||||
# );
|
||||
#
|
||||
# I'm not sure unique key with a first component of user_id will be
|
||||
# user by MySQL in query, so additional index wouldn't hurt.
|
||||
#
|
||||
# To test JDBC implementation:
|
||||
#
|
||||
# mysql> insert into users values (1, 'admin', 'password');
|
||||
# mysql> insert into roles values (1, 'server-administrator');
|
||||
# mysql> insert into roles values (2, 'content-administrator');
|
||||
# mysql> insert into user_roles values (1, 1);
|
||||
# mysql> insert into user_roles values (1, 2);
|
||||
#
|
||||
# Replace HashUserRealm in etc/admin.xml with JDBCUserRealm and
|
||||
# set path to properties file.
|
||||
#
|
||||
jdbcdriver = org.gjt.mm.mysql.Driver
|
||||
url = jdbc:mysql://localhost/jetty
|
||||
username = jetty
|
||||
password = jetty
|
||||
usertable = users
|
||||
usertablekey = id
|
||||
usertableuserfield = username
|
||||
usertablepasswordfield = pwd
|
||||
roletable = roles
|
||||
roletablekey = id
|
||||
roletablerolefield = role
|
||||
userroletable = user_roles
|
||||
userroletableuserkey = user_id
|
||||
userroletablerolekey = role_id
|
||||
cachetime = 300
|
|
@ -0,0 +1,18 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
|
||||
|
||||
<Configure id="Server" class="org.mortbay.jetty.Server">
|
||||
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- Add a AJP listener on port 8009 -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<Call name="addConnector">
|
||||
<Arg>
|
||||
<New class="org.mortbay.jetty.ajp.Ajp13SocketConnector">
|
||||
<Set name="port">8009</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
</Configure>
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Mixin configuration for Block socket connector -->
|
||||
<!-- -->
|
||||
<!-- =============================================================== -->
|
||||
|
||||
|
||||
<Configure id="Server" class="org.mortbay.jetty.Server">
|
||||
|
||||
<!-- Use this connector if NIO is not available. -->
|
||||
<Call name="addConnector">
|
||||
<Arg>
|
||||
<New class="org.mortbay.jetty.bio.SocketConnector">
|
||||
<Set name="port"><SystemProperty name="jetty.bio.port" default="8081"/></Set>
|
||||
<Set name="maxIdleTime">50000</Set>
|
||||
<Set name="lowResourceMaxIdleTime">1500</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
</Configure>
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
|
||||
|
||||
<Configure id="Server" class="org.mortbay.jetty.Server">
|
||||
|
||||
|
||||
<!-- ======================================================== -->
|
||||
<!-- java.security.auth.login.config System property -->
|
||||
<!-- This is usually a runtime parameter to the jvm, but -->
|
||||
<!-- it is placed here for convenience. -->
|
||||
<!-- ======================================================== -->
|
||||
<Call class="java.lang.System" name="setProperty">
|
||||
<Arg>java.security.auth.login.config</Arg>
|
||||
<Arg><SystemProperty name="jetty.home" default="." />/etc/login.conf</Arg>
|
||||
</Call>
|
||||
|
||||
|
||||
<!-- ======================================================== -->
|
||||
<!-- An example JAAS realm setup -->
|
||||
<!-- For more information see the jetty wiki at -->
|
||||
<!-- http://http://docs.codehaus.org/display/JETTY/JAAS -->
|
||||
<!-- ======================================================== -->
|
||||
<Set name="UserRealms">
|
||||
<Array type="org.mortbay.jetty.security.UserRealm">
|
||||
<Item>
|
||||
<New class="org.mortbay.jetty.plus.jaas.JAASUserRealm">
|
||||
<Set name="Name">Test JAAS Realm</Set>
|
||||
<Set name="LoginModuleName">xyz</Set>
|
||||
</New>
|
||||
</Item>
|
||||
</Array>
|
||||
</Set>
|
||||
|
||||
|
||||
</Configure>
|
|
@ -0,0 +1,54 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
|
||||
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure the JVM JMX Server -->
|
||||
<!-- this configuration file should be used in combination with -->
|
||||
<!-- other configuration files. e.g. -->
|
||||
<!-- java -jar start.jar etc/jetty-jmx.xml etc/jetty.xml -->
|
||||
<!-- See jetty-jmx-mx4j.xml for a non JVM server solution -->
|
||||
<!-- =============================================================== -->
|
||||
<Configure id="Server" class="org.mortbay.jetty.Server">
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Initialize an mbean server -->
|
||||
<!-- =========================================================== -->
|
||||
<!-- Use the jdk 1.5 platformMBeanServer -->
|
||||
<Call id="MBeanServer" class="java.lang.management.ManagementFactory" name="getPlatformMBeanServer"/>
|
||||
|
||||
<!-- Use an mx4j mbean server - use this if running with jdk<1.5
|
||||
<Call id="MBeanServer" class="javax.management.MBeanServerFactory" name="createMBeanServer"/>
|
||||
-->
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Initialize the Jetty MBean container -->
|
||||
<!-- =========================================================== -->
|
||||
<Get id="Container" name="container">
|
||||
<Call name="addEventListener">
|
||||
<Arg>
|
||||
<New class="org.mortbay.management.MBeanContainer">
|
||||
<Arg><Ref id="MBeanServer"/></Arg>
|
||||
<!-- If using < jdk1.5 uncomment to start http adaptor -->
|
||||
<!-- Set name="managementPort">8082</Set -->
|
||||
<Call name="start" />
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
</Get>
|
||||
|
||||
<!-- optionally add a remote JMX connector
|
||||
<Call id="jmxConnector" class="javax.management.remote.JMXConnectorServerFactory" name="newJMXConnectorServer">
|
||||
<Arg>
|
||||
<New class="javax.management.remote.JMXServiceURL">
|
||||
<Arg>service:jmx:rmi:///jndi/rmi:///jettymbeanserver</Arg>
|
||||
</New>
|
||||
</Arg>
|
||||
<Arg/>
|
||||
<Arg><Ref id="MBeanServer"/></Arg>
|
||||
<Call name="start"/>
|
||||
</Call>
|
||||
-->
|
||||
|
||||
</Configure>
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
|
||||
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure stderr and stdout to a Jetty rollover log file -->
|
||||
<!-- this configuration file should be used in combination with -->
|
||||
<!-- other configuration files. e.g. -->
|
||||
<!-- java -jar start.jar etc/jetty-logging.xml etc/jetty.xml -->
|
||||
<!-- =============================================================== -->
|
||||
<Configure id="Server" class="org.mortbay.jetty.Server">
|
||||
|
||||
<New id="ServerLog" class="java.io.PrintStream">
|
||||
<Arg>
|
||||
<New class="org.mortbay.util.RolloverFileOutputStream">
|
||||
<Arg><SystemProperty name="jetty.home" default="."/>/logs/yyyy_mm_dd.stderrout.log</Arg>
|
||||
<Arg type="boolean">false</Arg>
|
||||
<Arg type="int">90</Arg>
|
||||
<Arg><Call class="java.util.TimeZone" name="getTimeZone"><Arg>GMT</Arg></Call></Arg>
|
||||
<Get id="ServerLogName" name="datedFilename"/>
|
||||
</New>
|
||||
</Arg>
|
||||
</New>
|
||||
|
||||
<Call class="org.mortbay.log.Log" name="info"><Arg>Redirecting stderr/stdout to <Ref id="ServerLogName"/></Arg></Call>
|
||||
<Call class="java.lang.System" name="setErr"><Arg><Ref id="ServerLog"/></Arg></Call>
|
||||
<Call class="java.lang.System" name="setOut"><Arg><Ref id="ServerLog"/></Arg></Call>
|
||||
|
||||
</Configure>
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure Jetty Plus features -->
|
||||
<!-- -->
|
||||
<!-- This file sets up a WebAppDeployer to automatically deploy all -->
|
||||
<!-- webapps in $jetty.home/webapps-plus at startup time, and to -->
|
||||
<!-- enable all of them with Plus features (jndi etc). -->
|
||||
<!-- -->
|
||||
<!-- You can instead configure individual webapps with Jetty Plus -->
|
||||
<!-- features by using the ContextDeployer (configured in -->
|
||||
<!-- $jetty.home/etc/jetty.xml), and ensuring that you set the -->
|
||||
<!-- same set of classes listed below in the "plusConfig" as the -->
|
||||
<!-- webapp's configurationClasses. -->
|
||||
<!-- -->
|
||||
<!-- For more information about Jetty Plus, see the Jetty wiki at -->
|
||||
<!-- http://docs.codehaus.org/display/JETTY/Jetty+Wiki -->
|
||||
<!-- =============================================================== -->
|
||||
<Configure id="Server" class="org.mortbay.jetty.Server">
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Example JAAS realm setup. -->
|
||||
<!-- The LoginModuleName must be exactly the same as in the -->
|
||||
<!-- login.conf file, and the realm Name must be the same as in -->
|
||||
<!-- the web.xml file. -->
|
||||
<!-- =========================================================== -->
|
||||
<!--
|
||||
<Call name="addUserRealm">
|
||||
<Arg>
|
||||
<New class="org.mortbay.jetty.plus.jaas.JAASUserRealm">
|
||||
<Set name="name">xyzrealm</Set>
|
||||
<Set name="LoginModuleName">xyz</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
-->
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Configurations for WebAppContexts -->
|
||||
<!-- Sequence of configurations to enable Plus features. -->
|
||||
<!-- =========================================================== -->
|
||||
<Array id="plusConfig" type="java.lang.String">
|
||||
<Item>org.mortbay.jetty.webapp.WebInfConfiguration</Item>
|
||||
<Item>org.mortbay.jetty.plus.webapp.EnvConfiguration</Item>
|
||||
<Item>org.mortbay.jetty.plus.webapp.Configuration</Item>
|
||||
<Item>org.mortbay.jetty.webapp.JettyWebXmlConfiguration</Item>
|
||||
<Item>org.mortbay.jetty.webapp.TagLibConfiguration</Item>
|
||||
</Array>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Deploy all webapps in webapps-plus -->
|
||||
<!-- =========================================================== -->
|
||||
<!-- Uncomment the following to set up a WebAppDeployer that will -->
|
||||
<!-- deploy webapps from a directory called webapps-plus. Note -->
|
||||
<!-- that you will need to create this directory first! -->
|
||||
<!--
|
||||
<Call name="addLifeCycle">
|
||||
<Arg>
|
||||
<New class="org.mortbay.jetty.deployer.WebAppDeployer">
|
||||
<Set name="contexts"><Ref id="Contexts"/></Set>
|
||||
<Set name="webAppDir"><SystemProperty name="jetty.home" default="."/>/webapps-plus</Set>
|
||||
<Set name="parentLoaderPriority">false</Set>
|
||||
<Set name="extract">true</Set>
|
||||
<Set name="allowDuplicates">false</Set>
|
||||
<Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
|
||||
<Set name="configurationClasses"><Ref id="plusConfig"/></Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
-->
|
||||
|
||||
</Configure>
|
||||
|
|
@ -0,0 +1,149 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Mixin the RewriteHandler -->
|
||||
<!-- =============================================================== -->
|
||||
|
||||
|
||||
<Configure id="Server" class="org.mortbay.jetty.Server">
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Configure Rewrite Handler -->
|
||||
<!-- =========================================================== -->
|
||||
<Get id="oldhandler" name="handler"/>
|
||||
|
||||
<Set name="handler">
|
||||
<New id="Rewrite" class="org.mortbay.jetty.handler.rewrite.RewriteHandler">
|
||||
|
||||
<Set name="handler"><Ref id="oldhandler"/></Set>
|
||||
<Set name="rewriteRequestURI">true</Set>
|
||||
<Set name="rewritePathInfo">false</Set>
|
||||
<Set name="originalPathAttribute">requestedPath</Set>
|
||||
|
||||
<Set name="rules">
|
||||
<Array type="org.mortbay.jetty.handler.rewrite.Rule">
|
||||
|
||||
<!-- return an error message if low on threads; put this at the top so it will be processed first -->
|
||||
<Item>
|
||||
<New id="lowThreads" class="org.mortbay.jetty.handler.rewrite.LowThreadsRuleContainer">
|
||||
<!-- set the trigger for low threads ridiculously low
|
||||
uncomment the block below to see it in action -->
|
||||
<!--Ref id="Server">
|
||||
<Get id="serverThreadPool" name="threadPool">
|
||||
<Set name="minThreads">3</Set>
|
||||
<Set name="maxThreads">4</Set>
|
||||
<Set name="lowThreads">0</Set>
|
||||
</Get>
|
||||
</Ref>
|
||||
|
||||
<Set name="threadPool"><Ref id="serverThreadPool"/></Set-->
|
||||
|
||||
<Call name="addRule">
|
||||
<Arg>
|
||||
<New id="busyresponse" class="org.mortbay.jetty.handler.rewrite.ResponsePatternRule">
|
||||
<Set name="pattern">/*</Set>
|
||||
<Set name="code">500</Set>
|
||||
<Set name="reason">Server busy</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
</Item>
|
||||
|
||||
<!-- Add rule to protect against IE ssl bug -->
|
||||
<Item>
|
||||
<New class="org.mortbay.jetty.handler.rewrite.MsieSslRule"/>
|
||||
</Item>
|
||||
|
||||
<!-- protect favicon handling -->
|
||||
<Item>
|
||||
<New class="org.mortbay.jetty.handler.rewrite.HeaderPatternRule">
|
||||
<Set name="pattern">/favicon.ico</Set>
|
||||
<Set name="name">Cache-Control</Set>
|
||||
<Set name="value">Max-Age=3600,public</Set>
|
||||
<Set name="terminating">true</Set>
|
||||
</New>
|
||||
</Item>
|
||||
|
||||
|
||||
<!-- add a regex rule -->
|
||||
<Item>
|
||||
<New class="org.mortbay.jetty.handler.rewrite.RewriteRegexRule">
|
||||
<Set name="regex">/rewrite/dump/regex/([^/]*)/(.*)</Set>
|
||||
<Set name="replacement">/test/dump/$2/$1</Set>
|
||||
</New>
|
||||
</Item>
|
||||
|
||||
<!-- add a rewrite rule -->
|
||||
<Item>
|
||||
<New id="" class="org.mortbay.jetty.handler.rewrite.RewritePatternRule">
|
||||
<Set name="pattern">/rewrite</Set>
|
||||
<Set name="replacement">/rewrittento</Set>
|
||||
</New>
|
||||
</Item>
|
||||
|
||||
<!-- add a response rule -->
|
||||
<Item>
|
||||
<New id="response" class="org.mortbay.jetty.handler.rewrite.ResponsePatternRule">
|
||||
<Set name="pattern">/rewrite/session/</Set>
|
||||
<Set name="code">401</Set>
|
||||
<Set name="reason">Setting error code 401</Set>
|
||||
</New>
|
||||
</Item>
|
||||
|
||||
<!-- add a header pattern rule -->
|
||||
<Item>
|
||||
<New id="header" class="org.mortbay.jetty.handler.rewrite.HeaderPatternRule">
|
||||
<Set name="pattern">*.jsp</Set>
|
||||
<Set name="name">Server</Set>
|
||||
<Set name="value">Server for JSP</Set>
|
||||
</New>
|
||||
</Item>
|
||||
|
||||
<!-- add a redirect -->
|
||||
<Item>
|
||||
<New id="redirect" class="org.mortbay.jetty.handler.rewrite.RedirectPatternRule">
|
||||
<Set name="pattern">/rewrite/dispatch</Set>
|
||||
<Set name="location">http://jetty.mortbay.org</Set>
|
||||
</New>
|
||||
</Item>
|
||||
|
||||
<Item>
|
||||
<New id="forwardedHttps" class="org.mortbay.jetty.handler.rewrite.ForwardedSchemeHeaderRule">
|
||||
<Set name="header">X-Forwarded-Scheme</Set>
|
||||
<Set name="headerValue">https</Set>
|
||||
<Set name="scheme">https</Set>
|
||||
</New>
|
||||
</Item>
|
||||
|
||||
<Item>
|
||||
<New id="virtualHost" class="org.mortbay.jetty.handler.rewrite.VirtualHostRuleContainer">
|
||||
|
||||
<Set name="virtualHosts">
|
||||
<Array type="java.lang.String">
|
||||
<Item>mortbay.com</Item>
|
||||
<Item>www.mortbay.com</Item>
|
||||
<Item>mortbay.org</Item>
|
||||
<Item>www.mortbay.org</Item>
|
||||
</Array>
|
||||
</Set>
|
||||
|
||||
<Call name="addRule">
|
||||
<Arg>
|
||||
<New class="org.mortbay.jetty.handler.rewrite.CookiePatternRule">
|
||||
<Set name="pattern">/*</Set>
|
||||
<Set name="name">CookiePatternRule</Set>
|
||||
<Set name="value">1</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
</New>
|
||||
</Item>
|
||||
</Array>
|
||||
</Set>
|
||||
</New>
|
||||
</Set>
|
||||
|
||||
</Configure>
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
|
||||
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure the Jetty SetUIDServer -->
|
||||
<!-- this configuration file should be used in combination with -->
|
||||
<!-- other configuration files. e.g. -->
|
||||
<!-- java -jar start.jar etc/jetty-setuid.xml etc/jetty.xml -->
|
||||
<!-- =============================================================== -->
|
||||
<Configure id="Server" class="org.mortbay.setuid.SetUIDServer">
|
||||
<Set name="startServerAsPrivileged">false</Set>
|
||||
<Set name="umask">2</Set>
|
||||
<Set name="uid">jetty</Set>
|
||||
<Set name="gid">jetty</Set>
|
||||
</Configure>
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure SSL for the Jetty Server -->
|
||||
<!-- this configuration file should be used in combination with -->
|
||||
<!-- other configuration files. e.g. -->
|
||||
<!-- java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml -->
|
||||
<!-- =============================================================== -->
|
||||
<Configure id="Server" class="org.mortbay.jetty.Server">
|
||||
|
||||
|
||||
|
||||
<Call name="addConnector">
|
||||
<Arg>
|
||||
<New class="org.mortbay.jetty.security.SslSocketConnector">
|
||||
<Set name="Port">8443</Set>
|
||||
<Set name="maxIdleTime">30000</Set>
|
||||
<Set name="handshakeTimeout">2000</Set>
|
||||
<Set name="keystore"><SystemProperty name="jetty.home" default="." />/etc/keystore</Set>
|
||||
<Set name="password">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
|
||||
<Set name="keyPassword">OBF:1u2u1wml1z7s1z7a1wnl1u2g</Set>
|
||||
<Set name="truststore"><SystemProperty name="jetty.home" default="." />/etc/keystore</Set>
|
||||
<Set name="trustPassword">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
|
||||
<Set name="handshakeTimeout">2000</Set>
|
||||
<!-- Set name="ThreadPool">
|
||||
<New class="org.mortbay.thread.BoundedThreadPool">
|
||||
<Set name="minThreads">10</Set>
|
||||
<Set name="maxThreads">250</Set>
|
||||
</New>
|
||||
</Set -->
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
</Configure>
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure SSL for the Jetty Server -->
|
||||
<!-- this configuration file should be used in combination with -->
|
||||
<!-- other configuration files. e.g. -->
|
||||
<!-- java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml -->
|
||||
<!-- =============================================================== -->
|
||||
<Configure id="Server" class="org.mortbay.jetty.Server">
|
||||
<Call name="addConnector">
|
||||
<Arg>
|
||||
<New class="org.mortbay.jetty.security.SslSelectChannelConnector">
|
||||
<Set name="Port">8444</Set>
|
||||
<Set name="maxIdleTime">30000</Set>
|
||||
<Set name="Acceptors">2</Set>
|
||||
<Set name="AcceptQueueSize">100</Set>
|
||||
<Set name="Keystore"><SystemProperty name="jetty.home" default="." />/etc/keystore</Set>
|
||||
<Set name="Password">OBF:1vny1zlo1x8e1vnw1vn61x8g1zlu1vn4</Set>
|
||||
<Set name="KeyPassword">OBF:1u2u1wml1z7s1z7a1wnl1u2g</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
</Configure>
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Mixin the Statistics Handler -->
|
||||
<!-- =============================================================== -->
|
||||
|
||||
<Configure id="Server" class="org.mortbay.jetty.Server">
|
||||
|
||||
<Get id="oldhandler" name="handler"/>
|
||||
<Set name="handler">
|
||||
<New id="StatsHandler" class="org.mortbay.jetty.handler.AtomicStatisticsHandler">
|
||||
<!-- Use non-atomic for jdk 1.4 -->
|
||||
<!-- New id="StatsHandler" class="org.mortbay.jetty.handler.StatisticsHandler" -->
|
||||
<Set name="handler"><Ref id="oldhandler"/></Set>
|
||||
</New>
|
||||
</Set>
|
||||
|
||||
</Configure>
|
|
@ -0,0 +1,28 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure the Jetty Server -->
|
||||
<!-- -->
|
||||
<!-- Documentation of this file format can be found at: -->
|
||||
<!-- http://docs.codehaus.org/display/JETTY/jetty.xml -->
|
||||
<!-- -->
|
||||
<!-- =============================================================== -->
|
||||
|
||||
|
||||
<Configure id="Server" class="org.mortbay.jetty.Server">
|
||||
|
||||
|
||||
<Call name="addLifeCycle">
|
||||
<Arg>
|
||||
<New class="org.mortbay.jetty.win32service.Win32Service">
|
||||
<Set name="server"><Ref id="Server"/></Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
<Set name="stopAtShutdown">true</Set>
|
||||
<!-- ensure/prevent Server: header being sent to browsers -->
|
||||
<Set name="sendServerVersion">true</Set>
|
||||
|
||||
</Configure>
|
|
@ -0,0 +1,56 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/configure.dtd">
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configuration for starting up Jetty using inetd/xinetd -->
|
||||
<!-- This feature requires at least Java 5 -->
|
||||
<!-- -->
|
||||
<!-- Making it a mixin for convenience, but note that if used -->
|
||||
<!-- with jetty.xml, Jetty will use multiple connectors -->
|
||||
<!-- =============================================================== -->
|
||||
|
||||
<!-- Sample xinetd configuration (restart xinetd after adding the configuration file)
|
||||
|
||||
service jetty
|
||||
{
|
||||
disable = no
|
||||
|
||||
id = jetty
|
||||
type = UNLISTED
|
||||
wait = yes
|
||||
socket_type = stream
|
||||
|
||||
# change this
|
||||
user = username
|
||||
group = groupname
|
||||
port = 2001
|
||||
|
||||
# sample script for running jetty as a service
|
||||
# replace $JETTY_HOME with /path/to/jetty_home/
|
||||
server = $JETTY_HOME/bin/jetty-xinetd.sh
|
||||
}
|
||||
|
||||
-->
|
||||
|
||||
<Configure id="Server" class="org.mortbay.jetty.Server">
|
||||
<Call name="addConnector">
|
||||
<Arg>
|
||||
<!-- Inherited channel (from inetd/xinetd) -->
|
||||
<New class="org.mortbay.jetty.nio.InheritedChannelConnector">
|
||||
|
||||
|
||||
<!-- Optional. Fallback in case System.inheritedChannel() does not give a ServerSocketChannel
|
||||
<Set name="port"><SystemProperty name="jetty.service.port" default="8082"/></Set>
|
||||
-->
|
||||
|
||||
<!-- sane defaults -->
|
||||
<Set name="maxIdleTime">300000</Set>
|
||||
<Set name="Acceptors">2</Set>
|
||||
<Set name="statsOn">false</Set>
|
||||
<Set name="lowResourcesConnections">20000</Set>
|
||||
<Set name="lowResourcesMaxIdleTime">5000</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
</Configure>
|
||||
|
|
@ -0,0 +1,209 @@
|
|||
<?xml version="1.0"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
|
||||
<!-- =============================================================== -->
|
||||
<!-- Configure the Jetty Server -->
|
||||
<!-- -->
|
||||
<!-- Documentation of this file format can be found at: -->
|
||||
<!-- http://docs.codehaus.org/display/JETTY/jetty.xml -->
|
||||
<!-- -->
|
||||
<!-- =============================================================== -->
|
||||
|
||||
|
||||
<Configure id="Server" class="org.eclipse.jetty.server.Server">
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Server Thread Pool -->
|
||||
<!-- =========================================================== -->
|
||||
<Set name="ThreadPool">
|
||||
<!-- Default queued blocking threadpool
|
||||
-->
|
||||
<New class="org.eclipse.jetty.util.thread.QueuedThreadPool">
|
||||
<Set name="minThreads">10</Set>
|
||||
<Set name="maxThreads">200</Set>
|
||||
</New>
|
||||
|
||||
<!-- Optional Java 5 bounded threadpool with job queue
|
||||
<New class="org.eclipse.thread.concurrent.ThreadPool">
|
||||
<Set name="corePoolSize">50</Set>
|
||||
<Set name="maximumPoolSize">50</Set>
|
||||
</New>
|
||||
-->
|
||||
</Set>
|
||||
|
||||
<!-- Added from jetty-plus.xml but is this really necessary? -->
|
||||
<!-- =========================================================== -->
|
||||
<!-- Configurations for WebAppContexts -->
|
||||
<!-- Sequence of configurations to enable Plus features. -->
|
||||
<!-- =========================================================== -->
|
||||
<Array id="plusConfig" type="java.lang.String">
|
||||
<Item>org.mortbay.jetty.webapp.WebInfConfiguration</Item>
|
||||
<Item>org.mortbay.jetty.plus.webapp.EnvConfiguration</Item>
|
||||
<Item>org.mortbay.jetty.plus.webapp.Configuration</Item>
|
||||
<Item>org.mortbay.jetty.webapp.JettyWebXmlConfiguration</Item>
|
||||
<Item>org.mortbay.jetty.webapp.TagLibConfiguration</Item>
|
||||
</Array>
|
||||
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Set connectors -->
|
||||
<!-- =========================================================== -->
|
||||
|
||||
<Call name="addConnector">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.server.nio.SelectChannelConnector">
|
||||
<Set name="host"><SystemProperty name="jetty.host" /></Set>
|
||||
<Set name="port"><SystemProperty name="jetty.port" default="8080"/></Set>
|
||||
<Set name="maxIdleTime">300000</Set>
|
||||
<Set name="Acceptors">2</Set>
|
||||
<Set name="statsOn">false</Set>
|
||||
<Set name="confidentialPort">8443</Set>
|
||||
<Set name="lowResourcesConnections">20000</Set>
|
||||
<Set name="lowResourcesMaxIdleTime">5000</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- To add a HTTPS SSL connector -->
|
||||
<!-- mixin jetty-ssl.xml: -->
|
||||
<!-- java -jar start.jar etc/jetty.xml etc/jetty-ssl.xml -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- To add a HTTP blocking connector -->
|
||||
<!-- mixin jetty-bio.xml: -->
|
||||
<!-- java -jar start.jar etc/jetty.xml etc/jetty-bio.xml -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- To allow Jetty to be started from xinetd -->
|
||||
<!-- mixin jetty-xinetd.xml: -->
|
||||
<!-- java -jar start.jar etc/jetty.xml etc/jetty-xinetd.xml -->
|
||||
<!-- -->
|
||||
<!-- See jetty-xinetd.xml for further instructions. -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Set handler Collection Structure -->
|
||||
<!-- =========================================================== -->
|
||||
<Set name="handler">
|
||||
<New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
|
||||
<Set name="handlers">
|
||||
<Array type="org.eclipse.jetty.server.Handler">
|
||||
<Item>
|
||||
<New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
|
||||
</Item>
|
||||
<Item>
|
||||
<New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler"/>
|
||||
</Item>
|
||||
</Array>
|
||||
</Set>
|
||||
</New>
|
||||
</Set>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Configure the context deployer -->
|
||||
<!-- A context deployer will deploy contexts described in -->
|
||||
<!-- configuration files discovered in a directory. -->
|
||||
<!-- The configuration directory can be scanned for hot -->
|
||||
<!-- deployments at the configured scanInterval. -->
|
||||
<!-- -->
|
||||
<!-- This deployer is configured to deploy contexts configured -->
|
||||
<!-- in the $JETTY_HOME/contexts directory -->
|
||||
<!-- -->
|
||||
<!-- =========================================================== -->
|
||||
<Call name="addBean">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.deploy.ContextDeployer">
|
||||
<Set name="contexts"><Ref id="Contexts"/></Set>
|
||||
<Set name="configurationDir"><SystemProperty name="jetty.home" default="."/>/contexts</Set>
|
||||
<Set name="scanInterval">5</Set>
|
||||
<Call name="setAttribute">
|
||||
<Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
|
||||
<Arg>.*/jsp-api-[^/]*\.jar$|.*/jsp-[^/]*\.jar$</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Configure the webapp deployer. -->
|
||||
<!-- A webapp deployer will deploy standard webapps discovered -->
|
||||
<!-- in a directory at startup, without the need for additional -->
|
||||
<!-- configuration files. It does not support hot deploy or -->
|
||||
<!-- non standard contexts (see ContextDeployer above). -->
|
||||
<!-- -->
|
||||
<!-- This deployer is configured to deploy webapps from the -->
|
||||
<!-- $JETTY_HOME/webapps directory -->
|
||||
<!-- -->
|
||||
<!-- Normally only one type of deployer need be used. -->
|
||||
<!-- -->
|
||||
<!-- =========================================================== -->
|
||||
<Call name="addBean">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.deploy.WebAppDeployer">
|
||||
<Set name="contexts"><Ref id="Contexts"/></Set>
|
||||
<Set name="webAppDir"><SystemProperty name="jetty.home" default="."/>/webapps</Set>
|
||||
<Set name="parentLoaderPriority">false</Set>
|
||||
<Set name="extract">true</Set>
|
||||
<Set name="allowDuplicates">false</Set>
|
||||
<Set name="defaultsDescriptor"><SystemProperty name="jetty.home" default="."/>/etc/webdefault.xml</Set>
|
||||
<Call name="setAttribute">
|
||||
<Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
|
||||
<Arg>.*/jsp-api-[^/]*\.jar$|.*/jsp-[^/]*\.jar$</Arg>
|
||||
</Call>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Configure Authentication Login Service -->
|
||||
<!-- Realms may be configured for the entire server here, or -->
|
||||
<!-- they can be configured for a specific web app in a context -->
|
||||
<!-- configuration (see $(jetty.home)/contexts/test.xml for an -->
|
||||
<!-- example). -->
|
||||
<!-- =========================================================== -->
|
||||
<Call name="addBean">
|
||||
<Arg>
|
||||
<New class="org.eclipse.jetty.security.HashLoginService">
|
||||
<Set name="name">Test Realm</Set>
|
||||
<Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
|
||||
<Set name="refreshInterval">0</Set>
|
||||
</New>
|
||||
</Arg>
|
||||
</Call>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- Configure Request Log -->
|
||||
<!-- Request logs may be configured for the entire server here, -->
|
||||
<!-- or they can be configured for a specific web app in a -->
|
||||
<!-- contexts configuration (see $(jetty.home)/contexts/test.xml -->
|
||||
<!-- for an example). -->
|
||||
<!-- =========================================================== -->
|
||||
<Ref id="RequestLog">
|
||||
<Set name="requestLog">
|
||||
<New id="RequestLogImpl" class="org.eclipse.jetty.server.NCSARequestLog">
|
||||
<Set name="filename"><SystemProperty name="jetty.home" default="."/>/logs/yyyy_mm_dd.request.log</Set>
|
||||
<Set name="filenameDateFormat">yyyy_MM_dd</Set>
|
||||
<Set name="retainDays">90</Set>
|
||||
<Set name="append">true</Set>
|
||||
<Set name="extended">false</Set>
|
||||
<Set name="logCookies">false</Set>
|
||||
<Set name="LogTimeZone">GMT</Set>
|
||||
</New>
|
||||
</Set>
|
||||
</Ref>
|
||||
|
||||
<!-- =========================================================== -->
|
||||
<!-- extra options -->
|
||||
<!-- =========================================================== -->
|
||||
<Set name="stopAtShutdown">true</Set>
|
||||
<Set name="sendServerVersion">true</Set>
|
||||
<Set name="sendDateHeader">true</Set>
|
||||
<Set name="gracefulShutdown">1000</Set>
|
||||
|
||||
</Configure>
|
Binary file not shown.
|
@ -0,0 +1,5 @@
|
|||
xyz {
|
||||
org.mortbay.jetty.plus.jaas.spi.PropertyFileLoginModule required
|
||||
debug="true"
|
||||
file="${jetty.home}/etc/login.properties";
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
me=me,me,roleA
|
|
@ -0,0 +1,21 @@
|
|||
#
|
||||
# This file defines users passwords and roles for a HashUserRealm
|
||||
#
|
||||
# The format is
|
||||
# <username>: <password>[,<rolename> ...]
|
||||
#
|
||||
# Passwords may be clear text, obfuscated or checksummed. The class
|
||||
# org.mortbay.util.Password should be used to generate obfuscated
|
||||
# passwords or password checksums
|
||||
#
|
||||
# If DIGEST Authentication is used, the password must be in a recoverable
|
||||
# format, either plain text or OBF:.
|
||||
#
|
||||
jetty: MD5:164c88b302622e17050af52c89945d44,user
|
||||
admin: CRYPT:ad1ks..kc.1Ug,server-administrator,content-administrator,admin
|
||||
other: OBF:1xmk1w261u9r1w1c1xmq
|
||||
plain: plain
|
||||
user: password
|
||||
|
||||
# This entry is for digest auth. The credential is a MD5 hash of username:realmname:password
|
||||
digest: MD5:6e120743ad67abfbc385bc2bb754e297
|
|
@ -0,0 +1,404 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
|
||||
<!-- ===================================================================== -->
|
||||
<!-- This file contains the default descriptor for web applications. -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- The intent of this descriptor is to include jetty specific or common -->
|
||||
<!-- configuration for all webapps. If a context has a webdefault.xml -->
|
||||
<!-- descriptor, it is applied before the contexts own web.xml file -->
|
||||
<!-- -->
|
||||
<!-- A context may be assigned a default descriptor by: -->
|
||||
<!-- + Calling WebApplicationContext.setDefaultsDescriptor -->
|
||||
<!-- + Passed an arg to addWebApplications -->
|
||||
<!-- -->
|
||||
<!-- This file is used both as the resource within the jetty.jar (which is -->
|
||||
<!-- used as the default if no explicit defaults descriptor is set) and it -->
|
||||
<!-- is copied to the etc directory of the Jetty distro and explicitly -->
|
||||
<!-- by the jetty.xml file. -->
|
||||
<!-- -->
|
||||
<!-- ===================================================================== -->
|
||||
<web-app
|
||||
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
|
||||
metadata-complete="true"
|
||||
version="2.5">
|
||||
|
||||
<description>
|
||||
Default web.xml file.
|
||||
This file is applied to a Web application before it's own WEB_INF/web.xml file
|
||||
</description>
|
||||
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<!-- Context params to control Session Cookies -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- UNCOMMENT TO ACTIVATE
|
||||
<context-param>
|
||||
<param-name>org.eclipse.jetty.servlet.SessionDomain</param-name>
|
||||
<param-value>127.0.0.1</param-value>
|
||||
</context-param>
|
||||
|
||||
<context-param>
|
||||
<param-name>org.eclipse.jetty.servlet.SessionPath</param-name>
|
||||
<param-value>/</param-value>
|
||||
</context-param>
|
||||
|
||||
<context-param>
|
||||
<param-name>org.eclipse.jetty.servlet.MaxAge</param-name>
|
||||
<param-value>-1</param-value>
|
||||
</context-param>
|
||||
-->
|
||||
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<!-- The default servlet. -->
|
||||
<!-- This servlet, normally mapped to /, provides the handling for static -->
|
||||
<!-- content, OPTIONS and TRACE methods for the context. -->
|
||||
<!-- The following initParameters are supported: -->
|
||||
<!-- -->
|
||||
<!-- acceptRanges If true, range requests and responses are -->
|
||||
<!-- supported -->
|
||||
<!-- -->
|
||||
<!-- dirAllowed If true, directory listings are returned if no -->
|
||||
<!-- welcome file is found. Else 403 Forbidden. -->
|
||||
<!-- -->
|
||||
<!-- welcomeServlets If true, attempt to dispatch to welcome files -->
|
||||
<!-- that are servlets, if no matching static -->
|
||||
<!-- resources can be found. -->
|
||||
<!-- -->
|
||||
<!-- redirectWelcome If true, redirect welcome file requests -->
|
||||
<!-- else use request dispatcher forwards -->
|
||||
<!-- -->
|
||||
<!-- gzip If set to true, then static content will be served-->
|
||||
<!-- as gzip content encoded if a matching resource is -->
|
||||
<!-- found ending with ".gz" -->
|
||||
<!-- -->
|
||||
<!-- resoureBase Can be set to replace the context resource base -->
|
||||
<!-- -->
|
||||
<!-- relativeResourceBase -->
|
||||
<!-- Set with a pathname relative to the base of the -->
|
||||
<!-- servlet context root. Useful for only serving -->
|
||||
<!-- static content from only specific subdirectories. -->
|
||||
<!-- -->
|
||||
<!-- useFileMappedBuffer -->
|
||||
<!-- If set to true (the default), a memory mapped -->
|
||||
<!-- file buffer will be used to serve static content -->
|
||||
<!-- when using an NIO connector. Setting this value -->
|
||||
<!-- to false means that a direct buffer will be used -->
|
||||
<!-- instead. If you are having trouble with Windows -->
|
||||
<!-- file locking, set this to false. -->
|
||||
<!-- -->
|
||||
<!-- cacheControl If set, all static content will have this value -->
|
||||
<!-- set as the cache-control header. -->
|
||||
<!-- -->
|
||||
<!-- maxCacheSize Maximum size of the static resource cache -->
|
||||
<!-- -->
|
||||
<!-- maxCachedFileSize Maximum size of any single file in the cache -->
|
||||
<!-- -->
|
||||
<!-- maxCachedFiles Maximum number of files in the cache -->
|
||||
<!-- -->
|
||||
<!-- cacheType "nio", "bio" or "both" to determine the type(s) -->
|
||||
<!-- of resource cache. A bio cached buffer may be used-->
|
||||
<!-- by nio but is not as efficient as a nio buffer. -->
|
||||
<!-- An nio cached buffer may not be used by bio. -->
|
||||
<!-- -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<servlet>
|
||||
<servlet-name>default</servlet-name>
|
||||
<servlet-class>org.eclipse.jetty.servlet.DefaultServlet</servlet-class>
|
||||
<init-param>
|
||||
<param-name>acceptRanges</param-name>
|
||||
<param-value>true</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>dirAllowed</param-name>
|
||||
<param-value>true</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>welcomeServlets</param-name>
|
||||
<param-value>false</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>redirectWelcome</param-name>
|
||||
<param-value>false</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>maxCacheSize</param-name>
|
||||
<param-value>256000000</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>maxCachedFileSize</param-name>
|
||||
<param-value>10000000</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>maxCachedFiles</param-name>
|
||||
<param-value>1000</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>cacheType</param-name>
|
||||
<param-value>both</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>gzip</param-name>
|
||||
<param-value>true</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>useFileMappedBuffer</param-name>
|
||||
<param-value>true</param-value>
|
||||
</init-param>
|
||||
<!--
|
||||
<init-param>
|
||||
<param-name>cacheControl</param-name>
|
||||
<param-value>max-age=3600,public</param-value>
|
||||
</init-param>
|
||||
-->
|
||||
<load-on-startup>0</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping> <servlet-name>default</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
|
||||
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<!-- JSP Servlet -->
|
||||
<!-- This is the jasper JSP servlet from the jakarta project -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- The JSP page compiler and execution servlet, which is the mechanism -->
|
||||
<!-- used by Glassfish to support JSP pages. Traditionally, this servlet -->
|
||||
<!-- is mapped to URL patterh "*.jsp". This servlet supports the -->
|
||||
<!-- following initialization parameters (default values are in square -->
|
||||
<!-- brackets): -->
|
||||
<!-- -->
|
||||
<!-- checkInterval If development is false and reloading is true, -->
|
||||
<!-- background compiles are enabled. checkInterval -->
|
||||
<!-- is the time in seconds between checks to see -->
|
||||
<!-- if a JSP page needs to be recompiled. [300] -->
|
||||
<!-- -->
|
||||
<!-- compiler Which compiler Ant should use to compile JSP -->
|
||||
<!-- pages. See the Ant documenation for more -->
|
||||
<!-- information. [javac] -->
|
||||
<!-- -->
|
||||
<!-- classdebuginfo Should the class file be compiled with -->
|
||||
<!-- debugging information? [true] -->
|
||||
<!-- -->
|
||||
<!-- classpath What class path should I use while compiling -->
|
||||
<!-- generated servlets? [Created dynamically -->
|
||||
<!-- based on the current web application] -->
|
||||
<!-- Set to ? to make the container explicitly set -->
|
||||
<!-- this parameter. -->
|
||||
<!-- -->
|
||||
<!-- development Is Jasper used in development mode (will check -->
|
||||
<!-- for JSP modification on every access)? [true] -->
|
||||
<!-- -->
|
||||
<!-- enablePooling Determines whether tag handler pooling is -->
|
||||
<!-- enabled [true] -->
|
||||
<!-- -->
|
||||
<!-- fork Tell Ant to fork compiles of JSP pages so that -->
|
||||
<!-- a separate JVM is used for JSP page compiles -->
|
||||
<!-- from the one Tomcat is running in. [true] -->
|
||||
<!-- -->
|
||||
<!-- ieClassId The class-id value to be sent to Internet -->
|
||||
<!-- Explorer when using <jsp:plugin> tags. -->
|
||||
<!-- [clsid:8AD9C840-044E-11D1-B3E9-00805F499D93] -->
|
||||
<!-- -->
|
||||
<!-- javaEncoding Java file encoding to use for generating java -->
|
||||
<!-- source files. [UTF-8] -->
|
||||
<!-- -->
|
||||
<!-- keepgenerated Should we keep the generated Java source code -->
|
||||
<!-- for each page instead of deleting it? [true] -->
|
||||
<!-- -->
|
||||
<!-- logVerbosityLevel The level of detailed messages to be produced -->
|
||||
<!-- by this servlet. Increasing levels cause the -->
|
||||
<!-- generation of more messages. Valid values are -->
|
||||
<!-- FATAL, ERROR, WARNING, INFORMATION, and DEBUG. -->
|
||||
<!-- [WARNING] -->
|
||||
<!-- -->
|
||||
<!-- mappedfile Should we generate static content with one -->
|
||||
<!-- print statement per input line, to ease -->
|
||||
<!-- debugging? [false] -->
|
||||
<!-- -->
|
||||
<!-- -->
|
||||
<!-- reloading Should Jasper check for modified JSPs? [true] -->
|
||||
<!-- -->
|
||||
<!-- suppressSmap Should the generation of SMAP info for JSR45 -->
|
||||
<!-- debugging be suppressed? [false] -->
|
||||
<!-- -->
|
||||
<!-- dumpSmap Should the SMAP info for JSR45 debugging be -->
|
||||
<!-- dumped to a file? [false] -->
|
||||
<!-- False if suppressSmap is true -->
|
||||
<!-- -->
|
||||
<!-- scratchdir What scratch directory should we use when -->
|
||||
<!-- compiling JSP pages? [default work directory -->
|
||||
<!-- for the current web application] -->
|
||||
<!-- -->
|
||||
<!-- tagpoolMaxSize The maximum tag handler pool size [5] -->
|
||||
<!-- -->
|
||||
<!-- xpoweredBy Determines whether X-Powered-By response -->
|
||||
<!-- header is added by generated servlet [false] -->
|
||||
<!-- -->
|
||||
<!-- If you wish to use Jikes to compile JSP pages: -->
|
||||
<!-- Set the init parameter "compiler" to "jikes". Define -->
|
||||
<!-- the property "-Dbuild.compiler.emacs=true" when starting Jetty -->
|
||||
<!-- to cause Jikes to emit error messages in a format compatible with -->
|
||||
<!-- Jasper. -->
|
||||
<!-- If you get an error reporting that jikes can't use UTF-8 encoding, -->
|
||||
<!-- try setting the init parameter "javaEncoding" to "ISO-8859-1". -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<servlet id="jsp">
|
||||
<servlet-name>jsp</servlet-name>
|
||||
<servlet-class>org.apache.jasper.servlet.JspServlet</servlet-class>
|
||||
<init-param>
|
||||
<param-name>logVerbosityLevel</param-name>
|
||||
<param-value>DEBUG</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>fork</param-name>
|
||||
<param-value>false</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>xpoweredBy</param-name>
|
||||
<param-value>false</param-value>
|
||||
</init-param>
|
||||
<!--
|
||||
<init-param>
|
||||
<param-name>classpath</param-name>
|
||||
<param-value>?</param-value>
|
||||
</init-param>
|
||||
-->
|
||||
<load-on-startup>0</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping>
|
||||
<servlet-name>jsp</servlet-name>
|
||||
<url-pattern>*.jsp</url-pattern>
|
||||
<url-pattern>*.jspf</url-pattern>
|
||||
<url-pattern>*.jspx</url-pattern>
|
||||
<url-pattern>*.xsp</url-pattern>
|
||||
<url-pattern>*.JSP</url-pattern>
|
||||
<url-pattern>*.JSPF</url-pattern>
|
||||
<url-pattern>*.JSPX</url-pattern>
|
||||
<url-pattern>*.XSP</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<!-- Dynamic Servlet Invoker. -->
|
||||
<!-- This servlet invokes anonymous servlets that have not been defined -->
|
||||
<!-- in the web.xml or by other means. The first element of the pathInfo -->
|
||||
<!-- of a request passed to the envoker is treated as a servlet name for -->
|
||||
<!-- an existing servlet, or as a class name of a new servlet. -->
|
||||
<!-- This servlet is normally mapped to /servlet/* -->
|
||||
<!-- This servlet support the following initParams: -->
|
||||
<!-- -->
|
||||
<!-- nonContextServlets If false, the invoker can only load -->
|
||||
<!-- servlets from the contexts classloader. -->
|
||||
<!-- This is false by default and setting this -->
|
||||
<!-- to true may have security implications. -->
|
||||
<!-- -->
|
||||
<!-- verbose If true, log dynamic loads -->
|
||||
<!-- -->
|
||||
<!-- * All other parameters are copied to the -->
|
||||
<!-- each dynamic servlet as init parameters -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- Uncomment for dynamic invocation
|
||||
<servlet>
|
||||
<servlet-name>invoker</servlet-name>
|
||||
<servlet-class>org.eclipse.jetty.servlet.Invoker</servlet-class>
|
||||
<init-param>
|
||||
<param-name>verbose</param-name>
|
||||
<param-value>false</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>nonContextServlets</param-name>
|
||||
<param-value>false</param-value>
|
||||
</init-param>
|
||||
<init-param>
|
||||
<param-name>dynamicParam</param-name>
|
||||
<param-value>anyValue</param-value>
|
||||
</init-param>
|
||||
<load-on-startup>0</load-on-startup>
|
||||
</servlet>
|
||||
|
||||
<servlet-mapping> <servlet-name>invoker</servlet-name> <url-pattern>/servlet/*</url-pattern> </servlet-mapping>
|
||||
-->
|
||||
|
||||
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<session-config>
|
||||
<session-timeout>30</session-timeout>
|
||||
</session-config>
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<!-- Default MIME mappings -->
|
||||
<!-- The default MIME mappings are provided by the mime.properties -->
|
||||
<!-- resource in the org.eclipse.jetty.server.jar file. Additional or modified -->
|
||||
<!-- mappings may be specified here -->
|
||||
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
||||
<!-- UNCOMMENT TO ACTIVATE
|
||||
<mime-mapping>
|
||||
<extension>mysuffix</extension>
|
||||
<mime-type>mymime/type</mime-type>
|
||||
</mime-mapping>
|
||||
-->
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<welcome-file-list>
|
||||
<welcome-file>index.html</welcome-file>
|
||||
<welcome-file>index.htm</welcome-file>
|
||||
<welcome-file>index.jsp</welcome-file>
|
||||
</welcome-file-list>
|
||||
|
||||
<!-- ==================================================================== -->
|
||||
<locale-encoding-mapping-list>
|
||||
<locale-encoding-mapping><locale>ar</locale><encoding>ISO-8859-6</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>be</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>bg</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>ca</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>cs</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>da</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>de</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>el</locale><encoding>ISO-8859-7</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>en</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>es</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>et</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>fi</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>fr</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>hr</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>hu</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>is</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>it</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>iw</locale><encoding>ISO-8859-8</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>ja</locale><encoding>Shift_JIS</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>ko</locale><encoding>EUC-KR</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>lt</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>lv</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>mk</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>nl</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>no</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>pl</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>pt</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>ro</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>ru</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>sh</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>sk</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>sl</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>sq</locale><encoding>ISO-8859-2</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>sr</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>sv</locale><encoding>ISO-8859-1</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>tr</locale><encoding>ISO-8859-9</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>uk</locale><encoding>ISO-8859-5</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>zh</locale><encoding>GB2312</encoding></locale-encoding-mapping>
|
||||
<locale-encoding-mapping><locale>zh_TW</locale><encoding>Big5</encoding></locale-encoding-mapping>
|
||||
</locale-encoding-mapping-list>
|
||||
|
||||
<security-constraint>
|
||||
<web-resource-collection>
|
||||
<web-resource-name>Disable TRACE</web-resource-name>
|
||||
<url-pattern>/</url-pattern>
|
||||
<http-method>TRACE</http-method>
|
||||
</web-resource-collection>
|
||||
<auth-constraint/>
|
||||
</security-constraint>
|
||||
|
||||
</web-app>
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
Place here the jars that are inserted in the jetty classloader.
|
||||
As similar as possible as what this folder was for in the classical jetty installation.
|
|
@ -0,0 +1,3 @@
|
|||
This folder contains the logs by default during development time.
|
||||
In production or outside the eclipse PDE, it is likely that a different jetty.home
|
||||
was set or jetty.log so it won't be here.
|
|
@ -0,0 +1,2 @@
|
|||
This folder is part of the class-loader shared by the webapps run in jetty.
|
||||
Typically it contains log4j configuration files.
|
|
@ -0,0 +1,2 @@
|
|||
Default locations for standard web-applications.
|
||||
Those applications are unlikely to have access to the OSGi framework currently.
|
|
@ -0,0 +1,182 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.boot;
|
||||
|
||||
import java.util.Properties;
|
||||
|
||||
import org.eclipse.jetty.osgi.boot.internal.webapp.JettyContextHandlerExtender;
|
||||
import org.eclipse.jetty.osgi.boot.internal.webapp.JettyContextHandlerServiceTracker;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.ServiceRegistration;
|
||||
|
||||
/**
|
||||
* Experiment: bootstrap jetty's complete distrib from an OSGi bundle.
|
||||
* Progress:
|
||||
* <ol>
|
||||
* <li> basic servlet [ok]</li>
|
||||
* <li> basic jetty.xml [ok]</li>
|
||||
* <li> basic jetty.xml and jetty-plus.xml [ok]</li>
|
||||
* <li> basic jsp [ok with modifications]
|
||||
* <ul>
|
||||
* <li>Needed to modify the headers of jdt.core-3.1.1 so that its dependency on
|
||||
* eclipse.runtime, eclipse.resources and eclipse.text are optional.
|
||||
* Also we should depend on the latest jdt.core from eclipse-3.5 not from eclipse-3.1.1
|
||||
* although that will require actual changes to jasper as some internal APIs of
|
||||
* jdt.core have changed.</li>
|
||||
* <li>Modifications to org.mortbay.jetty.jsp-2.1-glassfish:
|
||||
* made all imports to ant, xalan and sun packages optional.</li>
|
||||
* </ul>
|
||||
* </li>
|
||||
* <li> jsp with tag-libs [ok]</li>
|
||||
* <li> test-jndi with atomikos and derby inside ${jetty.home}/lib/ext [ok]</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class JettyBootstrapActivator implements BundleActivator
|
||||
{
|
||||
|
||||
private static JettyBootstrapActivator INSTANCE = null;
|
||||
|
||||
public static JettyBootstrapActivator getInstance()
|
||||
{
|
||||
return INSTANCE;
|
||||
}
|
||||
|
||||
private ServiceRegistration _registeredServer;
|
||||
private Server _server;
|
||||
private JettyContextHandlerServiceTracker _jettyContextHandlerTracker;
|
||||
|
||||
/**
|
||||
* Setup a new jetty Server, registers it as a service. Setup the Service
|
||||
* tracker for the jetty ContextHandlers that are in charge of deploying the webapps.
|
||||
* Setup the BundleListener that supports the extender pattern for the
|
||||
* jetty ContextHandler.
|
||||
*
|
||||
* @param context
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception
|
||||
{
|
||||
INSTANCE = this;
|
||||
|
||||
// todo: replace all this by the ManagedFactory so that we can start multiple jetty servers.
|
||||
_server = new Server();
|
||||
// expose the server as a service.
|
||||
_registeredServer = context.registerService(_server.getClass().getName(),_server,new Properties());
|
||||
// the tracker in charge of the actual deployment
|
||||
// and that will configure and start the jetty server.
|
||||
_jettyContextHandlerTracker = new JettyContextHandlerServiceTracker(context,_server);
|
||||
|
||||
// TODO: add a couple more checks on the properties?
|
||||
// kind of nice not to so we can debug what is missing easily.
|
||||
context.addServiceListener(_jettyContextHandlerTracker,"(objectclass=" + ContextHandler.class.getName() + ")");
|
||||
|
||||
// now ready to support the Extender pattern:
|
||||
JettyContextHandlerExtender jettyContexHandlerExtender = new JettyContextHandlerExtender();
|
||||
context.addBundleListener(jettyContexHandlerExtender);
|
||||
|
||||
jettyContexHandlerExtender.init(context);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_jettyContextHandlerTracker != null)
|
||||
{
|
||||
_jettyContextHandlerTracker.stop();
|
||||
context.removeServiceListener(_jettyContextHandlerTracker);
|
||||
}
|
||||
if (_registeredServer != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
_registeredServer.unregister();
|
||||
_registeredServer = null;
|
||||
}
|
||||
catch (IllegalArgumentException ill)
|
||||
{
|
||||
// already unregistered.
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
_server.stop();
|
||||
INSTANCE = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that creates a new org.jetty.webapp.WebAppContext and
|
||||
* registers it as an OSGi service. The tracker
|
||||
* {@link JettyContextHandlerServiceTracker} will do the actual deployment.
|
||||
*
|
||||
* @param context
|
||||
* The current bundle context
|
||||
* @param webappFolderPath
|
||||
* The path to the root of the webapp. Must be a path relative
|
||||
* to bundle; either an absolute path.
|
||||
* @param contextPath
|
||||
* The context path. Must start with "/"
|
||||
* @param classInBundle
|
||||
* A class that belongs to the current bundle to inherit from the
|
||||
* osgi classloader. Null to not have access to the OSGI classloader.
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void registerWebapplication(Bundle contributor,
|
||||
String webappFolderPath, String contextPath) throws Exception
|
||||
{
|
||||
WebAppContext contextHandler = new WebAppContext();
|
||||
Properties dic = new Properties();
|
||||
dic.put("war",webappFolderPath);
|
||||
dic.put("contextPath",contextPath);
|
||||
contributor.getBundleContext().registerService(ContextHandler.class.getName(),contextHandler,dic);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method that creates a new skeleton of a ContextHandler and registers it as an OSGi service.
|
||||
* The tracker {@link JettyContextHandlerServiceTracker} will do the actual deployment.
|
||||
*
|
||||
* @param contributor
|
||||
* The bundle that registers a new context
|
||||
* @param contextFilePath
|
||||
* The path to the file inside the bundle that defines the context.
|
||||
* @throws Exception
|
||||
*/
|
||||
public static void registerContext(Bundle contributor, String contextFilePath) throws Exception
|
||||
{
|
||||
ContextHandler contextHandler = new ContextHandler();
|
||||
Properties dic = new Properties();
|
||||
dic.put("contextFilePath",contextFilePath);
|
||||
contributor.getBundleContext().registerService(ContextHandler.class.getName(),contextHandler,dic);
|
||||
}
|
||||
|
||||
public static void unregister(String contextPath)
|
||||
{
|
||||
// todo
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.boot.internal.jsp;
|
||||
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
|
||||
/**
|
||||
* Tricky url classloader.
|
||||
* In fact we don't want a real URLClassLoader: we want OSGi to provide its classloader
|
||||
* and let it does.
|
||||
* But to let {@link org.apache.jasper.compiler.TldLocationsCache} find the core tlds inside the jars
|
||||
* we must be a URLClassLoader that returns an array of jars where tlds are stored
|
||||
* when the method getURLs is called.
|
||||
*/
|
||||
public class TldLocatableURLClassloader extends URLClassLoader
|
||||
{
|
||||
|
||||
private URL[] _jarsWithTldsInside;
|
||||
|
||||
public TldLocatableURLClassloader(ClassLoader osgiClassLoader, URL[] jarsWithTldsInside)
|
||||
{
|
||||
super(new URL[] {},osgiClassLoader);
|
||||
_jarsWithTldsInside = jarsWithTldsInside;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the jars that contains tlds so that TldLocationsCache or
|
||||
* TldScanner can find them.
|
||||
*/
|
||||
@Override
|
||||
public URL[] getURLs()
|
||||
{
|
||||
return _jarsWithTldsInside;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.boot.internal.jsp;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
/**
|
||||
* Add a classloader to the org.apache.jasper.compiler.TldLocatableURLClassloader.
|
||||
* Hopefuly not necessary: still experimenting.
|
||||
* @see TldLocatableURLClassloader
|
||||
*/
|
||||
public class TldLocatableURLClassloaderWithInsertedJettyClassloader extends TldLocatableURLClassloader
|
||||
{
|
||||
|
||||
private ClassLoader _internalClassLoader;
|
||||
|
||||
public TldLocatableURLClassloaderWithInsertedJettyClassloader(ClassLoader osgiClassLoader,
|
||||
ClassLoader internalClassLoader, URL[] jarsWithTldsInside)
|
||||
{
|
||||
super(osgiClassLoader,jarsWithTldsInside);
|
||||
_internalClassLoader = internalClassLoader;
|
||||
}
|
||||
|
||||
protected Class<?> findClass(String name) throws ClassNotFoundException
|
||||
{
|
||||
try
|
||||
{
|
||||
return super.findClass(name);
|
||||
}
|
||||
catch (ClassNotFoundException cne)
|
||||
{
|
||||
if (_internalClassLoader != null)
|
||||
{
|
||||
return _internalClassLoader.loadClass(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw cne;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,115 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.boot.internal.serverfactory;
|
||||
|
||||
import java.util.Dictionary;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.osgi.service.cm.ConfigurationException;
|
||||
import org.osgi.service.cm.ManagedServiceFactory;
|
||||
|
||||
/**
|
||||
* This is a work in progress.
|
||||
* <br/>
|
||||
* In particular there is a lot of work required during the update of the configuration
|
||||
* of a server. It might not be practical to in fact support that and re-deploy
|
||||
* the webapps in the same state than before the server was stopped.
|
||||
* <p>
|
||||
* jetty servers are managed as OSGi services registered here.
|
||||
* try to find out if a configuration will fail (ports already opened etc).
|
||||
* </p>
|
||||
* <p>
|
||||
* Try to enable the creation and configuration of jetty servers in all the usual standard ways.
|
||||
* The configuration of the server is defined by the properties passed to the service:
|
||||
* <ol>
|
||||
* <li>First look for jettyfactory. If the value is a jetty server, use that server</li>
|
||||
* <li>Then look for jettyhome key. The value should be a java.io.File or a String that is a path to the folder
|
||||
* It is required that a etc/jetty.xml file will be loated from that folder.</li>
|
||||
* <li>Then look for a jettyxml key. The value should be a java.io.File or an InputStream
|
||||
* that contains a jetty configuration file.</li>
|
||||
* <li>TODO: More ways to configure a jetty server?
|
||||
* (other IOCs like spring, equinox properties...)</li>
|
||||
* <li>Throw an exception if none of the relevant parameters are found</li>
|
||||
* </ol>
|
||||
* </p>
|
||||
*
|
||||
* A nice intro to ManagedFactory in OSGi:
|
||||
* http://www.osgilook.com/2009/08/04/factory-pattern-on-steroids-the-managedservicefactory/
|
||||
*
|
||||
* @author hmalphettes
|
||||
*/
|
||||
public class JettyServersManagedFactory implements ManagedServiceFactory {
|
||||
|
||||
/** key to configure the server according to a jetty home folder.
|
||||
* the value is the corresponding java.io.File */
|
||||
public static final String JETTY_HOME = "jettyhome";
|
||||
/** key to configure the server according to a jetty.xml file */
|
||||
public static final String JETTY_CONFIG_XML = "jettyxml";
|
||||
|
||||
/** invoke jetty-factory class. the value of this property is the
|
||||
* instance of that class to call back. */
|
||||
public static final String JETTY_FACTORY = "jettyfactory";
|
||||
|
||||
/** default property in jetty.xml that is used as the value of the http port. */
|
||||
public static final String JETTY_HTTP_PORT = "jetty.http.port";
|
||||
/** default property in jetty.xml that is used as the value of the https port. */
|
||||
public static final String JETTY_HTTPS_PORT = "jetty.http.port";
|
||||
|
||||
/** */
|
||||
private Map<String, Server> _servers = new HashMap<String, Server>();
|
||||
|
||||
/**
|
||||
* @return the name for the factory
|
||||
*/
|
||||
public String getName()
|
||||
{
|
||||
return "Jetty Servers Managed Factory";
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when the config for a jetty server is updated.
|
||||
*/
|
||||
public void updated(String pid, Dictionary properties)
|
||||
throws ConfigurationException {
|
||||
Server server = _servers.get(pid);
|
||||
deleted(pid);
|
||||
//do we need to collect the currently deployed http services and webapps
|
||||
//to be able to re-deploy them later?
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Will stop the corresponding server is there is one.
|
||||
* @pid the unique identifier for that implementtion of the service: in this case the jetty server.
|
||||
*/
|
||||
public synchronized void deleted(String pid)
|
||||
{
|
||||
Server server = (Server) _servers.remove(pid);
|
||||
if (server != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
server.stop();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,161 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.boot.internal.webapp;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.Dictionary;
|
||||
|
||||
import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.BundleEvent;
|
||||
import org.osgi.framework.BundleListener;
|
||||
|
||||
/**
|
||||
* Support bundles that declare the webapp directly through headers in their manifest.
|
||||
* <p>
|
||||
* Those headers will define a new WebApplication:
|
||||
* <ul><li>Web-ContextPath</li>
|
||||
* <li>Jetty-WarFolderPath</li>
|
||||
* </ul>
|
||||
* </p>
|
||||
* <p>
|
||||
* Those headers will define a new app started via a jetty-context:
|
||||
* <ul><li>Jetty-ContextFilePath</li></ul>
|
||||
* </p>
|
||||
* And generate a jetty WebAppContext or another ContextHandler then registers it
|
||||
* as service. Kind of simpler than declarative services and their xml files.
|
||||
* Also avoid having the contributing bundle depend on jetty's package for WebApp.
|
||||
*/
|
||||
public class JettyContextHandlerExtender implements BundleListener {
|
||||
|
||||
/**
|
||||
* Receives notification that a bundle has had a lifecycle change.
|
||||
*
|
||||
* @param event The <code>BundleEvent</code>.
|
||||
*/
|
||||
public void bundleChanged(BundleEvent event) {
|
||||
switch (event.getType()) {
|
||||
case BundleEvent.STARTED:
|
||||
register(event.getBundle());
|
||||
break;
|
||||
case BundleEvent.STOPPING:
|
||||
unregister(event.getBundle());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void init(BundleContext context) {
|
||||
Bundle bundles[] = context.getBundles();
|
||||
for (int i = 0; i < bundles.length; i++) {
|
||||
if ((bundles[i].getState() & (Bundle.STARTING | Bundle.ACTIVE)) != 0) {
|
||||
register(bundles[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void register(Bundle bundle) {
|
||||
Dictionary<?, ?> dic = bundle.getHeaders();
|
||||
String warFolderRelativePath = (String)dic.get("Jetty-WarFolderPath");
|
||||
if (warFolderRelativePath != null) {
|
||||
String contextPath = (String)dic.get("Web-ContextPath");
|
||||
if (contextPath == null) {
|
||||
contextPath = (String)dic.get("Jetty-WarContextPath");
|
||||
}
|
||||
if (contextPath == null || !contextPath.startsWith("/")) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
//create the corresponding service and publish it in the context of
|
||||
//the contributor bundle.
|
||||
try {
|
||||
JettyBootstrapActivator.registerWebapplication(
|
||||
bundle, warFolderRelativePath, contextPath);
|
||||
} catch (Throwable e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else if (dic.get("Jetty-ContextFilePath") != null) {
|
||||
String contextFileRelativePath = (String)dic.get("Jetty-ContextFilePath");
|
||||
if (contextFileRelativePath == null) {
|
||||
//nothing to register here.
|
||||
return;
|
||||
}
|
||||
//support for multiple webapps in the same bundle:
|
||||
String[] pathes = contextFileRelativePath.split(",");
|
||||
for (String path : pathes) {
|
||||
try {
|
||||
JettyBootstrapActivator.registerContext(
|
||||
bundle, path.trim());
|
||||
} catch (Throwable e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//support for OSGi-RFC66; disclaimer, no access to the actual
|
||||
//(draft) of the spec: just a couple of posts on the world-wide-web.
|
||||
URL rfc66Webxml = bundle.getEntry("/WEB-INF/web.xml");
|
||||
if (rfc66Webxml == null) {
|
||||
return;//no webapp in here
|
||||
}
|
||||
//this is risky: should we make sure that there is no classes and jars directly available
|
||||
//at the root of the of the bundle: otherwise they are accessible
|
||||
//through the browser. we should enforce that the whole classpath is
|
||||
//pointing to files and folders inside WEB-INF. We should filter-out
|
||||
//META-INF too
|
||||
String rfc66ContextPath = getWebContextPath(bundle, dic);
|
||||
try {
|
||||
JettyBootstrapActivator.registerWebapplication(bundle,
|
||||
".", rfc66ContextPath);
|
||||
} catch (Throwable e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getWebContextPath(Bundle bundle, Dictionary<?, ?> dic) {
|
||||
String rfc66ContextPath = (String)dic.get("Web-ContextPath");
|
||||
if (rfc66ContextPath == null) {
|
||||
//extract from the last token of the bundle's location:
|
||||
//(really ?
|
||||
//could consider processing the symbolic name as an alternative
|
||||
//the location will often reflect the version.
|
||||
//maybe this is relevant when the file is a war)
|
||||
String location = bundle.getLocation();
|
||||
String toks[] = location.replace('\\','/').split("/");
|
||||
rfc66ContextPath = toks[toks.length-1];
|
||||
//remove .jar, .war etc:
|
||||
int lastDot = rfc66ContextPath.lastIndexOf('.');
|
||||
if (lastDot != -1) {
|
||||
rfc66ContextPath = rfc66ContextPath.substring(0, lastDot);
|
||||
}
|
||||
}
|
||||
if (!rfc66ContextPath.startsWith("/")) {
|
||||
rfc66ContextPath = "/" + rfc66ContextPath;
|
||||
}
|
||||
return rfc66ContextPath;
|
||||
}
|
||||
|
||||
private void unregister(Bundle bundle) {
|
||||
//nothing to do: when the bundle is stopped, each one of its service
|
||||
//reference is also stopped and that is what we use to stop the corresponding
|
||||
//webapps registered in that bundle.
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,243 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.boot.internal.webapp;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.util.Scanner;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.osgi.framework.FrameworkUtil;
|
||||
import org.osgi.framework.ServiceEvent;
|
||||
import org.osgi.framework.ServiceListener;
|
||||
import org.osgi.framework.ServiceReference;
|
||||
|
||||
/**
|
||||
* When a {@link ContextHandler} service is activated we look into it and if
|
||||
* the corresponding webapp is actually not configured then we go and register it.
|
||||
* <p>
|
||||
* The idea is to always go through this class when we deploy a new webapp
|
||||
* on jetty.
|
||||
* </p>
|
||||
*/
|
||||
public class JettyContextHandlerServiceTracker implements ServiceListener {
|
||||
|
||||
private final WebappRegistrationHelper _helper;
|
||||
|
||||
/** The context-handler to deactivate indexed by context handler */
|
||||
private Map<ServiceReference, ContextHandler> _indexByServiceReference = new HashMap<ServiceReference, ContextHandler>();
|
||||
|
||||
/** The index is the bundle-symbolic-name/paht/to/context/file when there is such thing */
|
||||
private Map<String, ServiceReference> _indexByContextFile = new HashMap<String, ServiceReference>();
|
||||
|
||||
/** or null when */
|
||||
private String _osgiContextHomeFolderCanonicalPath;
|
||||
/** in charge of detecting changes in the osgi contexts home folder. */
|
||||
private Scanner _scanner;
|
||||
|
||||
/**
|
||||
* @param context
|
||||
* @param server
|
||||
*/
|
||||
public JettyContextHandlerServiceTracker(BundleContext context, Server server)
|
||||
throws Exception {
|
||||
_helper = new WebappRegistrationHelper(server);
|
||||
_helper.setup(context, new HashMap<String, String>());
|
||||
File contextHome = _helper.getOSGiContextsHome();
|
||||
if (contextHome != null) {
|
||||
_osgiContextHomeFolderCanonicalPath = contextHome.getCanonicalPath();
|
||||
_scanner = new Scanner();
|
||||
_scanner.setRecursive(true);
|
||||
_scanner.setReportExistingFilesOnStartup(false);
|
||||
_scanner.addListener(new Scanner.DiscreteListener() {
|
||||
public void fileAdded(String filename) throws Exception {
|
||||
//adding a file does not create a new app,
|
||||
//it just reloads it with the new custom file.
|
||||
//well, if the file does not define a context handler,
|
||||
//then in fact it does remove it.
|
||||
reloadJettyContextHandler(filename);
|
||||
}
|
||||
public void fileChanged(String filename) throws Exception {
|
||||
reloadJettyContextHandler(filename);
|
||||
}
|
||||
public void fileRemoved(String filename) throws Exception {
|
||||
//removing a file does not remove the app:
|
||||
//it just goes back to the default embedded in the bundle.
|
||||
//well, if there was no default then it does remove it.
|
||||
reloadJettyContextHandler(filename);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void stop() {
|
||||
if (_scanner != null) {
|
||||
_scanner.stop();
|
||||
}
|
||||
//the class that created the server is also in charge of stopping it.
|
||||
//nothing to stop in the WebappRegistrationHelper
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Receives notification that a service has had a lifecycle change.
|
||||
*
|
||||
* @param ev The <code>ServiceEvent</code> object.
|
||||
*/
|
||||
public void serviceChanged(ServiceEvent ev) {
|
||||
ServiceReference sr = ev.getServiceReference();
|
||||
switch(ev.getType()) {
|
||||
case ServiceEvent.MODIFIED:
|
||||
case ServiceEvent.UNREGISTERING: {
|
||||
ContextHandler ctxtHandler = unregisterInIndex(ev.getServiceReference());
|
||||
if (ctxtHandler != null && !ctxtHandler.isStopped()) {
|
||||
try {
|
||||
_helper.unregister(ctxtHandler);
|
||||
} catch (Exception e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
if (ev.getType() == ServiceEvent.UNREGISTERING) {
|
||||
break;
|
||||
} else {
|
||||
//modified, meaning: we reload it. now that we stopped it; we can register it.
|
||||
}
|
||||
case ServiceEvent.REGISTERED: {
|
||||
Bundle contributor = sr.getBundle();
|
||||
BundleContext context = FrameworkUtil
|
||||
.getBundle(JettyBootstrapActivator.class).getBundleContext();
|
||||
ContextHandler contextHandler = (ContextHandler) context.getService(sr);
|
||||
if (contextHandler.getServer() != null) {
|
||||
//is configured elsewhere.
|
||||
return;
|
||||
}
|
||||
if (contextHandler instanceof WebAppContext) {
|
||||
WebAppContext webapp = (WebAppContext)contextHandler;
|
||||
String contextPath = (String)sr.getProperty("contextPath");
|
||||
if (contextPath == null) {
|
||||
contextPath = webapp.getContextPath();
|
||||
}
|
||||
String war = (String)sr.getProperty("war");
|
||||
try {
|
||||
ContextHandler handler = _helper.registerWebapplication(contributor, war, contextPath);
|
||||
if (handler != null) {
|
||||
registerInIndex(handler, sr);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
} else {
|
||||
//consider this just an empty skeleton:
|
||||
String contextFilePath = (String)sr.getProperty("contextFilePath");
|
||||
if (contextFilePath == null) {
|
||||
throw new IllegalArgumentException("the property contextFilePath is required");
|
||||
}
|
||||
try {
|
||||
ContextHandler handler = _helper.registerContext(contributor, contextFilePath);
|
||||
if (handler != null) {
|
||||
registerInIndex(handler, sr);
|
||||
}
|
||||
} catch (Throwable e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void registerInIndex(ContextHandler handler, ServiceReference sr) {
|
||||
_indexByServiceReference.put(sr, handler);
|
||||
String key = getSymbolicNameAndContextFileKey(sr);
|
||||
if (key != null) {
|
||||
_indexByContextFile.put(key, sr);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the ContextHandler to stop.
|
||||
* @param reg
|
||||
* @return the ContextHandler to stop.
|
||||
*/
|
||||
private ContextHandler unregisterInIndex(ServiceReference sr) {
|
||||
ContextHandler handler = _indexByServiceReference.remove(sr);
|
||||
String key = getSymbolicNameAndContextFileKey(sr);
|
||||
if (key != null) {
|
||||
_indexByContextFile.remove(key);
|
||||
}
|
||||
if (handler == null) {
|
||||
//a warning?
|
||||
return null;
|
||||
}
|
||||
return handler;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param sr
|
||||
* @return The key for a context file within the osgi contexts home folder.
|
||||
*/
|
||||
private String getSymbolicNameAndContextFileKey(ServiceReference sr) {
|
||||
String contextFilePath = (String)sr.getProperty("contextFilePath");
|
||||
if (contextFilePath != null) {
|
||||
return sr.getBundle().getSymbolicName() + "/" + contextFilePath;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Called by the scanner when one of the context files is changed.
|
||||
* @param contextFileFully
|
||||
*/
|
||||
void reloadJettyContextHandler(String canonicalNameOfFileChanged) {
|
||||
String key = getNormalizedRelativePath(canonicalNameOfFileChanged);
|
||||
if (key == null) {
|
||||
return;
|
||||
}
|
||||
ServiceReference sr = _indexByContextFile.get(key);
|
||||
if (sr == null) {
|
||||
//nothing to do?
|
||||
return;
|
||||
}
|
||||
serviceChanged(new ServiceEvent(ServiceEvent.MODIFIED, sr));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param canFilename
|
||||
* @return
|
||||
*/
|
||||
private String getNormalizedRelativePath(String canFilename) {
|
||||
if (!canFilename.startsWith(_osgiContextHomeFolderCanonicalPath)) {
|
||||
//why are we here: this does not look like a child of the osgi contexts home.
|
||||
//warning?
|
||||
return null;
|
||||
}
|
||||
return canFilename.substring(
|
||||
_osgiContextHomeFolderCanonicalPath.length()).replace('\\', '/');
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,216 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.boot.internal.webapp;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.Enumeration;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Magically extract the jettyhome folder from this bundle's jar place it somewhere
|
||||
* in the file-system. Currently we do this only when we detect a system property
|
||||
* 'jetty.magic.home.parent' or if we are inside the pde in dev mode.
|
||||
* In dev mode we use the osgi.configuration.area folder.
|
||||
* </p>
|
||||
* <p>
|
||||
*
|
||||
* </p>
|
||||
*/
|
||||
class JettyHomeHelper {
|
||||
|
||||
/** only magically extract jettyhome if we are inside the pde. */
|
||||
static boolean magic_install_only_in_pde = Boolean.valueOf(
|
||||
System.getProperty("jetty.magic.home.pde.only", "true"));
|
||||
|
||||
/**
|
||||
* Hack for eclipse-PDE.
|
||||
* When no jetty.home was set, detect if we running inside eclipse-PDE
|
||||
* in development mode.
|
||||
* In that case extract the jettyhome folder embedded inside this plugin
|
||||
* inside the configuration area folder. It is specific to the workspace.
|
||||
* Set the folder as jetty.home.
|
||||
* If the folder already exist don't extract it again.
|
||||
* <p>
|
||||
* If we are not pde dev mode, the same but look in the installation folder
|
||||
* of eclipse itself.
|
||||
* </p>
|
||||
*
|
||||
* @return
|
||||
* @throws URISyntaxException
|
||||
*/
|
||||
static String setupJettyHomeInEclipsePDE(File thisbundlejar) {
|
||||
File ecFolder = getParentFolderOfMagicHome();
|
||||
if (ecFolder == null || !ecFolder.exists()) {
|
||||
return null;
|
||||
}
|
||||
File jettyhome = new File(ecFolder, "jettyhome");
|
||||
String path;
|
||||
try {
|
||||
path = jettyhome.getCanonicalPath();
|
||||
if (jettyhome.exists()) {
|
||||
System.setProperty("jetty.home", path);
|
||||
return path;
|
||||
} else {
|
||||
//now grab the jar and unzip the relevant portion
|
||||
unzipJettyHomeIntoDirectory(thisbundlejar, ecFolder);
|
||||
System.setProperty("jetty.home", path);
|
||||
return path;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true when we are currently being run by the pde in development mode.
|
||||
*/
|
||||
private static boolean isPDEDevelopment() {
|
||||
String eclipseCommands = System.getProperty("eclipse.commands");
|
||||
//detect if we are being run from the pde: ie during development.
|
||||
return eclipseCommands != null && eclipseCommands.indexOf("-dev") != -1
|
||||
&& (eclipseCommands.indexOf("-dev\n") != -1
|
||||
|| eclipseCommands.indexOf("-dev\r") != -1
|
||||
|| eclipseCommands.indexOf("-dev ") != -1);
|
||||
}
|
||||
|
||||
// /**
|
||||
// * @return
|
||||
// */
|
||||
// private static File getEclipseInstallationDir() {
|
||||
// return getFile(System.getProperty("eclipse.home.location",
|
||||
// System.getProperty("osgi.install.area")));
|
||||
// }
|
||||
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
private static File getConfigurationAreaDirectory() {
|
||||
return getFile(System.getProperty("osgi.configuration.area"));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param zipFile The current jar file for this bundle. contains an
|
||||
* archive of the default jettyhome
|
||||
* @param parentOfMagicJettyHome The folder inside which jettyhome is created.
|
||||
*/
|
||||
private static void unzipJettyHomeIntoDirectory(File thisbundlejar,
|
||||
File parentOfMagicJettyHome) throws IOException {
|
||||
ZipFile zipFile = null;
|
||||
try {
|
||||
zipFile = new ZipFile(thisbundlejar);
|
||||
Enumeration<? extends ZipEntry> files = zipFile.entries();
|
||||
File f = null;
|
||||
FileOutputStream fos = null;
|
||||
|
||||
while (files.hasMoreElements()) {
|
||||
try {
|
||||
ZipEntry entry = files.nextElement();
|
||||
String entryName = entry.getName();
|
||||
if (!entryName.startsWith("jettyhome")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
InputStream eis = zipFile.getInputStream(entry);
|
||||
byte[] buffer = new byte[1024];
|
||||
int bytesRead = 0;
|
||||
f = new File(parentOfMagicJettyHome, entry.getName());
|
||||
|
||||
if (entry.isDirectory()) {
|
||||
f.mkdirs();
|
||||
} else {
|
||||
f.getParentFile().mkdirs();
|
||||
f.createNewFile();
|
||||
fos = new FileOutputStream(f);
|
||||
while ((bytesRead = eis.read(buffer)) != -1) {
|
||||
fos.write(buffer, 0, bytesRead);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
continue;
|
||||
} finally {
|
||||
if (fos != null) {
|
||||
try { fos.close(); } catch (IOException e) {}
|
||||
fos = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (zipFile != null) try { zipFile.close(); } catch (Throwable t) {}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for the parent folder that contains jettyhome.
|
||||
* Can be specified by the sys property jetty.magic.home.parent
|
||||
* or if inside the pde will default on the configuration area.
|
||||
* Otherwise returns null.
|
||||
*
|
||||
* @return The folder inside which jettyhome should be placed.
|
||||
*/
|
||||
private static File getParentFolderOfMagicHome() {
|
||||
// for (java.util.Map.Entry<Object, Object> e : System.getProperties().entrySet()) {
|
||||
// System.err.println(e.getKey() + " -> " + e.getValue());
|
||||
// }
|
||||
String magicParent = System.getProperty("jetty.magic.home.parent");
|
||||
String magicParentValue = magicParent != null ? System.getProperty(magicParent) : null;
|
||||
File specifiedMagicParent = magicParentValue != null
|
||||
? getFile(magicParentValue) //in that case it was pointing to another system property.
|
||||
: getFile(magicParent); //in that case it was directly a file.
|
||||
if (specifiedMagicParent != null && specifiedMagicParent.exists()) {
|
||||
return specifiedMagicParent;
|
||||
}
|
||||
if (isPDEDevelopment()) {
|
||||
return getConfigurationAreaDirectory();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Be flexible with the url/uri/path that can be the value of the various
|
||||
* system properties.
|
||||
* @param file
|
||||
* @return a file. might not exist.
|
||||
*/
|
||||
private static File getFile(String file) {
|
||||
if (file == null) {
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
if (file.startsWith("file:/")) {
|
||||
if (!file.startsWith("file://")) {
|
||||
return new File(new URI(file));
|
||||
} else {
|
||||
return new File(new URL(file).toURI());
|
||||
}
|
||||
} else {
|
||||
return new File(file);
|
||||
}
|
||||
} catch (Throwable t) {
|
||||
t.printStackTrace();
|
||||
return new File(file);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,108 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.boot.internal.webapp;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.eclipse.jetty.server.Server;
|
||||
|
||||
/**
|
||||
* Helper to create a URL class-loader with the jars inside ${jetty.home}/lib/ext
|
||||
* and ${jetty.home}/resources.
|
||||
* In an ideal world, every library is an OSGi bundle that does loads nicely.
|
||||
* To support standard jars or bundles that cannot be loaded in the current
|
||||
* OSGi environment, we support inserting the jars in the usual jetty/lib/ext
|
||||
* folders in the proper classpath for the webapps.
|
||||
* <p>
|
||||
* For example the test-jndi webapplication depends on derby, derbytools, atomikos
|
||||
* none of them are osgi bundles.
|
||||
* we can either re-package them or we can place them in the usual lib/ext.
|
||||
* <br/>In fact jasper's jsp libraries should maybe place in lib/ext too.
|
||||
* </p>
|
||||
* <p>
|
||||
* The drawback is that those libraries will not be available in the OSGi classloader.
|
||||
* Note that we could have setup those jars as embedded jars of the current bundle.
|
||||
* However, we would need to know in advance what are those jars which was not acceptable.
|
||||
* Also having those jars in a URLClassLoader seem to be required for some cases.
|
||||
* For example jaspers' TldLocationsCache (replaced by TldScanner for servlet-3.0).
|
||||
* <br/>
|
||||
* Also all the dependencies of those libraries must be resolvable directly
|
||||
* from the JettyBooStrapper bundle as it is set as the parent classloader.
|
||||
* For example: if atomikos is placed in lib/ext
|
||||
* it will work if and only if JettyBootStrapper import the necessary packages
|
||||
* from javax.naming*, javax.transaction*, javax.mail* etc
|
||||
* Most of the common cases of javax are added as optional import packages into
|
||||
* jetty bootstrapper plugin. When there are not covered: please make a request
|
||||
* or create a fragment or register a bundle with a buddy-policy onto the jetty bootstrapper..
|
||||
* </p>
|
||||
* <p>
|
||||
* Alternatives to placing jars in lib/ext
|
||||
* <ol>
|
||||
* <li>Bundle the jars in an osgi bundle. Have the webapp(s) that context depends on them
|
||||
* depend on that bundle. Things will go well for jetty.</li>
|
||||
* <li>Bundle those jars in an osgi bundle-fragment that targets the jetty-bootstrap bundle</li>
|
||||
* <li>Use equinox Buddy-Policy: register a buddy of the jetty bootstrapper bundle.
|
||||
* (least favorite: it will work only on equinox)</li>
|
||||
* </ol>
|
||||
* </p>
|
||||
*/
|
||||
public class LibExtClassLoaderHelper {
|
||||
|
||||
/**
|
||||
* @param server
|
||||
* @return a url classloader with the jars of lib/ext. The parent classloader
|
||||
* usuall is the JettyBootStrapper.
|
||||
* @throws MalformedURLException
|
||||
*/
|
||||
public static ClassLoader createLibEtcClassLoaderHelper(File jettyHome, Server server,
|
||||
ClassLoader parentClassLoader)
|
||||
throws MalformedURLException {
|
||||
ArrayList<URL> urls = new ArrayList<URL>();
|
||||
File jettyResources = new File(jettyHome, "resources");
|
||||
if (jettyResources.exists()) {
|
||||
//make sure it contains something else than README:
|
||||
for (File f : jettyResources.listFiles()) {
|
||||
if (f.getName().toLowerCase().startsWith("readme")) {
|
||||
continue;
|
||||
} else {
|
||||
urls.add(jettyResources.toURI().toURL());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
File libEtc = new File(jettyHome, "lib/ext");
|
||||
for (File f : libEtc.listFiles()) {
|
||||
if (f.getName().endsWith(".jar")) {
|
||||
//cheap to tolerate folders so let's do it.
|
||||
URL url = f.toURI().toURL();
|
||||
if (f.isFile()) {//is this necessary anyways?
|
||||
url = new URL("jar:" + url.toString() + "!/");
|
||||
}
|
||||
urls.add(url);
|
||||
}
|
||||
}
|
||||
if (urls.isEmpty()) {
|
||||
return parentClassLoader;
|
||||
}
|
||||
return new URLClassLoader(urls.toArray(new URL[urls.size()]),
|
||||
parentClassLoader);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,863 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.boot.internal.webapp;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.eclipse.jetty.deploy.ConfigurationManager;
|
||||
import org.eclipse.jetty.deploy.ContextDeployer;
|
||||
import org.eclipse.jetty.deploy.WebAppDeployer;
|
||||
import org.eclipse.jetty.osgi.boot.JettyBootstrapActivator;
|
||||
import org.eclipse.jetty.osgi.boot.internal.jsp.TldLocatableURLClassloader;
|
||||
import org.eclipse.jetty.osgi.boot.internal.jsp.TldLocatableURLClassloaderWithInsertedJettyClassloader;
|
||||
import org.eclipse.jetty.osgi.boot.utils.BundleClassLoaderHelper;
|
||||
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper;
|
||||
import org.eclipse.jetty.osgi.boot.utils.WebappRegistrationCustomizer;
|
||||
import org.eclipse.jetty.osgi.boot.utils.internal.DefaultBundleClassLoaderHelper;
|
||||
import org.eclipse.jetty.osgi.boot.utils.internal.DefaultFileLocatorHelper;
|
||||
import org.eclipse.jetty.server.Server;
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.util.AttributesMap;
|
||||
import org.eclipse.jetty.webapp.JettyWebXmlConfiguration;
|
||||
import org.eclipse.jetty.webapp.WebAppClassLoader;
|
||||
import org.eclipse.jetty.webapp.WebAppContext;
|
||||
import org.eclipse.jetty.webapp.WebXmlConfiguration;
|
||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
import org.osgi.framework.Bundle;
|
||||
import org.osgi.framework.BundleContext;
|
||||
import org.xml.sax.SAXException;
|
||||
|
||||
/**
|
||||
* Bridges the traditional web-application deployers: {@link WebAppDeployer} and {@link ContextDeployer} with the OSGi lifecycle where applications are managed
|
||||
* inside OSGi-bundles.
|
||||
* <p>
|
||||
* This class should be called as a consequence of the activation of a new service that is a ContextHandler.<br/>
|
||||
* This way the new webapps are exposed as OSGi services.
|
||||
* </p>
|
||||
* <p>
|
||||
* Helper methods to register a bundle that is a web-application or a context. It is deployed as if the server was using its WebAppDeployer or ContextDeployer
|
||||
* as configured in its etc/jetty.xml file. Well as close as possible to that.
|
||||
* </p>
|
||||
* Limitations:
|
||||
* <ul>
|
||||
* <li>support for jarred webapps is somewhat limited.</li>
|
||||
* </ul>
|
||||
*/
|
||||
class WebappRegistrationHelper
|
||||
{
|
||||
|
||||
private static boolean INITIALIZED = false;
|
||||
|
||||
/** By default set to: {@link DefaultBundleClassLoaderHelper}. It supports equinox and apache-felix
|
||||
* fragment bundles that are specific to an OSGi implementation should set a different implementation. */
|
||||
public static BundleClassLoaderHelper BUNDLE_CLASS_LOADER_HELPER = null;
|
||||
/** By default set to: {@link DefaultBundleClassLoaderHelper}. It supports equinox and apache-felix
|
||||
* fragment bundles that are specific to an OSGi implementation should set a different implementation. */
|
||||
public static BundleFileLocatorHelper BUNDLE_FILE_LOCATOR_HELPER = null;
|
||||
|
||||
/** By default set to: {@link DefaultBundleClassLoaderHelper}. It supports equinox and apache-felix
|
||||
* fragment bundles that are specific to an OSGi implementation should set a different implementation. */
|
||||
public static WebappRegistrationCustomizer JSP_REGISTRATION_HELPER = null;
|
||||
|
||||
private Server _server;
|
||||
private ContextDeployer _ctxtDeployer;
|
||||
private WebAppDeployer _webappDeployer;
|
||||
private ContextHandlerCollection _ctxtHandler;
|
||||
|
||||
/**
|
||||
* this class loader loads the jars inside {$jetty.home}/lib/ext it is meant as a migration path and for jars that are not OSGi ready.
|
||||
*/
|
||||
private ClassLoader _libEtcClassLoader;
|
||||
|
||||
public WebappRegistrationHelper(Server server)
|
||||
{
|
||||
_server = server;
|
||||
staticInit();
|
||||
}
|
||||
|
||||
//Inject the customizing classes that might be defined in fragment bundles.
|
||||
private static synchronized void staticInit() {
|
||||
if (!INITIALIZED) {
|
||||
INITIALIZED = true;
|
||||
//setup the custom WebappRegistrationCustomizer
|
||||
try
|
||||
{
|
||||
Class<?> cl = Class.forName(WebappRegistrationCustomizer.CLASS_NAME);
|
||||
JSP_REGISTRATION_HELPER = (WebappRegistrationCustomizer)
|
||||
cl.newInstance();
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
// System.err.println("no jsp/jasper support");
|
||||
// System.exit(1);
|
||||
}
|
||||
//setup the custom BundleClassLoaderHelper
|
||||
try
|
||||
{
|
||||
BUNDLE_CLASS_LOADER_HELPER = (BundleClassLoaderHelper)
|
||||
Class.forName(BundleClassLoaderHelper.CLASS_NAME).newInstance();
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
// System.err.println("support for equinox and felix");
|
||||
BUNDLE_CLASS_LOADER_HELPER = new DefaultBundleClassLoaderHelper();
|
||||
}
|
||||
//setup the custom FileLocatorHelper
|
||||
try
|
||||
{
|
||||
BUNDLE_FILE_LOCATOR_HELPER = (BundleFileLocatorHelper)
|
||||
Class.forName(BundleFileLocatorHelper.CLASS_NAME).newInstance();
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
// System.err.println("no jsp/jasper support");
|
||||
BUNDLE_FILE_LOCATOR_HELPER = new DefaultFileLocatorHelper();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for the home directory of jetty as defined by the system property 'jetty.home'. If undefined, look at the current bundle and uses its own jettyhome
|
||||
* folder for this feature.
|
||||
* <p>
|
||||
* Special case: inside eclipse-SDK:<br/>
|
||||
* If the bundle is jarred, see if we are inside eclipse-PDE itself. In that case, look for the installation directory of eclipse-PDE, try to create a
|
||||
* jettyhome folder there and install the sample jettyhome folder at that location. This makes the installation in eclipse-SDK easier.
|
||||
* </p>
|
||||
*
|
||||
* @param context
|
||||
* @throws Exception
|
||||
*/
|
||||
public void setup(BundleContext context, Map<String, String> configProperties) throws Exception
|
||||
{
|
||||
File _installLocation = BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(context.getBundle());
|
||||
// debug:
|
||||
// new File("~/proj/eclipse-install/eclipse-3.5.1-SDK-jetty7/" +
|
||||
// "dropins/jetty7/plugins/org.eclipse.jetty.osgi.boot_0.0.1.001-SNAPSHOT.jar");
|
||||
boolean bootBundleCanBeJarred = true;
|
||||
String jettyHome = System.getProperty("jetty.home");
|
||||
if (jettyHome == null || jettyHome.length() == 0)
|
||||
{
|
||||
if (_installLocation.getName().endsWith(".jar"))
|
||||
{
|
||||
jettyHome = JettyHomeHelper.setupJettyHomeInEclipsePDE(_installLocation);
|
||||
}
|
||||
if (jettyHome == null)
|
||||
{
|
||||
jettyHome = _installLocation.getAbsolutePath() + "/jettyhome";
|
||||
bootBundleCanBeJarred = false;
|
||||
}
|
||||
System.setProperty("jetty.home",jettyHome);
|
||||
}
|
||||
String jettyLogs = System.getProperty("jetty.logs");
|
||||
if (jettyLogs == null || jettyLogs.length() == 0)
|
||||
{
|
||||
System.setProperty("jetty.logs",System.getProperty("jetty.home") + "/logs");
|
||||
}
|
||||
|
||||
if (!bootBundleCanBeJarred && !_installLocation.isDirectory())
|
||||
{
|
||||
String install = _installLocation != null?_installLocation.getCanonicalPath():" unresolved_install_location";
|
||||
throw new IllegalArgumentException("The system property -Djetty.home" + " must be set to a directory or the bundle "
|
||||
+ context.getBundle().getSymbolicName() + " installed here " + install + " must be unjarred.");
|
||||
|
||||
}
|
||||
try
|
||||
{
|
||||
System.err.println("JETTY_HOME set to " + new File(jettyHome).getCanonicalPath());
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
System.err.println("JETTY_HOME _set to " + new File(jettyHome).getAbsolutePath());
|
||||
}
|
||||
|
||||
ClassLoader contextCl = Thread.currentThread().getContextClassLoader();
|
||||
try
|
||||
{
|
||||
|
||||
XmlConfiguration config = new XmlConfiguration(new FileInputStream(jettyHome + "/etc/jetty.xml"));
|
||||
config.getProperties().put("jetty.home", jettyHome);
|
||||
|
||||
// passing this bundle's classloader as the context classlaoder
|
||||
// makes sure there is access to all the jetty's bundles
|
||||
|
||||
File jettyHomeF = new File(jettyHome);
|
||||
try
|
||||
{
|
||||
_libEtcClassLoader = LibExtClassLoaderHelper.createLibEtcClassLoaderHelper(jettyHomeF,_server,JettyBootstrapActivator.class.getClassLoader());
|
||||
}
|
||||
catch (MalformedURLException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
Thread.currentThread().setContextClassLoader(_libEtcClassLoader);
|
||||
config.configure(_server);
|
||||
|
||||
init();
|
||||
|
||||
_server.start();
|
||||
// _server.join();
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
t.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
Thread.currentThread().setContextClassLoader(contextCl);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Must be called after the server is configured.
|
||||
*
|
||||
* Locate the actual instance of the ContextDeployer and WebAppDeployer that was created when configuring the server through jetty.xml. If there is no such
|
||||
* thing it won't be possible to deploy webapps from a context and we throw IllegalStateExceptions.
|
||||
*/
|
||||
private void init()
|
||||
{
|
||||
|
||||
// [Hugues] if no jndi is setup let's do it.
|
||||
// we could also get the bundle for jetty-jndi and open the corresponding properties file
|
||||
// instead of hardcoding the values: but they are unlikely to change.
|
||||
if (System.getProperty("java.naming.factory.initial") == null)
|
||||
{
|
||||
System.setProperty("java.naming.factory.initial","org.eclipse.jetty.jndi.InitialContextFactory");
|
||||
}
|
||||
if (System.getProperty("java.naming.factory.url.pkgs") == null)
|
||||
{
|
||||
System.setProperty("java.naming.factory.url.pkgs","org.eclipse.jetty.jndi");
|
||||
}
|
||||
|
||||
_ctxtHandler = (ContextHandlerCollection)_server.getChildHandlerByClass(ContextHandlerCollection.class);
|
||||
if (_ctxtHandler == null)
|
||||
{
|
||||
throw new IllegalStateException("ERROR: No ContextHandlerCollection was configured" + " with the server to add applications to."
|
||||
+ "Using a default one is not supported at" + " this point. " + " Please review the jetty.xml file used.");
|
||||
}
|
||||
List<ContextDeployer> ctxtDeployers = _server.getBeans(ContextDeployer.class);
|
||||
|
||||
if (ctxtDeployers == null || ctxtDeployers.isEmpty())
|
||||
{
|
||||
System.err.println("Warn: No ContextDeployer was configured" + " with the server. Using a default one is not supported at" + " this point. "
|
||||
+ " Please review the jetty.xml file used.");
|
||||
}
|
||||
else
|
||||
{
|
||||
_ctxtDeployer = ctxtDeployers.get(0);
|
||||
}
|
||||
List<WebAppDeployer> wDeployers = _server.getBeans(WebAppDeployer.class);
|
||||
|
||||
if (wDeployers == null || wDeployers.isEmpty())
|
||||
{
|
||||
System.err.println("Warn: No WebappDeployer was configured" + " with the server. Using a default one is not supported at" + " this point. "
|
||||
+ " Please review the jetty.xml file used.");
|
||||
}
|
||||
else
|
||||
{
|
||||
_webappDeployer = (WebAppDeployer)wDeployers.get(0);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Deploy a new web application on the jetty server.
|
||||
*
|
||||
* @param context
|
||||
* The current bundle context
|
||||
* @param webappFolderPath
|
||||
* The path to the root of the webapp. Must be a path relative to bundle; either an absolute path.
|
||||
* @param contextPath
|
||||
* The context path. Must start with "/"
|
||||
* @param classInBundle
|
||||
* A class that belongs to the current bundle to inherit from the osgi classloader. Null to not have access to the OSGI classloader.
|
||||
* @throws Exception
|
||||
*/
|
||||
public ContextHandler registerWebapplication(Bundle bundle, String webappFolderPath, String contextPath) throws Exception
|
||||
{
|
||||
File bundleInstall = BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(bundle);
|
||||
File webapp = webappFolderPath != null && webappFolderPath.length() != 0
|
||||
&& !webappFolderPath.equals(".")
|
||||
? new File(bundleInstall,webappFolderPath)
|
||||
: bundleInstall;
|
||||
if (!webapp.exists())
|
||||
{
|
||||
throw new IllegalArgumentException("Unable to locate "
|
||||
+ webappFolderPath + " inside "
|
||||
+ (bundleInstall != null
|
||||
? bundleInstall.getAbsolutePath()
|
||||
: "unlocated bundle '" + bundle.getSymbolicName() + "'"));
|
||||
}
|
||||
return registerWebapplication(bundle,webapp,contextPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* @See {@link WebAppDeployer#scan()}
|
||||
*
|
||||
* @param webapp
|
||||
* @param contextPath
|
||||
* @param classInBundle
|
||||
* @return The contexthandler created and started
|
||||
* @throws Exception
|
||||
*/
|
||||
public ContextHandler registerWebapplication(Bundle contributor, File webapp, String contextPath) throws Exception
|
||||
{
|
||||
|
||||
ClassLoader contextCl = Thread.currentThread().getContextClassLoader();
|
||||
String[] oldServerClasses = null;
|
||||
WebAppContext context = null;
|
||||
try
|
||||
{
|
||||
// make sure we provide access to all the jetty bundles by going through this bundle.
|
||||
TldLocatableURLClassloader composite = createContextClassLoader(contributor);
|
||||
// configure with access to all jetty classes and also all the classes
|
||||
// that the contributor gives access to.
|
||||
Thread.currentThread().setContextClassLoader(composite);
|
||||
|
||||
context = new WebAppContext(webapp.getAbsolutePath(),contextPath);
|
||||
|
||||
WebXmlConfiguration webXml = new WebXmlConfiguration();
|
||||
webXml.configure(context);
|
||||
|
||||
JettyWebXmlConfiguration jettyXml = new JettyWebXmlConfiguration();
|
||||
jettyXml.configure(context);
|
||||
|
||||
configureWebAppContext(context);
|
||||
|
||||
// ok now register this webapp. we checked when we started jetty that there
|
||||
// was at least one such handler for webapps.
|
||||
_ctxtHandler.addHandler(context);
|
||||
|
||||
configureContextClassLoader(context,composite);
|
||||
|
||||
// @see org.eclipse.jetty.webapp.JettyWebXmlConfiguration#configure(WebAppContext)
|
||||
oldServerClasses = context.getServerClasses();
|
||||
context.setServerClasses(null);
|
||||
context.start();
|
||||
|
||||
return context;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (context != null)
|
||||
{
|
||||
context.setServerClasses(oldServerClasses);
|
||||
}
|
||||
Thread.currentThread().setContextClassLoader(contextCl);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop a ContextHandler and remove it from the collection.
|
||||
*
|
||||
* @See ContextDeployer#undeploy
|
||||
* @param contextHandler
|
||||
* @throws Exception
|
||||
*/
|
||||
public void unregister(ContextHandler contextHandler) throws Exception
|
||||
{
|
||||
contextHandler.stop();
|
||||
_ctxtHandler.removeHandler(contextHandler);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The folder in which the context files of the osgi bundles are
|
||||
* located and watched. Or null when the system property
|
||||
* "jetty.osgi.contexts.home" is not defined.
|
||||
*/
|
||||
File getOSGiContextsHome()
|
||||
{
|
||||
String jettyContextsHome = System.getProperty("jetty.osgi.contexts.home");
|
||||
if (jettyContextsHome != null)
|
||||
{
|
||||
File contextsHome = new File(jettyContextsHome);
|
||||
if (!contextsHome.exists() || !contextsHome.isDirectory())
|
||||
{
|
||||
throw new IllegalArgumentException("the ${jetty.osgi.contexts.home} '" + jettyContextsHome + " must exist and be a folder");
|
||||
}
|
||||
return contextsHome;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* This type of registration relies on jetty's complete context xml file.
|
||||
* Context encompasses jndi and all other things.
|
||||
* This makes the definition of the webapp a lot more self-contained.
|
||||
*
|
||||
* @param webapp
|
||||
* @param contextPath
|
||||
* @param classInBundle
|
||||
* @throws Exception
|
||||
*/
|
||||
public ContextHandler registerContext(Bundle contributor, String contextFileRelativePath) throws Exception
|
||||
{
|
||||
File contextsHome = getOSGiContextsHome();
|
||||
if (contextsHome != null)
|
||||
{
|
||||
File prodContextFile = new File(contextsHome,contributor.getSymbolicName() + "/" + contextFileRelativePath);
|
||||
if (prodContextFile.exists())
|
||||
{
|
||||
return registerContext(contributor,prodContextFile);
|
||||
}
|
||||
}
|
||||
File contextFile = new File(BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(contributor),contextFileRelativePath);
|
||||
if (contextFile.exists())
|
||||
{
|
||||
return registerContext(contributor,contextFile);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (contextFileRelativePath.startsWith("./"))
|
||||
{
|
||||
contextFileRelativePath = contextFileRelativePath.substring(1);
|
||||
}
|
||||
if (!contextFileRelativePath.startsWith("/"))
|
||||
{
|
||||
contextFileRelativePath = "/" + contextFileRelativePath;
|
||||
}
|
||||
URL contextURL = contributor.getEntry(contextFileRelativePath);
|
||||
if (contextURL != null)
|
||||
{
|
||||
return registerContext(contributor,contextURL.openStream());
|
||||
}
|
||||
throw new IllegalArgumentException("Could not find the context " + "file " + contextFileRelativePath + " for the bundle "
|
||||
+ contributor.getSymbolicName());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* This type of registration relies on jetty's complete context xml file.
|
||||
* Context encompasses jndi and all other things. This makes the definition of the
|
||||
* webapp a lot more self-contained.
|
||||
*
|
||||
* @param webapp
|
||||
* @param contextPath
|
||||
* @param classInBundle
|
||||
* @throws Exception
|
||||
*/
|
||||
private ContextHandler registerContext(Bundle contributor, File contextFile) throws Exception
|
||||
{
|
||||
InputStream contextFileInputStream = null;
|
||||
try
|
||||
{
|
||||
contextFileInputStream = new BufferedInputStream(new FileInputStream(contextFile));
|
||||
return registerContext(contributor,contextFileInputStream);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (contextFileInputStream != null)
|
||||
try
|
||||
{
|
||||
contextFileInputStream.close();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private ContextHandler registerContext(Bundle contributor, InputStream contextFileInputStream) throws Exception
|
||||
{
|
||||
ClassLoader contextCl = Thread.currentThread().getContextClassLoader();
|
||||
String[] oldServerClasses = null;
|
||||
WebAppContext webAppContext = null;
|
||||
try
|
||||
{
|
||||
// make sure we provide access to all the jetty bundles by going through this bundle.
|
||||
TldLocatableURLClassloader composite = createContextClassLoader(contributor);
|
||||
// configure with access to all jetty classes and also all the classes
|
||||
// that the contributor gives access to.
|
||||
Thread.currentThread().setContextClassLoader(composite);
|
||||
ContextHandler context = createContextHandler(contributor,contextFileInputStream);
|
||||
// //[H]extra work for the path to the file:
|
||||
// if (context instanceof WebAppContext) {
|
||||
// WebAppContext wah = (WebAppContext)context;
|
||||
// Resource.newResource(wah.getWar());
|
||||
// }
|
||||
|
||||
// ok now register this webapp. we checked when we started jetty that there
|
||||
// was at least one such handler for webapps.
|
||||
_ctxtHandler.addHandler(context);
|
||||
|
||||
configureContextClassLoader(context,composite);
|
||||
if (context instanceof WebAppContext)
|
||||
{
|
||||
webAppContext = (WebAppContext)context;
|
||||
// @see org.eclipse.jetty.webapp.JettyWebXmlConfiguration#configure(WebAppContext)
|
||||
oldServerClasses = webAppContext.getServerClasses();
|
||||
webAppContext.setServerClasses(null);
|
||||
}
|
||||
|
||||
context.start();
|
||||
return context;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (webAppContext != null)
|
||||
{
|
||||
webAppContext.setServerClasses(oldServerClasses);
|
||||
}
|
||||
Thread.currentThread().setContextClassLoader(contextCl);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO: right now only the jetty-jsp bundle is scanned for common taglibs. Should support a way to plug more bundles that contain taglibs.
|
||||
*
|
||||
* The jasper TldScanner expects a URLClassloader to parse a jar for the /META-INF/*.tld it may contain. We place the bundles that we know contain such
|
||||
* tag-libraries. Please note that it will work if and only if the bundle is a jar (!) Currently we just hardcode the bundle that contains the jstl
|
||||
* implemenation.
|
||||
*
|
||||
* A workaround when the tld cannot be parsed with this method is to copy and paste it inside the WEB-INF of the webapplication where it is used.
|
||||
*
|
||||
* Support only 2 types of packaging for the bundle: - the bundle is a jar (recommended for runtime.) - the bundle is a folder and contain jars in the root
|
||||
* and/or in the lib folder (nice for PDE developement situations) Unsupported: the bundle is a jar that embeds more jars.
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
private URL[] getJarsWithTlds() throws Exception
|
||||
{
|
||||
if (JSP_REGISTRATION_HELPER != null)
|
||||
{
|
||||
return JSP_REGISTRATION_HELPER.getJarsWithTlds(BUNDLE_FILE_LOCATOR_HELPER);
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies the properties of WebAppDeployer as defined in jetty.xml.
|
||||
*
|
||||
* @see {WebAppDeployer#scan} around the comment <code>// configure it</code>
|
||||
*/
|
||||
protected void configureWebAppContext(WebAppContext wah)
|
||||
{
|
||||
// configure it
|
||||
// wah.setContextPath(context);
|
||||
String[] _configurationClasses = _webappDeployer.getConfigurationClasses();
|
||||
String _defaultsDescriptor = _webappDeployer.getDefaultsDescriptor();
|
||||
boolean _parentLoaderPriority = _webappDeployer.isParentLoaderPriority();
|
||||
AttributesMap _contextAttributes = getWebAppDeployerContextAttributes();
|
||||
|
||||
if (_configurationClasses != null)
|
||||
wah.setConfigurationClasses(_configurationClasses);
|
||||
if (_defaultsDescriptor != null)
|
||||
wah.setDefaultsDescriptor(_defaultsDescriptor);
|
||||
// wah.setExtractWAR(_extract);//[H]should we force to extract ?
|
||||
// wah.setWar(app.toString());//[H]should we force to extract ?
|
||||
wah.setParentLoaderPriority(_parentLoaderPriority);
|
||||
|
||||
// set up any contextAttributes
|
||||
wah.setAttributes(new AttributesMap(_contextAttributes));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @See {@link ContextDeployer#scan}
|
||||
* @param contextFile
|
||||
* @return
|
||||
*/
|
||||
protected ContextHandler createContextHandler(Bundle bundle, File contextFile)
|
||||
{
|
||||
try
|
||||
{
|
||||
return createContextHandler(bundle,new BufferedInputStream(new FileInputStream(contextFile)));
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @See {@link ContextDeployer#scan}
|
||||
* @param contextFile
|
||||
* @return
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
protected ContextHandler createContextHandler(Bundle bundle, InputStream contextInputStream)
|
||||
{
|
||||
|
||||
/*
|
||||
* Do something identical to what the ContextDeployer would have done: XmlConfiguration xmlConfiguration=new XmlConfiguration(resource.getURL());
|
||||
* HashMap properties = new HashMap(); properties.put("Server", _contexts.getServer()); if (_configMgr!=null)
|
||||
* properties.putAll(_configMgr.getProperties());
|
||||
*
|
||||
* xmlConfiguration.setProperties(properties); ContextHandler context=(ContextHandler)xmlConfiguration.configure(); context.setAttributes(new
|
||||
* AttributesMap(_contextAttributes));
|
||||
*/
|
||||
ConfigurationManager _configMgr = getContextDeployerConfigurationManager();
|
||||
AttributesMap _contextAttributes = getContextDeployerContextAttributes();
|
||||
try
|
||||
{
|
||||
XmlConfiguration xmlConfiguration = new XmlConfiguration(contextInputStream);
|
||||
HashMap<String, Object> properties = new HashMap<String, Object>();
|
||||
properties.put("Server",_server);
|
||||
if (_configMgr != null)
|
||||
{
|
||||
properties.putAll(_configMgr.getProperties());
|
||||
}
|
||||
// insert the bundle's location as a property.
|
||||
setThisBundleHomeProperty(bundle,properties);
|
||||
xmlConfiguration.setProperties(properties);
|
||||
|
||||
// bug in equinox? if jetty plus is an optionally required-bundle, then we can't load the class!
|
||||
// JettyBootstrapActivator.class.getClassLoader().loadClass("org.eclipse.jetty.plus.jndi.EnvEntry");
|
||||
// FrameworkUtil.getBundle(JettyBootstrapActivator.class).loadClass("org.eclipse.jetty.plus.jndi.EnvEntry");
|
||||
// in fact the pde can't find it at compilation time and shows a warning "Unsatisfied version constraint: ..."
|
||||
// System.err.println(EnvEntry.class);
|
||||
ContextHandler context = (ContextHandler)xmlConfiguration.configure();
|
||||
context.setAttributes(new AttributesMap(_contextAttributes));
|
||||
|
||||
// rfc-66:
|
||||
context.setAttribute("osgi-bundlecontext",bundle.getBundleContext());
|
||||
|
||||
return context;
|
||||
}
|
||||
catch (FileNotFoundException e)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
catch (SAXException e)
|
||||
{
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
catch (Throwable e)
|
||||
{
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (contextInputStream != null)
|
||||
try
|
||||
{
|
||||
contextInputStream.close();
|
||||
}
|
||||
catch (IOException ioe)
|
||||
{
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure a classloader onto the context. If the context is a WebAppContext, build a WebAppClassLoader that has access to all the jetty classes thanks to
|
||||
* the classloader of the JettyBootStrapper bundle and also has access to the classloader of the bundle that defines this context.
|
||||
* <p>
|
||||
* If the context is not a WebAppContext, same but with a simpler URLClassLoader. Note that the URLClassLoader is pretty much fake: it delegate all actual
|
||||
* classloading to the parent classloaders.
|
||||
* </p>
|
||||
* <p>
|
||||
* The URL[] returned by the URLClassLoader create contained specifically the jars that some j2ee tools expect and look into. For example the jars that
|
||||
* contain tld files for jasper's jstl support.
|
||||
* </p>
|
||||
*
|
||||
* @param context
|
||||
* @param contributor
|
||||
* @param webapp
|
||||
* @param contextPath
|
||||
* @param classInBundle
|
||||
* @throws Exception
|
||||
*/
|
||||
protected void configureContextClassLoader(ContextHandler context, TldLocatableURLClassloader composite) throws Exception
|
||||
{
|
||||
if (context instanceof WebAppContext)
|
||||
{
|
||||
WebAppContext webappCtxt = (WebAppContext)context;
|
||||
// updateServerClasses(webappCtxt);
|
||||
WebAppClassLoader wcl = new WebAppClassLoader(composite,webappCtxt);
|
||||
|
||||
// addJarsWithTlds(wcl);
|
||||
context.setClassLoader(wcl);
|
||||
}
|
||||
else
|
||||
{
|
||||
context.setClassLoader(composite);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Right now we avoid this by doing what JettWebXmlConfiguration is doing during the configureWebapp method call: set the serverclasses to null and when
|
||||
* done put back the limitations as defined.
|
||||
*
|
||||
* We need to test that though.
|
||||
*
|
||||
* TODO: review this with the jetty team: how do you let cometd cleanly access jetty-client, jetty-io, jetty-http from osgi? The webapp-classloader of jetty
|
||||
* refuses to delegate loading the class to the parent classloader if that class belongs to the org.eclipse.jetty package or one of its descendants: make
|
||||
* sure they isolate the webapp from the server.
|
||||
*
|
||||
* Maybe we need to somehow chagne the way we buidl the webappcontext classloader so that the osgi classloader is not the parent of the webappclassloader.
|
||||
*
|
||||
*/
|
||||
private static String[] visibleinOsgi = new String[]
|
||||
{ "-org.eclipse.jetty.util.", "-org.eclipse.jetty.io.", "-org.eclipse.jetty.client.", "-org.eclipse.jetty.http.", "-org.eclipse.jetty.osgi." };
|
||||
|
||||
/**
|
||||
* @deprecated not so good.
|
||||
* @see WebAppContext#setServerClasses(String[]) We make org.eclipse.jetty.osgi visible if they are hidden.
|
||||
*/
|
||||
private void updateServerClasses(WebAppContext webappCtxt)
|
||||
{
|
||||
String[] serverClasses = webappCtxt.getServerClasses();
|
||||
for (String s : serverClasses)
|
||||
{
|
||||
if (s.startsWith("-org.eclipse.jetty.osgi."))
|
||||
{
|
||||
return;// ok already visible
|
||||
}
|
||||
}
|
||||
String[] serverClasses2 = new String[serverClasses.length + visibleinOsgi.length];
|
||||
System.arraycopy(visibleinOsgi,0,serverClasses2,0,visibleinOsgi.length);
|
||||
System.arraycopy(serverClasses,0,serverClasses2,visibleinOsgi.length,serverClasses.length);
|
||||
webappCtxt.setServerClasses(serverClasses2);
|
||||
}
|
||||
|
||||
protected TldLocatableURLClassloader createContextClassLoader(Bundle contributor) throws Exception
|
||||
{
|
||||
ClassLoader osgiCl = BUNDLE_CLASS_LOADER_HELPER.getBundleClassLoader(contributor);
|
||||
if (osgiCl != null)
|
||||
{
|
||||
// this solution does not insert all the jetty related classes in the webapp's classloader:
|
||||
// WebAppClassLoader cl = new WebAppClassLoader(classInBundle.getClassLoader(), context);
|
||||
// context.setClassLoader(cl);
|
||||
|
||||
// Make all of the jetty's classes available to the webapplication classloader
|
||||
// also add the contributing bundle's classloader to give access to osgi to
|
||||
// the contributed webapp.
|
||||
TldLocatableURLClassloader composite =
|
||||
new TldLocatableURLClassloaderWithInsertedJettyClassloader(
|
||||
_libEtcClassLoader,osgiCl, getJarsWithTlds());
|
||||
return composite;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Make all of the jetty's classes available to the webapplication classloader
|
||||
TldLocatableURLClassloader composite = new TldLocatableURLClassloader(
|
||||
_libEtcClassLoader,getJarsWithTlds());
|
||||
return composite;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the property "this.bundle.install" to point to the location of the bundle. Useful when <SystemProperty name="this.bundle.home"/> is used.
|
||||
*/
|
||||
private void setThisBundleHomeProperty(Bundle bundle, HashMap<String, Object> properties)
|
||||
{
|
||||
try
|
||||
{
|
||||
File location = BUNDLE_FILE_LOCATOR_HELPER.getBundleInstallLocation(bundle);
|
||||
properties.put("this.bundle.install",location.getCanonicalPath());
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
System.err.println("Unable to set 'this.bundle.install' " + " for the bundle " + bundle.getSymbolicName());
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
// some private suff in ContextDeployer that we need to
|
||||
// be faithful to the ContextDeployer definition created in etc/jetty.xml
|
||||
// kindly ask to have a public getter for those?
|
||||
private static Field CONTEXT_DEPLOYER_CONFIGURATION_MANAGER_FIELD = null;
|
||||
private static Field CONTEXT_DEPLOYER_CONTEXT_ATTRIBUTES_FIELD = null;
|
||||
|
||||
private ConfigurationManager getContextDeployerConfigurationManager()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (CONTEXT_DEPLOYER_CONFIGURATION_MANAGER_FIELD == null)
|
||||
{
|
||||
CONTEXT_DEPLOYER_CONFIGURATION_MANAGER_FIELD = ContextDeployer.class.getDeclaredField("_configMgr");
|
||||
CONTEXT_DEPLOYER_CONFIGURATION_MANAGER_FIELD.setAccessible(true);
|
||||
}
|
||||
return (ConfigurationManager)CONTEXT_DEPLOYER_CONFIGURATION_MANAGER_FIELD.get(_ctxtDeployer);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
t.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private AttributesMap getContextDeployerContextAttributes()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (CONTEXT_DEPLOYER_CONTEXT_ATTRIBUTES_FIELD == null)
|
||||
{
|
||||
CONTEXT_DEPLOYER_CONTEXT_ATTRIBUTES_FIELD = ContextDeployer.class.getDeclaredField("_contextAttributes");
|
||||
CONTEXT_DEPLOYER_CONTEXT_ATTRIBUTES_FIELD.setAccessible(true);
|
||||
}
|
||||
return (AttributesMap)CONTEXT_DEPLOYER_CONTEXT_ATTRIBUTES_FIELD.get(_ctxtDeployer);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
t.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
private static Field WEBAPP_DEPLOYER_CONTEXT_ATTRIBUTES_FIELD = null;
|
||||
|
||||
private AttributesMap getWebAppDeployerContextAttributes()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (WEBAPP_DEPLOYER_CONTEXT_ATTRIBUTES_FIELD == null)
|
||||
{
|
||||
WEBAPP_DEPLOYER_CONTEXT_ATTRIBUTES_FIELD = WebAppDeployer.class.getDeclaredField("_contextAttributes");
|
||||
WEBAPP_DEPLOYER_CONTEXT_ATTRIBUTES_FIELD.setAccessible(true);
|
||||
}
|
||||
return (AttributesMap)WEBAPP_DEPLOYER_CONTEXT_ATTRIBUTES_FIELD.get(_webappDeployer);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
t.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.boot.utils;
|
||||
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
/**
|
||||
* Is there a clean OSGi way to go from the Bundle object to the classloader of the Bundle ?
|
||||
* You can certainly take a class inside the bundle and get the bundle's classloader
|
||||
* that way. Getting the classloader directly from the bundle would be nice.
|
||||
* <p>
|
||||
* We could use fragments that are specific to each OSGi implementation.
|
||||
* Using introspection here to keep packaging simple and avoid the multiplication of the jars.
|
||||
* </p>
|
||||
* <p>
|
||||
* The default implementation relies on introspection and supports equinox-3.5 and felix-2.0.0
|
||||
* </p>
|
||||
*/
|
||||
public interface BundleClassLoaderHelper
|
||||
{
|
||||
|
||||
/** The name of the custom implementation for this interface in a fragment. */
|
||||
public static final String CLASS_NAME = "org.eclipse.jetty.osgi.boot.utils.BundleClassLoaderHelperImpl";
|
||||
|
||||
/**
|
||||
* @return The classloader of a given bundle. Assuming the bundle is started.
|
||||
*/
|
||||
public ClassLoader getBundleClassLoader(Bundle bundle);
|
||||
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.boot.utils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
/**
|
||||
* From a bundle to its location on the filesystem. Assumes the bundle is not a jar.
|
||||
*
|
||||
* @author hmalphettes
|
||||
*/
|
||||
public interface BundleFileLocatorHelper
|
||||
{
|
||||
|
||||
/** The name of the custom implementation for this interface in a fragment. */
|
||||
public static final String CLASS_NAME = "org.eclipse.jetty.osgi.boot.utils.FileLocatorHelperImpl";
|
||||
|
||||
/**
|
||||
* Works with equinox, felix, nuxeo and probably more. Not exactly in the
|
||||
* spirit of OSGi but quite necessary to support self-contained webapps and other
|
||||
* situations.
|
||||
* <p>
|
||||
* Currently only works with bundles that are not jar.
|
||||
* </p>
|
||||
*
|
||||
* @param bundle
|
||||
* The bundle
|
||||
* @return Its installation location as a file.
|
||||
* @throws Exception
|
||||
*/
|
||||
public File getBundleInstallLocation(Bundle bundle) throws Exception;
|
||||
|
||||
/**
|
||||
* Locate a file inside a bundle.
|
||||
*
|
||||
* @param bundle
|
||||
* @param path
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public File getFileInBundle(Bundle bundle, String path) throws Exception;
|
||||
|
||||
/**
|
||||
* If the bundle is a jar, returns the jar. If the bundle is a folder, look inside it and search for jars that it returns.
|
||||
* <p>
|
||||
* Good enough for our purpose (TldLocationsCache when it scans for tld files inside jars alone.
|
||||
* In fact we only support the second situation for
|
||||
* development purpose where the bundle was imported in pde and the classes kept in a jar.
|
||||
* </p>
|
||||
*
|
||||
* @param bundle
|
||||
* @return The jar(s) file that is either the bundle itself, either the jars embedded inside it.
|
||||
*/
|
||||
public File[] locateJarsInsideBundle(Bundle bundle) throws Exception;
|
||||
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.boot.utils;
|
||||
|
||||
import java.net.URL;
|
||||
|
||||
|
||||
/**
|
||||
* Fix various shortcomings with the way jasper parses the tld files.
|
||||
*/
|
||||
public interface WebappRegistrationCustomizer
|
||||
{
|
||||
/** we could do something a lot more pluggable with
|
||||
* a custom header in the manifest or some customer declarative services
|
||||
* let's keep it simple for now. hopefully the rest of the world
|
||||
* won't need to customize this. */
|
||||
public static final String CLASS_NAME = "org.eclipse.jetty.osgi.boot.jasper.WebappRegistrationCustomizerImpl";
|
||||
|
||||
/**
|
||||
* TODO: right now only the jetty-jsp bundle is scanned for common taglibs. Should support a way to plug more bundles that contain taglibs.
|
||||
*
|
||||
* The jasper TldScanner expects a URLClassloader to parse a jar for the /META-INF/*.tld it may contain. We place the bundles that we know contain such
|
||||
* tag-libraries. Please note that it will work if and only if the bundle is a jar (!) Currently we just hardcode the bundle that contains the jstl
|
||||
* implemenation.
|
||||
*
|
||||
* A workaround when the tld cannot be parsed with this method is to copy and paste it inside the WEB-INF of the webapplication where it is used.
|
||||
*
|
||||
* Support only 2 types of packaging for the bundle: - the bundle is a jar (recommended for runtime.) - the bundle is a folder and contain jars in the root
|
||||
* and/or in the lib folder (nice for PDE developement situations) Unsupported: the bundle is a jar that embeds more jars.
|
||||
*
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
URL[] getJarsWithTlds(BundleFileLocatorHelper fileLocator) throws Exception;
|
||||
|
||||
}
|
|
@ -0,0 +1,181 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.boot.utils.internal;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import org.eclipse.jetty.osgi.boot.utils.BundleClassLoaderHelper;
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
/**
|
||||
* Default implementation of the BundleClassLoaderHelper.
|
||||
* Uses introspection to support equinox-3.5 and felix-2.0.0
|
||||
*/
|
||||
public class DefaultBundleClassLoaderHelper implements BundleClassLoaderHelper
|
||||
{
|
||||
|
||||
private static boolean identifiedOsgiImpl = false;
|
||||
private static boolean isEquinox = false;
|
||||
private static boolean isFelix = false;
|
||||
|
||||
private static void init(Bundle bundle)
|
||||
{
|
||||
identifiedOsgiImpl = true;
|
||||
try
|
||||
{
|
||||
isEquinox = bundle.getClass().getClassLoader().loadClass("org.eclipse.osgi.framework.internal.core.BundleHost") != null;
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
isEquinox = false;
|
||||
}
|
||||
if (!isEquinox)
|
||||
{
|
||||
try
|
||||
{
|
||||
isFelix = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.BundleImpl") != null;
|
||||
}
|
||||
catch (Throwable t2)
|
||||
{
|
||||
isFelix = false;
|
||||
}
|
||||
}
|
||||
// System.err.println("isEquinox=" + isEquinox);
|
||||
// System.err.println("isFelix=" + isFelix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Assuming the bundle is started.
|
||||
*
|
||||
* @param bundle
|
||||
* @return
|
||||
*/
|
||||
public ClassLoader getBundleClassLoader(Bundle bundle)
|
||||
{
|
||||
String bundleActivator = (String)bundle.getHeaders().get("Bundle-Activator");
|
||||
if (bundleActivator == null)
|
||||
{
|
||||
bundleActivator = (String)bundle.getHeaders().get("Jetty-ClassInBundle");
|
||||
}
|
||||
if (bundleActivator != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
return bundle.loadClass(bundleActivator).getClassLoader();
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
// should not happen as we are called if the bundle is started anyways.
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
// resort to introspection
|
||||
if (!identifiedOsgiImpl)
|
||||
{
|
||||
init(bundle);
|
||||
}
|
||||
if (isEquinox)
|
||||
{
|
||||
return internalGetEquinoxBundleClassLoader(bundle);
|
||||
}
|
||||
else if (isFelix)
|
||||
{
|
||||
return internalGetFelixBundleClassLoader(bundle);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Method Equinox_BundleHost_getBundleLoader_method;
|
||||
private static Method Equinox_BundleLoader_createClassLoader_method;
|
||||
|
||||
private static ClassLoader internalGetEquinoxBundleClassLoader(Bundle bundle)
|
||||
{
|
||||
// assume equinox:
|
||||
try
|
||||
{
|
||||
if (Equinox_BundleHost_getBundleLoader_method == null)
|
||||
{
|
||||
Equinox_BundleHost_getBundleLoader_method = bundle.getClass().getClassLoader().loadClass("org.eclipse.osgi.framework.internal.core.BundleHost")
|
||||
.getDeclaredMethod("getBundleLoader",new Class[] {});
|
||||
Equinox_BundleHost_getBundleLoader_method.setAccessible(true);
|
||||
}
|
||||
Object bundleLoader = Equinox_BundleHost_getBundleLoader_method.invoke(bundle,new Object[] {});
|
||||
if (Equinox_BundleLoader_createClassLoader_method == null && bundleLoader != null)
|
||||
{
|
||||
Equinox_BundleLoader_createClassLoader_method = bundleLoader.getClass().getClassLoader().loadClass(
|
||||
"org.eclipse.osgi.internal.loader.BundleLoader").getDeclaredMethod("createClassLoader",new Class[] {});
|
||||
Equinox_BundleLoader_createClassLoader_method.setAccessible(true);
|
||||
}
|
||||
return (ClassLoader)Equinox_BundleLoader_createClassLoader_method.invoke(bundleLoader,new Object[] {});
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
t.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Field Felix_BundleImpl_m_modules_field;
|
||||
private static Field Felix_ModuleImpl_m_classLoader_field;
|
||||
|
||||
private static ClassLoader internalGetFelixBundleClassLoader(Bundle bundle)
|
||||
{
|
||||
// assume felix:
|
||||
try
|
||||
{
|
||||
// now get the current module from the bundle.
|
||||
// and return the private field m_classLoader of ModuleImpl
|
||||
if (Felix_BundleImpl_m_modules_field == null)
|
||||
{
|
||||
Felix_BundleImpl_m_modules_field = bundle.getClass().getClassLoader()
|
||||
.loadClass("org.apache.felix.framework.BundleImpl").getDeclaredField(
|
||||
"m_modules");
|
||||
Felix_BundleImpl_m_modules_field.setAccessible(true);
|
||||
}
|
||||
Object[] moduleArray = (Object[])Felix_BundleImpl_m_modules_field.get(bundle);
|
||||
Object currentModuleImpl = moduleArray[moduleArray.length - 1];
|
||||
if (Felix_ModuleImpl_m_classLoader_field == null && currentModuleImpl != null)
|
||||
{
|
||||
Felix_ModuleImpl_m_classLoader_field = bundle.getClass().getClassLoader().loadClass("org.apache.felix.framework.ModuleImpl").getDeclaredField(
|
||||
"m_classLoader");
|
||||
Felix_ModuleImpl_m_classLoader_field.setAccessible(true);
|
||||
}
|
||||
// first make sure that the classloader is ready:
|
||||
// the m_classLoader field must be initialized by the ModuleImpl.getClassLoader() private method.
|
||||
ClassLoader cl = (ClassLoader)Felix_ModuleImpl_m_classLoader_field.get(currentModuleImpl);
|
||||
if (cl == null)
|
||||
{
|
||||
// looks like it was not ready:
|
||||
// the m_classLoader field must be initialized by the ModuleImpl.getClassLoader() private method.
|
||||
// this call will do that.
|
||||
bundle.loadClass("java.lang.Object");
|
||||
cl = (ClassLoader)Felix_ModuleImpl_m_classLoader_field.get(currentModuleImpl);
|
||||
// System.err.println("Got the bundle class loader of felix_: " + cl);
|
||||
return cl;
|
||||
}
|
||||
else
|
||||
{
|
||||
// System.err.println("Got the bundle class loader of felix: " + cl);
|
||||
return cl;
|
||||
}
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
t.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,202 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.boot.utils.internal;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.net.URLConnection;
|
||||
import java.util.ArrayList;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import org.eclipse.jetty.osgi.boot.utils.BundleFileLocatorHelper;
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
/**
|
||||
* From a bundle to its location on the filesystem. Assumes the bundle is not a jar.
|
||||
*
|
||||
* @author hmalphettes
|
||||
*/
|
||||
public class DefaultFileLocatorHelper implements BundleFileLocatorHelper
|
||||
{
|
||||
|
||||
// hack to locate the file-system directly from the bundle.
|
||||
// support equinox, felix and nuxeo's osgi implementations.
|
||||
// not tested on nuxeo and felix just yet.
|
||||
// The url nuxeo and felix return is created directly from the File so it should work.
|
||||
private static Field BUNDLE_ENTRY_FIELD = null;
|
||||
private static Field FILE_FIELD = null;
|
||||
|
||||
private static Field BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY = null;// ZipBundleFile inside DirZipBundleEntry
|
||||
|
||||
private static Field ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE = null;// ZipFile
|
||||
|
||||
/**
|
||||
* Works with equinox, felix, nuxeo and probably more.
|
||||
* Not exactly in the spirit of OSGi but quite necessary to support self-contained webapps and other
|
||||
* situations.
|
||||
* <p>
|
||||
* Currently only works with bundles that are not jar.
|
||||
* </p>
|
||||
*
|
||||
* @param bundle
|
||||
* The bundle
|
||||
* @return Its installation location as a file.
|
||||
* @throws Exception
|
||||
*/
|
||||
public File getBundleInstallLocation(Bundle bundle) throws Exception
|
||||
{
|
||||
// String installedBundles = System.getProperty("osgi.bundles");
|
||||
// grab the MANIFEST.MF's url
|
||||
// and then do what it takes.
|
||||
URL url = bundle.getEntry("/META-INF/MANIFEST.MF");
|
||||
// System.err.println(url.toString() + " " + url.toURI() + " " + url.getProtocol());
|
||||
if (url.getProtocol().equals("file"))
|
||||
{
|
||||
// some osgi frameworks do use the file protocole directly in some situations
|
||||
return new File(url.toURI()).getParentFile().getParentFile();
|
||||
}
|
||||
else if (url.getProtocol().equals("bundleentry"))
|
||||
{
|
||||
// say hello to equinox who has its own protocol.
|
||||
// we use introspection like there is no tomorrow to get access to the File
|
||||
URLConnection con = url.openConnection();
|
||||
if (BUNDLE_ENTRY_FIELD == null)
|
||||
{
|
||||
BUNDLE_ENTRY_FIELD = con.getClass().getDeclaredField("bundleEntry");
|
||||
BUNDLE_ENTRY_FIELD.setAccessible(true);
|
||||
}
|
||||
Object bundleEntry = BUNDLE_ENTRY_FIELD.get(con);
|
||||
if (bundleEntry.getClass().getName().equals("org.eclipse.osgi.baseadaptor.bundlefile.FileBundleEntry"))
|
||||
{
|
||||
if (FILE_FIELD == null)
|
||||
{
|
||||
FILE_FIELD = bundleEntry.getClass().getDeclaredField("file");
|
||||
FILE_FIELD.setAccessible(true);
|
||||
}
|
||||
File f = (File)FILE_FIELD.get(bundleEntry);
|
||||
return f.getParentFile().getParentFile();
|
||||
}
|
||||
else if (bundleEntry.getClass().getName().equals("org.eclipse.osgi.baseadaptor.bundlefile.ZipBundleEntry"))
|
||||
{
|
||||
url = bundle.getEntry("/");
|
||||
con = url.openConnection();
|
||||
if (BUNDLE_ENTRY_FIELD == null)
|
||||
{// this one will be a DirZipBundleEntry
|
||||
BUNDLE_ENTRY_FIELD = con.getClass().getDeclaredField("bundleEntry");
|
||||
BUNDLE_ENTRY_FIELD.setAccessible(true);
|
||||
}
|
||||
bundleEntry = BUNDLE_ENTRY_FIELD.get(con);
|
||||
if (BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY == null)
|
||||
{
|
||||
BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY = bundleEntry.getClass().getDeclaredField("bundleFile");
|
||||
BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY.setAccessible(true);
|
||||
}
|
||||
Object zipBundleFile = BUNDLE_FILE_FIELD_FOR_DIR_ZIP_BUNDLE_ENTRY.get(bundleEntry);
|
||||
if (ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE == null)
|
||||
{
|
||||
ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE = zipBundleFile.getClass().getDeclaredField("zipFile");
|
||||
ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE.setAccessible(true);
|
||||
}
|
||||
ZipFile zipFile = (ZipFile)ZIP_FILE_FILED_FOR_ZIP_BUNDLE_FILE.get(zipBundleFile);
|
||||
return new File(zipFile.getName());
|
||||
}
|
||||
else if (bundleEntry.getClass().getName().equals("org.eclipse.osgi.baseadaptor.bundlefile.DirZipBundleEntry"))
|
||||
{
|
||||
// that will not happen as we did ask for the manifest not a directory.
|
||||
}
|
||||
}
|
||||
else if ("bundle".equals(url.getProtocol()))
|
||||
{
|
||||
// observed this on felix-2.0.0
|
||||
String location = bundle.getLocation();
|
||||
if (location.startsWith("file:/"))
|
||||
{
|
||||
URI uri = new URI(bundle.getLocation());
|
||||
return new File(uri);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Locate a file inside a bundle.
|
||||
*
|
||||
* @param bundle
|
||||
* @param path
|
||||
* @return
|
||||
* @throws Exception
|
||||
*/
|
||||
public File getFileInBundle(Bundle bundle, String path) throws Exception
|
||||
{
|
||||
if (path != null && path.length() > 0 && path.charAt(0) == '/')
|
||||
{
|
||||
path = path.substring(1);
|
||||
}
|
||||
File bundleInstall = getBundleInstallLocation(bundle);
|
||||
File webapp = path != null && path.length() != 0?new File(bundleInstall,path):bundleInstall;
|
||||
if (!webapp.exists())
|
||||
{
|
||||
throw new IllegalArgumentException("Unable to locate " + path + " inside " + bundle.getSymbolicName() + " ("
|
||||
+ (bundleInstall != null?bundleInstall.getAbsolutePath():" no_bundle_location ") + ")");
|
||||
}
|
||||
return webapp;
|
||||
}
|
||||
|
||||
/**
|
||||
* If the bundle is a jar, returns the jar. If the bundle is a folder, look inside it and search for jars that it returns.
|
||||
* <p>
|
||||
* Good enough for our purpose (TldLocationsCache when it scans for tld files inside jars alone. In fact we only support the second situation for
|
||||
* development purpose where the bundle was imported in pde and the classes kept in a jar.
|
||||
* </p>
|
||||
*
|
||||
* @param bundle
|
||||
* @return The jar(s) file that is either the bundle itself, either the jars embedded inside it.
|
||||
*/
|
||||
public File[] locateJarsInsideBundle(Bundle bundle) throws Exception
|
||||
{
|
||||
File jasperLocation = getBundleInstallLocation(bundle);
|
||||
if (jasperLocation.isDirectory())
|
||||
{
|
||||
// try to find the jar files inside this folder
|
||||
ArrayList<File> urls = new ArrayList<File>();
|
||||
for (File f : jasperLocation.listFiles())
|
||||
{
|
||||
if (f.getName().endsWith(".jar") && f.isFile())
|
||||
{
|
||||
urls.add(f);
|
||||
}
|
||||
else if (f.isDirectory() && f.getName().equals("lib"))
|
||||
{
|
||||
for (File f2 : jasperLocation.listFiles())
|
||||
{
|
||||
if (f2.getName().endsWith(".jar") && f2.isFile())
|
||||
{
|
||||
urls.add(f2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return urls.toArray(new File[urls.size()]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return new File[]
|
||||
{ jasperLocation };
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: OSGi HttpService provided by equinox HttpServiceServlet deployed on jetty
|
||||
Bundle-SymbolicName: org.eclipse.jetty.osgi.httpservice
|
||||
Bundle-Version: 7.0.1.qualifier
|
||||
Bundle-Vendor: Intalio Inc
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
Import-Package: javax.servlet;version="2.5.0",
|
||||
javax.servlet.http;version="2.5.0",
|
||||
org.osgi.service.http;version="1.2.0",
|
||||
org.eclipse.equinox.http.servlet
|
||||
Jetty-ContextFilePath: contexts/httpservice.xml
|
|
@ -0,0 +1,4 @@
|
|||
source.. = src/main/java/
|
||||
output.. = target/classes/
|
||||
bin.includes = META-INF/,\
|
||||
.
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
<!--
|
||||
// ========================================================================
|
||||
// Copyright (c) 2004-2009 Mort Bay Consulting Pty. Ltd.
|
||||
//
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
-->
|
||||
<Configure class="org.eclipse.jetty.servlet.ServletContextHandler">
|
||||
<!-- this servlet provides the OSGi HTTP Service once it is initialized -->
|
||||
<Call name="addServlet">
|
||||
<Arg>org.eclipse.jetty.osgi.httpservice.HttpServiceServletX</Arg>
|
||||
<Arg>/*</Arg>
|
||||
</Call>
|
||||
</Configure>
|
|
@ -0,0 +1,28 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.httpservice;
|
||||
|
||||
import org.eclipse.equinox.http.servlet.HttpServiceServlet;
|
||||
|
||||
/**
|
||||
* Once this servlet is initialized, it provides the OSGi HttpService.
|
||||
* Compliments of equinox. Currently has no added value.
|
||||
*/
|
||||
public class HttpServiceServletX extends HttpServiceServlet
|
||||
{
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
|
@ -0,0 +1,16 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Eclipse PDE Run Configuration
|
||||
Bundle-SymbolicName: org.eclipse.jetty.osgi.pde.launch;singleton:=true
|
||||
Bundle-Version: 1.0.0.qualifier
|
||||
Bundle-Activator: org.eclipse.jetty.osgi.pde.launch.JettyOSGiPDEPlugin
|
||||
Bundle-Vendor: Intalio Inc
|
||||
Require-Bundle: org.eclipse.ui,
|
||||
org.eclipse.core.runtime,
|
||||
org.eclipse.debug.core;bundle-version="3.5.0",
|
||||
org.eclipse.pde.ui;bundle-version="3.5.0",
|
||||
org.eclipse.debug.ui;bundle-version="3.5.0",
|
||||
org.eclipse.core.variables;bundle-version="3.2.200",
|
||||
org.eclipse.jdt.debug.ui;bundle-version="3.4.1"
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
Bundle-ActivationPolicy: lazy
|
|
@ -0,0 +1,5 @@
|
|||
source.. = src/main/java/
|
||||
output.. = target/classes/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
plugin.xml
|
Binary file not shown.
After Width: | Height: | Size: 815 B |
|
@ -0,0 +1,97 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?eclipse version="3.4"?>
|
||||
<!--
|
||||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
//
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
-->
|
||||
<plugin>
|
||||
<extension
|
||||
point="org.eclipse.debug.core.launchConfigurationTypes">
|
||||
<launchConfigurationType
|
||||
delegate="org.eclipse.jetty.osgi.pde.launch.ui.JettyEquinoxLaunchConfiguration"
|
||||
delegateDescription="Launch Jetty in OSGi"
|
||||
delegateName="%PDELaunchDelegate.name"
|
||||
id="org.eclipse.jetty.osgi.pde.launch.ui.jettyosgilaunch"
|
||||
migrationDelegate="org.eclipse.pde.internal.ui.launcher.OSGiMigrationDelegate"
|
||||
modes="run, debug"
|
||||
name="Launch Jetty in OSGi"
|
||||
sourceLocatorId="org.eclipse.pde.ui.launcher.PDESourceLookupDirector"
|
||||
sourcePathComputerId="org.eclipse.jdt.launching.sourceLookup.javaSourcePathComputer">
|
||||
</launchConfigurationType>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.debug.ui.launchConfigurationTypeImages">
|
||||
<launchConfigurationTypeImage
|
||||
icon="$nl$/icons/jetty.png"
|
||||
configTypeID="org.eclipse.jetty.osgi.pde.launch.ui.jettyosgilaunch"
|
||||
id="org.eclipse.jetty.osgi.pde.launch.jettyLaunchImage">
|
||||
</launchConfigurationTypeImage>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.debug.ui.launchShortcuts">
|
||||
<shortcut
|
||||
label="Jetty on OSGi"
|
||||
icon="$nl$/icons/jetty.png"
|
||||
modes="run, debug"
|
||||
class="org.eclipse.jetty.osgi.pde.launch.ui.JettyLaunchShortcut"
|
||||
id="org.eclipse.jetty.osgi.pde.launch.runjetty">
|
||||
<contextualLaunch>
|
||||
<enablement>
|
||||
<with variable="selection">
|
||||
<count value="1"/>
|
||||
<iterate>
|
||||
<and>
|
||||
<instanceof value="org.eclipse.core.runtime.IAdaptable"/>
|
||||
<test property="org.eclipse.debug.ui.projectNature" value="org.eclipse.pde.PluginNature"/>
|
||||
<or>
|
||||
<adapt type="org.eclipse.core.resources.IProject"/>
|
||||
<test property="org.eclipse.debug.ui.matchesPattern" value="MANIFEST.MF"/>
|
||||
</or>
|
||||
</and>
|
||||
</iterate>
|
||||
</with>
|
||||
</enablement>
|
||||
</contextualLaunch>
|
||||
<configurationType
|
||||
id="org.eclipse.jetty.osgi.pde.launch.ui.jettyosgilaunch">
|
||||
</configurationType>
|
||||
<description
|
||||
description="Lauch jetty in OSGi and deploy the OSGi webapps"
|
||||
mode="run">
|
||||
</description>
|
||||
<description
|
||||
description="Debug jetty in OSGi and the OSGi webapps"
|
||||
mode="debug">
|
||||
</description>
|
||||
</shortcut>
|
||||
</extension>
|
||||
<extension
|
||||
point="org.eclipse.debug.ui.launchConfigurationTabGroups">
|
||||
<launchConfigurationTabGroup
|
||||
type="org.eclipse.jetty.osgi.pde.launch.ui.jettyosgilaunch"
|
||||
class="org.eclipse.jetty.osgi.pde.launch.ui.JettyOSGiLauncherTabGroup"
|
||||
id="org.eclipse.jetty.osgi.pde.launch.ui.EquinoxLauncherTabGroup">
|
||||
<launchMode
|
||||
description="Create a configuration to launch Jetty in OSGi in debug mode"
|
||||
perspective="org.eclipse.debug.ui.DebugPerspective"
|
||||
mode="debug">
|
||||
</launchMode>
|
||||
<launchMode
|
||||
description="Create a configuration to launch Jetty in OSGi in run mode"
|
||||
mode="run">
|
||||
</launchMode>
|
||||
</launchConfigurationTabGroup>
|
||||
</extension>
|
||||
</plugin>
|
|
@ -0,0 +1,28 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.pde.launch;
|
||||
|
||||
/**
|
||||
* Configuration constants.
|
||||
*/
|
||||
public class JettyConfigurationConstants
|
||||
{
|
||||
private static final String PLUGIN_ID = JettyOSGiPDEPlugin.PLUGIN_ID;
|
||||
|
||||
/** Points to the jetty home folder */
|
||||
public static final String ATTR_JETTY_HOME = PLUGIN_ID + ".jettyhome";
|
||||
public static final String JETTY_HOME_DEFAULT = "${workspace_loc}/jettyhome";
|
||||
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.pde.launch;
|
||||
|
||||
import org.eclipse.osgi.util.NLS;
|
||||
|
||||
/**
|
||||
* NLS
|
||||
*/
|
||||
public class JettyLauncherMessages extends NLS
|
||||
{
|
||||
private static final String BUNDLE_NAME = "org.eclipse.jetty.osgi.pde.launch.JettyLauncherMessages";//$NON-NLS-1$
|
||||
|
||||
public static String JettyConfigurationLaunchTab_JettyConfigurationTitle;
|
||||
public static String JettyConfigurationLaunchTab_VariablesButtonLabel;
|
||||
|
||||
public static String JettyXmlBlock_JettyConfigurationBlockTitle;
|
||||
public static String JettyXmlBlock_JettyConfigurationBlockLabel;
|
||||
public static String JettyXmlBlock_VariablesButtonLabel;
|
||||
|
||||
public static String JettyXmlEditDialog_Cancel;
|
||||
public static String JettyXmlEditDialog_OK;
|
||||
public static String JettyXmlEditDialog_Apply;
|
||||
public static String JettyXmlEditDialog_Edit_jetty_xml;
|
||||
public static String JettyXmlEditDialog_Edit_jetty_xml_title;
|
||||
|
||||
static {
|
||||
// load message values from bundle file
|
||||
NLS.initializeMessages(BUNDLE_NAME, JettyLauncherMessages.class);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
# ========================================================================
|
||||
# Copyright (c) 2009 Intalio, Inc.
|
||||
# ------------------------------------------------------------------------
|
||||
# All rights reserved. This program and the accompanying materials
|
||||
# are made available under the terms of the Eclipse Public License v1.0
|
||||
# and Apache License v2.0 which accompanies this distribution.
|
||||
# The Eclipse Public License is available at
|
||||
# http://www.eclipse.org/legal/epl-v10.html
|
||||
# The Apache License v2.0 is available at
|
||||
# http://www.opensource.org/licenses/apache2.0.php
|
||||
# Contributors:
|
||||
# Hugues Malphettes - initial API and implementation
|
||||
# You may elect to redistribute this code under either of these licenses.
|
||||
# ========================================================================
|
||||
JettyConfigurationLaunchTab_JettyConfigurationTitle=Jetty &Configuration
|
||||
JettyConfigurationLaunchTab_VariablesButtonLabel=Var&iables...
|
||||
JettyXmlBlock_JettyConfigurationBlockTitle=jetty.xml configuration file:
|
||||
JettyXmlBlock_JettyConfigurationBlockLabel=jetty.xml &configuration file:
|
||||
JettyXmlBlock_VariablesButtonLabel=Variable&s
|
||||
JettyXmlEditDialog_Cancel=Cancel
|
||||
JettyXmlEditDialog_OK=OK
|
||||
JettyXmlEditDialog_Apply=Apply
|
||||
JettyXmlEditDialog_Edit_jetty_xml_title=Edit jetty.xml
|
||||
JettyXmlEditDialog_Edit_jetty_xml=Edit jetty.xml in ${0}
|
|
@ -0,0 +1,71 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.pde.launch;
|
||||
|
||||
import org.eclipse.ui.plugin.AbstractUIPlugin;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
* The activator class controls the plug-in life cycle
|
||||
*/
|
||||
public class JettyOSGiPDEPlugin extends AbstractUIPlugin
|
||||
{
|
||||
|
||||
// The plug-in ID
|
||||
public static final String PLUGIN_ID = "org.eclipse.jetty.osgi.pde.core";
|
||||
|
||||
// The shared instance
|
||||
private static JettyOSGiPDEPlugin plugin;
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*/
|
||||
public JettyOSGiPDEPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception
|
||||
{
|
||||
super.start(context);
|
||||
plugin = this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception
|
||||
{
|
||||
plugin = null;
|
||||
super.stop(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shared instance
|
||||
*
|
||||
* @return the shared instance
|
||||
*/
|
||||
public static JettyOSGiPDEPlugin getDefault()
|
||||
{
|
||||
return plugin;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,471 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.pde.launch.internal;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStreamWriter;
|
||||
import java.net.URI;
|
||||
import java.nio.channels.FileChannel;
|
||||
import java.util.Enumeration;
|
||||
import java.util.zip.ZipEntry;
|
||||
import java.util.zip.ZipFile;
|
||||
|
||||
import org.eclipse.core.resources.IContainer;
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.core.resources.IFolder;
|
||||
import org.eclipse.core.resources.IResource;
|
||||
import org.eclipse.core.resources.IWorkspaceRoot;
|
||||
import org.eclipse.core.resources.ResourcesPlugin;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.FileLocator;
|
||||
import org.eclipse.core.runtime.Path;
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.core.variables.IStringVariableManager;
|
||||
import org.eclipse.core.variables.VariablesPlugin;
|
||||
import org.osgi.framework.Bundle;
|
||||
|
||||
/**
|
||||
* Utility methods related to jetty home and jetty.xml.
|
||||
* Default will be something like this:
|
||||
* ${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/Launch Jetty in OSGi
|
||||
*/
|
||||
public class JettyHomeHelper
|
||||
{
|
||||
/**
|
||||
* Helper
|
||||
* @return The bundle that is in charge of starting jetty in OSGi.
|
||||
*/
|
||||
private static Bundle getJettyOSGiBootBundle()
|
||||
{
|
||||
return Platform.getBundle("org.eclipse.jetty.osgi.boot");
|
||||
}
|
||||
|
||||
private static String resolveVariables(String target) {
|
||||
IStringVariableManager manager = VariablesPlugin.getDefault().getStringVariableManager();
|
||||
try
|
||||
{
|
||||
return manager.performStringSubstitution(target, false);
|
||||
}
|
||||
catch (CoreException e)
|
||||
{
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves strings that start with "${workspace_loc:"
|
||||
* or "${workspace}"
|
||||
* Useful as the default configuration area used by pde is:
|
||||
* ${workspace_loc}/.metadata/.plugins/org.eclipse.pde.core/${name_of_configuration}
|
||||
* @see IStringVariableManager
|
||||
* @see org.eclipse.pde.internal.ui.launcher.ConfigurationTemplateBlock
|
||||
* @return The container
|
||||
*/
|
||||
public static IContainer getContainerFromWorkspace(String path)
|
||||
{
|
||||
// /.../theworkspace/.metadata/.plugins/org.eclipse.pde.core/Launch Jetty in OSGi/jettyhome
|
||||
if (path == null || path.trim().length() == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();
|
||||
if (path.startsWith("${workspace_loc:"))
|
||||
{
|
||||
path = resolveVariables(path);
|
||||
return root.getContainerForLocation(new Path(path).makeAbsolute());
|
||||
}
|
||||
else if (path.startsWith("${workspace_loc}"))
|
||||
{
|
||||
path = path.substring("${workspace_loc}".length());
|
||||
path = resolveVariables(path);
|
||||
IFolder f = root.getFolder(new Path(path).makeAbsolute());
|
||||
if (f.getRawLocation() == null) {
|
||||
IContainer c = root.getContainerForLocation(new Path(path).makeAbsolute());
|
||||
if (c != null) {
|
||||
return c;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
IResource res = root.findMember(path);
|
||||
if (res instanceof IContainer)
|
||||
{
|
||||
return (IContainer) res;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Resolves strings and try to make it a file in the filesystem.
|
||||
* @see IStringVariableManager
|
||||
* @see org.eclipse.pde.internal.ui.launcher.ConfigurationTemplateBlock
|
||||
* @return The container
|
||||
*/
|
||||
public static File getFileOutsideOfWorkspace(String path)
|
||||
{
|
||||
if (path == null || path.trim().length() == 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return new File(resolveVariables(path));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* The current content of jettyXml
|
||||
*/
|
||||
public static String getCurrentJettyXml(String jettyHomePath, boolean returnNullIfJettyXmlIsNull)
|
||||
{
|
||||
IContainer container = JettyHomeHelper.getContainerFromWorkspace(jettyHomePath);
|
||||
if (container != null)
|
||||
{
|
||||
IFile jettyXml = container.getFile(new Path("jettyhome/etc/jetty.xml"));
|
||||
if (!jettyXml.exists()) {
|
||||
//does not exist at this point:
|
||||
//just read the one in the bundle directly.
|
||||
return returnNullIfJettyXmlIsNull ? null : JettyHomeHelper.getJettyXmlInsideBootBundle();
|
||||
} else {
|
||||
//return the one that exists already.
|
||||
return JettyHomeHelper.loadIFileAsString(jettyXml);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
File configArea = JettyHomeHelper.getFileOutsideOfWorkspace(jettyHomePath);
|
||||
File jettyXml = new File(configArea, "jettyhome/etc/jetty.xml");
|
||||
if (jettyXml.exists()) {
|
||||
return JettyHomeHelper.loadFileAsString(jettyXml);
|
||||
} else {
|
||||
//does not exist at this point:
|
||||
//just read the one in the bundle directly.
|
||||
return returnNullIfJettyXmlIsNull ? null : JettyHomeHelper.getJettyXmlInsideBootBundle();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @return The content of jetty.xml inside the boot bundle.
|
||||
*/
|
||||
public static String getJettyXmlInsideBootBundle()
|
||||
{
|
||||
Bundle b = getJettyOSGiBootBundle();
|
||||
try
|
||||
{
|
||||
InputStream is = b.getEntry("/jettyhome/etc/jetty.xml").openStream();
|
||||
return loadInputAsString(is);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Something really straight forward to read the content of the file.
|
||||
* It is just jetty.xml: no need to be really fast and optimized here.
|
||||
*/
|
||||
public static String loadFileAsString(File jettyXml)
|
||||
{
|
||||
try
|
||||
{
|
||||
return loadInputAsString(new FileInputStream(jettyXml));
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
/**
|
||||
* Something really straight forward to read the content of the file.
|
||||
* It is just jetty.xml: no need to be really fast and optimized here.
|
||||
*/
|
||||
public static String loadIFileAsString(IFile jettyXml)
|
||||
{
|
||||
try
|
||||
{
|
||||
return loadInputAsString(jettyXml.getContents());
|
||||
}
|
||||
catch (CoreException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Something really straight forward to read the content of the file.
|
||||
* It is just jetty.xml: no need to be really fast and optimized here.
|
||||
*/
|
||||
public static String loadInputAsString(InputStream is)
|
||||
{
|
||||
StringBuilder sb = new StringBuilder();
|
||||
try
|
||||
{
|
||||
BufferedReader reader = new BufferedReader(new InputStreamReader(is,"UTF-8")); //$NON-NLS-1$
|
||||
String newline = System.getProperty("line.separator"); //$NON-NLS-1$
|
||||
String line = null;
|
||||
while ((line = reader.readLine()) != null)
|
||||
{
|
||||
sb.append(line + newline);
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
finally
|
||||
{
|
||||
try
|
||||
{
|
||||
is.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public static File resolveJettyHome(String jettyHomeInConfig) {
|
||||
IContainer container = JettyHomeHelper.getContainerFromWorkspace(jettyHomeInConfig);
|
||||
if (container != null)
|
||||
{
|
||||
URI rawURI = container.getRawLocationURI();
|
||||
if (rawURI != null) {
|
||||
//it is null when the folder is not inside a project.
|
||||
return new File(rawURI);
|
||||
}
|
||||
}
|
||||
return JettyHomeHelper.getFileOutsideOfWorkspace(jettyHomeInConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* Look for the jettyhome folder.
|
||||
* If empty or it does not exist, extract the default one from the boot.
|
||||
*
|
||||
*
|
||||
* @param jettyXml custom content for jetty.xml or null if we keep the default one.
|
||||
* @param jettyHomePath path to jettyhome as set by the user.
|
||||
*/
|
||||
public static void setupJettyHomeAndJettyXML(String jettyXml, String jettyHomePath,
|
||||
boolean doNothingIfJettyHomeExists)
|
||||
throws IOException
|
||||
{
|
||||
File jettyhome = resolveJettyHome(jettyHomePath);
|
||||
if (jettyhome == null)
|
||||
{//we probably have a problem now.
|
||||
throw new IllegalArgumentException(
|
||||
"Unable to resolve jettyhome " + jettyHomePath);
|
||||
}
|
||||
if (!jettyhome.exists())
|
||||
{
|
||||
//does not exist at this point: extract the default one:
|
||||
installDefaultJettyHome(jettyhome);
|
||||
}
|
||||
else if (doNothingIfJettyHomeExists)
|
||||
{
|
||||
return;
|
||||
}
|
||||
//check jetty.xml exists.
|
||||
File jettyXmlFile = new File(jettyhome, "etc/jetty.xml");
|
||||
if (!jettyXmlFile.exists())
|
||||
{//we probably have a problem now.
|
||||
throw new IllegalArgumentException(
|
||||
"The jetty configuration file must exist: '"
|
||||
+ jettyXmlFile.getAbsolutePath());
|
||||
}
|
||||
if (jettyXml != null) {
|
||||
//override the current jettyxml:
|
||||
FileOutputStream out = null;
|
||||
try
|
||||
{
|
||||
out = new FileOutputStream(jettyXmlFile);
|
||||
OutputStreamWriter writer = new OutputStreamWriter(out, "UTF-8");
|
||||
writer.append(jettyXml);
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (out != null) try { out.close(); } catch (IOException ioee) {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually creates the jettyhome folder template in the location set
|
||||
* for the user.
|
||||
* Currently unzips the jettyhome folder located in the
|
||||
* org.eclipse.jetty.osgi.boot bundle.
|
||||
*/
|
||||
public static void installDefaultJettyHome(File jettyhomeFolder) throws IOException
|
||||
{
|
||||
jettyhomeFolder.mkdirs();
|
||||
Bundle bootBundle = getJettyOSGiBootBundle();
|
||||
File bootBundleFile = FileLocator.getBundleFile(bootBundle);
|
||||
|
||||
if (bootBundleFile.getName().endsWith(".jar"))
|
||||
{
|
||||
//unzip it.
|
||||
unzipJettyHomeIntoDirectory(bootBundleFile, jettyhomeFolder);
|
||||
}
|
||||
else
|
||||
{
|
||||
//copy the folders.
|
||||
copyDirectory(new File(bootBundleFile, "jettyhome"), jettyhomeFolder);
|
||||
}
|
||||
|
||||
}
|
||||
/**
|
||||
* @param zipFile
|
||||
* The current jar file for this bundle. contains an archive of
|
||||
* the default jettyhome
|
||||
* @param parentOfMagicJettyHome
|
||||
* The folder inside which jettyhome is created.
|
||||
*/
|
||||
private static void unzipJettyHomeIntoDirectory(File thisbundlejar,
|
||||
File parentOfMagicJettyHome) throws IOException
|
||||
{
|
||||
ZipFile zipFile = null;
|
||||
try
|
||||
{
|
||||
zipFile = new ZipFile(thisbundlejar);
|
||||
Enumeration<? extends ZipEntry> files = zipFile.entries();
|
||||
File f = null;
|
||||
FileOutputStream fos = null;
|
||||
|
||||
while (files.hasMoreElements())
|
||||
{
|
||||
try
|
||||
{
|
||||
ZipEntry entry = files.nextElement();
|
||||
String entryName = entry.getName();
|
||||
if (!entryName.startsWith("jettyhome"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
InputStream eis = zipFile.getInputStream(entry);
|
||||
byte[] buffer = new byte[1024];
|
||||
int bytesRead = 0;
|
||||
f = new File(parentOfMagicJettyHome,entry.getName());
|
||||
|
||||
if (entry.isDirectory())
|
||||
{
|
||||
f.mkdirs();
|
||||
}
|
||||
else
|
||||
{
|
||||
f.getParentFile().mkdirs();
|
||||
f.createNewFile();
|
||||
fos = new FileOutputStream(f);
|
||||
while ((bytesRead = eis.read(buffer)) != -1)
|
||||
{
|
||||
fos.write(buffer,0,bytesRead);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
continue;
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (fos != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
fos.close();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
}
|
||||
fos = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (zipFile != null) try { zipFile.close(); } catch (Throwable t) {}
|
||||
}
|
||||
}
|
||||
|
||||
private static void copyDirectory(File sourceFile, File destFile) throws IOException
|
||||
{
|
||||
if (sourceFile.isDirectory())
|
||||
{
|
||||
if (!destFile.exists())
|
||||
{
|
||||
destFile.mkdir();
|
||||
}
|
||||
String files[] = sourceFile.list();
|
||||
for (int i = 0; i < files.length; i++)
|
||||
{
|
||||
copyDirectory(new File(sourceFile,files[i]),new File(destFile,files[i]));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!sourceFile.exists())
|
||||
{
|
||||
//humf
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
copyFile(sourceFile,destFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void copyFile(File sourceFile, File destFile) throws IOException
|
||||
{
|
||||
if (!destFile.exists())
|
||||
{
|
||||
destFile.createNewFile();
|
||||
}
|
||||
|
||||
FileChannel source = null;
|
||||
FileChannel destination = null;
|
||||
try
|
||||
{
|
||||
source = new FileInputStream(sourceFile).getChannel();
|
||||
destination = new FileOutputStream(destFile).getChannel();
|
||||
destination.transferFrom(source,0,source.size());
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (source != null) { source.close(); }
|
||||
if (destination != null) { destination.close(); }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.pde.launch.ui;
|
||||
|
||||
/**
|
||||
* Object that can read the value of the osgi.config.area property that will be
|
||||
* used when the OSGi app is launched.
|
||||
*/
|
||||
public interface IConfigurationAreaSettingHolder
|
||||
{
|
||||
/**
|
||||
* @return the string entered in the settings tab that defines the
|
||||
* value o osgi.config.area.
|
||||
*/
|
||||
public String getConfigurationAreaLocation();
|
||||
|
||||
}
|
|
@ -0,0 +1,124 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.pde.launch.ui;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.debug.core.ILaunch;
|
||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.jetty.osgi.pde.launch.JettyConfigurationConstants;
|
||||
import org.eclipse.jetty.osgi.pde.launch.JettyOSGiPDEPlugin;
|
||||
import org.eclipse.jetty.osgi.pde.launch.internal.JettyHomeHelper;
|
||||
import org.eclipse.pde.internal.ui.launcher.LaunchConfigurationHelper;
|
||||
import org.eclipse.pde.ui.launcher.EquinoxLaunchConfiguration;
|
||||
import org.eclipse.pde.ui.launcher.IPDELauncherConstants;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class JettyEquinoxLaunchConfiguration extends EquinoxLaunchConfiguration
|
||||
{
|
||||
|
||||
/** The configuration type as declared in the extension point's plugin.xml */
|
||||
public static final String ID = "org.eclipse.jetty.osgi.pde.launch.ui.jettyosgilaunch";
|
||||
|
||||
@Override
|
||||
protected void preLaunchCheck(ILaunchConfiguration configuration, ILaunch launch, IProgressMonitor monitor) throws CoreException
|
||||
{
|
||||
if (!configuration.getAttribute(IPDELauncherConstants.DOCLEAR, false))
|
||||
{
|
||||
super.preLaunchCheck(configuration,launch,monitor);
|
||||
//make sure jettyhome exists and set it up if it does not:
|
||||
File jettyHome = resolveJettyHome(configuration);
|
||||
if (jettyHome != null && !jettyHome.exists())
|
||||
{
|
||||
try
|
||||
{
|
||||
JettyHomeHelper.setupJettyHomeAndJettyXML(null, jettyHome.getAbsolutePath(), true);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new CoreException(new Status(IStatus.ERROR,
|
||||
JettyOSGiPDEPlugin.PLUGIN_ID,"Unable to setup jettyhome", e));
|
||||
}
|
||||
}
|
||||
return;//nothing else to do.
|
||||
}
|
||||
//this will wipe the workspace if it was configured that way.
|
||||
//it means we must setup jettyhome and jettyxml immediately after
|
||||
//if indeed it was wiped:
|
||||
String jettyHomePath = resolveJettyHome(configuration).getAbsolutePath();
|
||||
String jettyXml = JettyHomeHelper.getCurrentJettyXml(jettyHomePath, true);
|
||||
super.preLaunchCheck(configuration,launch,monitor);
|
||||
try
|
||||
{
|
||||
JettyHomeHelper.setupJettyHomeAndJettyXML(jettyXml, jettyHomePath, true);
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
throw new CoreException(new Status(IStatus.ERROR,
|
||||
JettyOSGiPDEPlugin.PLUGIN_ID,"Unable to setup jettyhome", e));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Append -Djetty.home
|
||||
*/
|
||||
@Override
|
||||
public String[] getVMArguments(ILaunchConfiguration configuration) throws CoreException
|
||||
{
|
||||
String[] args = super.getVMArguments(configuration);
|
||||
for (int i = 0; i < args.length ;i++) {
|
||||
String arg = args[i];
|
||||
if (arg.startsWith("-Djetty.home=")) {
|
||||
//overridden by the arg nothing to change (?)
|
||||
return args;
|
||||
}
|
||||
}
|
||||
String jettyHomePath = configuration.getAttribute(JettyConfigurationConstants.ATTR_JETTY_HOME, "");
|
||||
File jettyHome = resolveJettyHome(configuration);
|
||||
if (jettyHome == null || !jettyHome.exists())
|
||||
{
|
||||
//err?
|
||||
System.err.println("could not resolve jettyhome; "
|
||||
+ jettyHomePath + " -> " + jettyHome);
|
||||
return args;
|
||||
}
|
||||
String[] newArgs = new String[args.length+1];
|
||||
System.arraycopy(args, 0, newArgs, 0, args.length);
|
||||
newArgs[args.length] = "-Djetty.home=\""+jettyHome.getAbsolutePath()+"\"";
|
||||
return newArgs;
|
||||
}
|
||||
|
||||
private File resolveJettyHome(ILaunchConfiguration configuration) throws CoreException
|
||||
{
|
||||
String jettyHomePath = configuration.getAttribute(JettyConfigurationConstants.ATTR_JETTY_HOME, "");
|
||||
if (jettyHomePath == null || jettyHomePath.length() == 0)
|
||||
{
|
||||
File configArea = LaunchConfigurationHelper.getConfigurationArea(configuration);
|
||||
return new File(configArea, "jettyhome");
|
||||
}
|
||||
else
|
||||
{
|
||||
return JettyHomeHelper.resolveJettyHome(jettyHomePath);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,89 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
package org.eclipse.jetty.osgi.pde.launch.ui;
|
||||
|
||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
|
||||
import org.eclipse.jface.viewers.ISelection;
|
||||
import org.eclipse.pde.ui.launcher.AbstractLaunchShortcut;
|
||||
import org.eclipse.pde.ui.launcher.IPDELauncherConstants;
|
||||
import org.eclipse.ui.IEditorPart;
|
||||
|
||||
/**
|
||||
* Shortcut to launch Jetty on osgi.
|
||||
*/
|
||||
public class JettyLaunchShortcut extends AbstractLaunchShortcut
|
||||
{
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.debug.ui.ILaunchShortcut#launch(org.eclipse.jface.viewers.ISelection, java.lang.String)
|
||||
*/
|
||||
public void launch(ISelection selection, String mode)
|
||||
{
|
||||
launch(mode);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.debug.ui.ILaunchShortcut#launch(org.eclipse.ui.IEditorPart, java.lang.String)
|
||||
*/
|
||||
public void launch(IEditorPart editor, String mode)
|
||||
{
|
||||
launch(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the launch configuration type name.
|
||||
*
|
||||
* @return the launch configuration type name
|
||||
*/
|
||||
protected String getLaunchConfigurationTypeName()
|
||||
{
|
||||
return JettyEquinoxLaunchConfiguration.ID;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize launch attributes on the new launch configuration. Must be overridden by subclasses.
|
||||
*
|
||||
* @param wc
|
||||
* the launch configuration working copy to be initialize
|
||||
*
|
||||
* @see IPDELauncherConstants
|
||||
*/
|
||||
protected void initializeConfiguration(ILaunchConfigurationWorkingCopy wc)
|
||||
{
|
||||
JettyOSGiLaunchConfigurationInitializer confInitializer = new JettyOSGiLaunchConfigurationInitializer();
|
||||
confInitializer.initialize(wc);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether a given launch configuration is a good match given the
|
||||
* current application or framework being launched. This method must be overridden
|
||||
* by subclasses. Its purpose is to add criteria on what makes a good match or not.
|
||||
*
|
||||
* @param configuration
|
||||
* the launch configuration being evaluated
|
||||
* @return <code>true</code> if the launch configuration is a good match
|
||||
* for the application or framework being launched,
|
||||
* <code>false</code> otherwise.
|
||||
*/
|
||||
protected boolean isGoodMatch(ILaunchConfiguration configuration)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,203 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.pde.launch.ui;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
|
||||
import org.eclipse.osgi.service.resolver.ExportPackageDescription;
|
||||
import org.eclipse.pde.core.plugin.IPluginModelBase;
|
||||
import org.eclipse.pde.core.plugin.PluginRegistry;
|
||||
import org.eclipse.pde.internal.ui.launcher.BundleLauncherHelper;
|
||||
import org.eclipse.pde.internal.ui.launcher.EquinoxInitializer;
|
||||
import org.eclipse.pde.ui.launcher.IPDELauncherConstants;
|
||||
|
||||
/**
|
||||
* In charge of selecting the proper default bundles to load and to make sure
|
||||
* that the jetty.osgi.boot bundle will in fact start.
|
||||
* <p>
|
||||
* The default behavior of OSGi run configuration is to select everything.
|
||||
* This is overwhelming for the web-app developer.
|
||||
* This run configuration initializer will select the minimum set of plugins to run jetty.
|
||||
* </p>
|
||||
*/
|
||||
public class JettyOSGiLaunchConfigurationInitializer extends EquinoxInitializer
|
||||
{
|
||||
|
||||
/** well known bundles that jetty depends on, often optional dependency. */
|
||||
private static final Set<String> BUNDLE_DEPENDENCIES = new HashSet<String>();
|
||||
/** well known bundles required to support headles jdt */
|
||||
private static final Set<String> JDT_HEADLESS_DEPENDENCIES = new HashSet<String>();
|
||||
|
||||
private static final Set<String> ALL_BUNDLE_DEPS = new HashSet<String>();
|
||||
|
||||
|
||||
/** we don't know the bundle but if we find a bundle that exports this package */
|
||||
private static final Set<String> PACKAGES_DEPENDENCIES = new HashSet<String>();
|
||||
|
||||
private static final String JETTY_BUNDLES_PREFIX = "org.eclipse.jetty.";
|
||||
private static final String JETTY_JSP_BUNDLES_PREFIX = "org.mortbay.jetty.jsp-";
|
||||
static {
|
||||
BUNDLE_DEPENDENCIES.add("javax.servlet");
|
||||
BUNDLE_DEPENDENCIES.add("org.eclipse.osgi");
|
||||
BUNDLE_DEPENDENCIES.add("org.eclipse.osgi.services");
|
||||
BUNDLE_DEPENDENCIES.add("org.objectweb.asm");
|
||||
|
||||
PACKAGES_DEPENDENCIES.add("javax.mail");
|
||||
PACKAGES_DEPENDENCIES.add("javax.transaction");
|
||||
PACKAGES_DEPENDENCIES.add("javax.activation");
|
||||
PACKAGES_DEPENDENCIES.add("javax.annotation");
|
||||
|
||||
//now add the headless jdt:
|
||||
//no more ecj: we use jdt.core instead that contains ecj.
|
||||
// BUNDLE_DEPENDENCIES.add("org.eclipse.jdt.core.compiler.batch");
|
||||
JDT_HEADLESS_DEPENDENCIES.add("org.eclipse.core.commands");
|
||||
JDT_HEADLESS_DEPENDENCIES.add("org.eclipse.core.contenttype");
|
||||
JDT_HEADLESS_DEPENDENCIES.add("org.eclipse.core.expressions");
|
||||
JDT_HEADLESS_DEPENDENCIES.add("org.eclipse.core.filessytem");
|
||||
JDT_HEADLESS_DEPENDENCIES.add("org.eclipse.core.jobs");
|
||||
JDT_HEADLESS_DEPENDENCIES.add("org.eclipse.core.resources");
|
||||
JDT_HEADLESS_DEPENDENCIES.add("org.eclipse.core.runtime");
|
||||
JDT_HEADLESS_DEPENDENCIES.add("org.eclipse.core.variables");
|
||||
|
||||
JDT_HEADLESS_DEPENDENCIES.add("org.eclipse.debug.core");
|
||||
JDT_HEADLESS_DEPENDENCIES.add("org.eclipse.equinox.app");
|
||||
JDT_HEADLESS_DEPENDENCIES.add("org.eclipse.equinox.common");
|
||||
JDT_HEADLESS_DEPENDENCIES.add("org.eclipse.equinox.preferences");
|
||||
JDT_HEADLESS_DEPENDENCIES.add("org.eclipse.equinox.registry");
|
||||
JDT_HEADLESS_DEPENDENCIES.add("org.eclipse.equinox.app");
|
||||
|
||||
JDT_HEADLESS_DEPENDENCIES.add("org.eclipse.jdt.core");
|
||||
JDT_HEADLESS_DEPENDENCIES.add("org.eclipse.jdt.debug");
|
||||
JDT_HEADLESS_DEPENDENCIES.add("org.eclipse.jdt.launching");
|
||||
|
||||
JDT_HEADLESS_DEPENDENCIES.add("org.eclipse.text");
|
||||
|
||||
|
||||
ALL_BUNDLE_DEPS.addAll(JDT_HEADLESS_DEPENDENCIES);
|
||||
ALL_BUNDLE_DEPS.addAll(BUNDLE_DEPENDENCIES);
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the default behavior which consists of selecting every bundle.
|
||||
* Here we select only the jetty and jdt-headless bundles from the platform
|
||||
* By default we continue to select all the bundles located in the workspace.
|
||||
*
|
||||
* @param configuration the launch configuration
|
||||
*/
|
||||
@Override
|
||||
protected void initializeBundleState(ILaunchConfigurationWorkingCopy configuration)
|
||||
{
|
||||
List<IPluginModelBase> bundlesInPlatform = new ArrayList<IPluginModelBase>();
|
||||
List<IPluginModelBase> bundlesInWorkspace = new ArrayList<IPluginModelBase>();
|
||||
selectBundles(bundlesInPlatform, bundlesInWorkspace);
|
||||
|
||||
configuration.setAttribute(IPDELauncherConstants.WORKSPACE_BUNDLES, createBundleList(bundlesInWorkspace));
|
||||
configuration.setAttribute(IPDELauncherConstants.TARGET_BUNDLES, createBundleList(bundlesInPlatform));
|
||||
configuration.setAttribute(IPDELauncherConstants.AUTOMATIC_ADD, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The list of bundles to install along with their start level in the format expected by
|
||||
* equinox for the config.ini file. For example:
|
||||
* <code>osgi.bundles=org.eclipse.equinox.common@2:start, org.eclipse.update.configurator@3:start</code>
|
||||
*
|
||||
* (As documented here: http://www.eclipse.org/equinox/documents/quickstart.php)
|
||||
*/
|
||||
private String createBundleList(List<IPluginModelBase> bundlesInPlatform)
|
||||
{
|
||||
StringBuilder bundlesInPlatformString = new StringBuilder();
|
||||
String sep = "";
|
||||
for (IPluginModelBase bundleModel : bundlesInPlatform)
|
||||
{
|
||||
String id = bundleModel.getPluginBase().getId();
|
||||
bundlesInPlatformString.append(sep
|
||||
+ BundleLauncherHelper.writeBundleEntry(bundleModel,
|
||||
getStartLevel(id), getAutoStart(id)));
|
||||
sep = ",";
|
||||
}
|
||||
return bundlesInPlatformString.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is where we are doing something else than the default OSGi launch configuration initializer.
|
||||
* We select only the jetty plugins, their dependencies and the jdt-headless plugins
|
||||
* if we want to launch the ability to debug the java projects too.
|
||||
*
|
||||
* @param bundlesInPlatformCollector Where the bundles that belong to the platform are collected.
|
||||
* @param bundlesInWorkspaceCollector Where the bundles that belong to the workspace are collected.
|
||||
*/
|
||||
private void selectBundles(List<IPluginModelBase> bundlesInPlatformCollector,
|
||||
List<IPluginModelBase> bundlesInWorkspaceCollector)
|
||||
{
|
||||
for (IPluginModelBase pluginModel : PluginRegistry.getActiveModels())
|
||||
{
|
||||
String symbName = pluginModel.getBundleDescription().getSymbolicName();
|
||||
if (pluginModel.getUnderlyingResource() != null)
|
||||
{
|
||||
//all bundles in the workspace are added by default.
|
||||
bundlesInWorkspaceCollector.add(pluginModel);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (symbName.startsWith(JETTY_BUNDLES_PREFIX))
|
||||
{
|
||||
if (symbName.startsWith("org.eclipse.jetty.osgi.pde"))
|
||||
{
|
||||
// don't select the SDK PDE plugins for running jetty!
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else if (symbName.startsWith(JETTY_JSP_BUNDLES_PREFIX))
|
||||
{
|
||||
//let's add them.
|
||||
bundlesInPlatformCollector.add(pluginModel);
|
||||
}
|
||||
else if (!ALL_BUNDLE_DEPS.contains(symbName))
|
||||
{
|
||||
ExportPackageDescription[] exPacks =
|
||||
pluginModel.getBundleDescription().getExportPackages();
|
||||
for (int j = 0; j < exPacks.length; j++)
|
||||
{
|
||||
ExportPackageDescription xp = exPacks[j];
|
||||
if (PACKAGES_DEPENDENCIES.contains(xp.getName()))
|
||||
{
|
||||
bundlesInPlatformCollector.add(pluginModel);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Override the default behavior: we need to make sure that
|
||||
* org.eclipse.jetty.osgi.boot has its autostart level set to 'true'
|
||||
*/
|
||||
@Override
|
||||
protected String getAutoStart(String bundleID)
|
||||
{
|
||||
if (bundleID.equals("org.eclipse.jetty.osgi.boot"))
|
||||
{
|
||||
return Boolean.TRUE.toString();
|
||||
}
|
||||
return super.getAutoStart(bundleID);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,137 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.pde.launch.ui;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.eclipse.debug.ui.AbstractLaunchConfigurationTabGroup;
|
||||
import org.eclipse.debug.ui.ILaunchConfigurationDialog;
|
||||
import org.eclipse.debug.ui.ILaunchConfigurationTab;
|
||||
import org.eclipse.jetty.osgi.pde.launch.ui.tabs.JettyConfigurationLaunchTab;
|
||||
import org.eclipse.pde.ui.launcher.OSGiLauncherTabGroup;
|
||||
import org.eclipse.pde.ui.launcher.OSGiSettingsTab;
|
||||
|
||||
/**
|
||||
* Customizes the OSGi configuration UI.
|
||||
* <p>
|
||||
* Make sure that new default configurations select all the jetty bundles
|
||||
* and deselect the rest of the platform.
|
||||
* </p>
|
||||
* <p>
|
||||
* Insert a new tab for the configuration of jetty home and the ability to edit
|
||||
* jetty.xml
|
||||
* </p>
|
||||
*/
|
||||
public class JettyOSGiLauncherTabGroup extends AbstractLaunchConfigurationTabGroup
|
||||
implements IConfigurationAreaSettingHolder
|
||||
{
|
||||
|
||||
/**
|
||||
* Use the same tabs than the OSGi lauch.
|
||||
* Add one first tab to give access to the jetty configuration.
|
||||
* For now we will simply display the jetty.xml file in a text editor.
|
||||
*/
|
||||
public void createTabs(ILaunchConfigurationDialog dialog, String mode)
|
||||
{
|
||||
ILaunchConfigurationTab[] tabs = createOSGiLaunchTabs(dialog, mode);
|
||||
ILaunchConfigurationTab[] newtabs = new ILaunchConfigurationTab[tabs.length+1];
|
||||
newtabs[0] = new JettyConfigurationLaunchTab(this);
|
||||
System.arraycopy(tabs, 0, newtabs, 1, tabs.length);
|
||||
super.setTabs(newtabs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param dialog
|
||||
* @param mode
|
||||
* @return The tabs created for an OSGi Launch
|
||||
*/
|
||||
private ILaunchConfigurationTab[] createOSGiLaunchTabs(ILaunchConfigurationDialog dialog, String mode)
|
||||
{
|
||||
OSGiLauncherTabGroup osgiTabsFactory = new OSGiLauncherTabGroup();
|
||||
osgiTabsFactory.createTabs(dialog, mode);
|
||||
return osgiTabsFactory.getTabs();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to read the setting "Configuration Area" in the Settings tab
|
||||
* that will become the folder pointed by the system property osgi.config.area
|
||||
* when the app is run.
|
||||
* <p>
|
||||
* Painful to access it.
|
||||
* </p>
|
||||
*/
|
||||
public String getConfigurationAreaLocation()
|
||||
{
|
||||
OSGiSettingsTab settingsTab = null;
|
||||
for (ILaunchConfigurationTab t : getTabs())
|
||||
{
|
||||
if (t instanceof OSGiSettingsTab) {
|
||||
settingsTab = (OSGiSettingsTab)t;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (settingsTab == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
//OSGisettingsTab contains org.eclipse.pde.internal.ui.launcher.ConfigurationAreaBlock
|
||||
//it is a private field called "fConfigurationBlock"
|
||||
//that object contains the private string "fLastEnteredConfigArea"
|
||||
//which is what we want.
|
||||
//we must access it from there as we need the value "live"
|
||||
return getfLastEnteredConfigArea(getfConfigurationBlock(settingsTab));
|
||||
}
|
||||
|
||||
//introspection tricks..
|
||||
private static Field fConfigurationBlock;
|
||||
private static Field fLastEnteredConfigArea;
|
||||
|
||||
private static synchronized Object getfConfigurationBlock(OSGiSettingsTab settingsTab)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (fConfigurationBlock == null)
|
||||
{
|
||||
fConfigurationBlock = OSGiSettingsTab.class.getDeclaredField("fConfigurationBlock");
|
||||
fConfigurationBlock.setAccessible(true);
|
||||
}
|
||||
return fConfigurationBlock.get(settingsTab);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
t.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static synchronized String getfLastEnteredConfigArea(Object configurationBlock)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (fLastEnteredConfigArea == null)
|
||||
{
|
||||
fLastEnteredConfigArea = configurationBlock.getClass().getDeclaredField("fLastEnteredConfigArea");
|
||||
fLastEnteredConfigArea.setAccessible(true);
|
||||
}
|
||||
return (String)fLastEnteredConfigArea.get(configurationBlock);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
t.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.pde.launch.ui.tabs;
|
||||
|
||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
|
||||
import org.eclipse.jetty.osgi.pde.launch.JettyLauncherMessages;
|
||||
import org.eclipse.jetty.osgi.pde.launch.ui.IConfigurationAreaSettingHolder;
|
||||
import org.eclipse.jetty.osgi.pde.launch.ui.JettyOSGiLaunchConfigurationInitializer;
|
||||
import org.eclipse.pde.ui.launcher.AbstractLauncherTab;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
|
||||
/**
|
||||
* Choose a jetty.home.
|
||||
* Edit the jetty.xml file.
|
||||
* <p>
|
||||
* Similar to org.eclipse.jdt.debug.ui.launchConfigurations.JavaArgumentsTab
|
||||
* </p>
|
||||
*/
|
||||
public class JettyConfigurationLaunchTab extends AbstractLauncherTab
|
||||
{
|
||||
protected JettyHomeBlock _jettyHomeBlock;
|
||||
|
||||
public JettyConfigurationLaunchTab(IConfigurationAreaSettingHolder configAreaHolder)
|
||||
{
|
||||
_jettyHomeBlock = new JettyHomeBlock(configAreaHolder);
|
||||
}
|
||||
|
||||
/**
|
||||
* Currently does not do any validation.
|
||||
*/
|
||||
public void validateTab()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @see org.eclipse.debug.ui.ILaunchConfigurationTab#createControl(Composite)
|
||||
*/
|
||||
public void createControl(Composite parent)
|
||||
{
|
||||
Composite comp = new Composite(parent, SWT.NONE);
|
||||
GridLayout layout = new GridLayout(1, true);
|
||||
comp.setLayout(layout);
|
||||
comp.setFont(parent.getFont());
|
||||
|
||||
GridData gd = new GridData(GridData.FILL_BOTH);
|
||||
comp.setLayoutData(gd);
|
||||
setControl(comp);
|
||||
|
||||
_jettyHomeBlock.doCreateControl(comp);
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return JettyLauncherMessages.JettyConfigurationLaunchTab_JettyConfigurationTitle;
|
||||
}
|
||||
|
||||
public void initializeFrom(ILaunchConfiguration configuration)
|
||||
{
|
||||
_jettyHomeBlock.initializeFrom(configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public void performApply(ILaunchConfigurationWorkingCopy configuration)
|
||||
{
|
||||
_jettyHomeBlock.performApply(configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* This is where we initialize the selected bundles by default.
|
||||
*/
|
||||
public void setDefaults(ILaunchConfigurationWorkingCopy configuration)
|
||||
{
|
||||
_jettyHomeBlock.setDefaults(configuration);
|
||||
JettyOSGiLaunchConfigurationInitializer confInitializer =
|
||||
new JettyOSGiLaunchConfigurationInitializer();
|
||||
confInitializer.initialize(configuration);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,189 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.pde.launch.ui.tabs;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.Field;
|
||||
|
||||
import org.eclipse.core.resources.IProject;
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.debug.core.ILaunchConfiguration;
|
||||
import org.eclipse.debug.core.ILaunchConfigurationWorkingCopy;
|
||||
import org.eclipse.debug.ui.WorkingDirectoryBlock;
|
||||
import org.eclipse.jetty.osgi.pde.launch.JettyConfigurationConstants;
|
||||
import org.eclipse.jetty.osgi.pde.launch.internal.JettyHomeHelper;
|
||||
import org.eclipse.jetty.osgi.pde.launch.ui.IConfigurationAreaSettingHolder;
|
||||
import org.eclipse.jface.window.Window;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Group;
|
||||
|
||||
/**
|
||||
* Choose the jettyhome folder. A bit of a stretch to reuse the WorkingDirectoryBlock
|
||||
* but it does save us a lot of UI development.
|
||||
*/
|
||||
public class JettyHomeBlock extends WorkingDirectoryBlock
|
||||
{
|
||||
private Button _editJettyXml;
|
||||
private String _editedJettyXml;
|
||||
private IConfigurationAreaSettingHolder _configAreaHolder;
|
||||
private boolean _initializing = true;
|
||||
|
||||
/**
|
||||
* Constructs a new working directory block.
|
||||
*/
|
||||
public JettyHomeBlock(IConfigurationAreaSettingHolder configAreaHolder)
|
||||
{
|
||||
super(JettyConfigurationConstants.ATTR_JETTY_HOME);
|
||||
_configAreaHolder = configAreaHolder;
|
||||
setDirty(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null We don't use this in the context of a java project.
|
||||
*/
|
||||
protected IProject getProject(ILaunchConfiguration configuration)
|
||||
throws CoreException
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* For now just dumpt the stack trace on the console
|
||||
*/
|
||||
protected void log(CoreException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls create control of the super (which is final)
|
||||
* then go an tweak the created control so that its purpose is for jetty home
|
||||
* instead of a working directory selection.
|
||||
*/
|
||||
protected void doCreateControl(Composite parent)
|
||||
{
|
||||
super.createControl(parent);
|
||||
Group grp = (Group)super.getControl();
|
||||
grp.setText("Jetty &Home:");
|
||||
|
||||
//ok now a bit painful: get the composite inside which the buttons are
|
||||
//add a column to the grid layout and place a button.
|
||||
Button fSysButton = getfFileSystemButton();
|
||||
Composite compButtons = fSysButton.getParent();
|
||||
GridLayout gLayout = (GridLayout) compButtons.getLayout();
|
||||
gLayout.numColumns = gLayout.numColumns+1;
|
||||
_editJettyXml = createPushButton(compButtons, "Edit jetty.xml", null);
|
||||
_editJettyXml.addSelectionListener(new SelectionListener()
|
||||
{
|
||||
public void widgetSelected(SelectionEvent e)
|
||||
{
|
||||
//open a text editor for jetty.xml inside a popup window.
|
||||
//we are using a cheap popup.
|
||||
JettyXmlEditDialog diag = new JettyXmlEditDialog(_editJettyXml.getShell(),
|
||||
getCurrentJettyXml());
|
||||
if (diag.open() == Window.OK) {
|
||||
_editedJettyXml = diag.getNewJettyXml();
|
||||
setDirty(true);
|
||||
}
|
||||
}
|
||||
|
||||
public void widgetDefaultSelected(SelectionEvent e)
|
||||
{
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the default value for this field: not related to the working directory.
|
||||
*/
|
||||
@Override
|
||||
protected void setDefaultWorkingDir()
|
||||
{
|
||||
//the problem is that at this point, the settings tab is not configured yet...
|
||||
//so we delay the configuration of this one:
|
||||
getShell().getDisplay().asyncExec(new Runnable()
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
setDefaultWorkingDirectoryText(
|
||||
_configAreaHolder.getConfigurationAreaLocation()
|
||||
+ File.separator + "jettyhome"); //$NON-NLS-1$
|
||||
_initializing = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* The current content of jettyXml
|
||||
*/
|
||||
protected String getCurrentJettyXml()
|
||||
{
|
||||
return JettyHomeHelper.getCurrentJettyXml(getWorkingDirectoryText(), false);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@Override
|
||||
public void performApply(ILaunchConfigurationWorkingCopy configuration)
|
||||
{
|
||||
super.performApply(configuration);
|
||||
String jettyHome = getWorkingDirectoryText();
|
||||
if (_initializing || jettyHome == null || jettyHome.length() == 0) {
|
||||
//we are only interested in the case where the user really did press on
|
||||
//Apply or "Run". furthermore before the conf area is set
|
||||
//we will not be able to locate the default jettyhome.
|
||||
_initializing = false;
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
JettyHomeHelper.setupJettyHomeAndJettyXML(
|
||||
_editedJettyXml, getWorkingDirectoryText(), false);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
t.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
//introspection trick to be able to insert a button.
|
||||
private static Field fFileSystemButton_field;
|
||||
private Button getfFileSystemButton()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (fFileSystemButton_field == null)
|
||||
{
|
||||
fFileSystemButton_field = WorkingDirectoryBlock.class.getDeclaredField("fFileSystemButton");
|
||||
fFileSystemButton_field.setAccessible(true);
|
||||
}
|
||||
return (Button)fFileSystemButton_field.get(this);
|
||||
}
|
||||
catch (Throwable t)
|
||||
{
|
||||
t.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.pde.launch.ui.tabs;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
import org.eclipse.jetty.osgi.pde.launch.JettyLauncherMessages;
|
||||
import org.eclipse.jface.dialogs.Dialog;
|
||||
import org.eclipse.jface.dialogs.IDialogConstants;
|
||||
import org.eclipse.swt.SWT;
|
||||
import org.eclipse.swt.events.KeyEvent;
|
||||
import org.eclipse.swt.events.KeyListener;
|
||||
import org.eclipse.swt.layout.GridData;
|
||||
import org.eclipse.swt.layout.GridLayout;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
import org.eclipse.swt.widgets.Label;
|
||||
import org.eclipse.swt.widgets.Shell;
|
||||
import org.eclipse.swt.widgets.Text;
|
||||
|
||||
/**
|
||||
* A dialog that displays the content of jetty.xml
|
||||
* <p>
|
||||
* If someone knows how to open a standard editor provided by the IDE
|
||||
* inside a popup from a modal dialog please let us know:
|
||||
* that would be so much better than the simple SWT Text widget!
|
||||
* </p>
|
||||
*/
|
||||
public class JettyXmlEditDialog extends Dialog
|
||||
{
|
||||
|
||||
/** The text area to edit the contents of jetty.xml file */
|
||||
protected Text _textField;
|
||||
private Button _okButton;
|
||||
/** Status label. */
|
||||
private Label _statusLabel;
|
||||
|
||||
private boolean _isDirty = false;;
|
||||
private String _lastValidatedString;
|
||||
private String _jettyHome;
|
||||
|
||||
/**
|
||||
*
|
||||
* @param scope The scope in which the variable is created/edited
|
||||
* @param parentShell The parent shell
|
||||
* @param initValue The initial name of the variable
|
||||
* before the edit. Or null if it is a bran new variable.
|
||||
*/
|
||||
public JettyXmlEditDialog(Shell parentShell, String currentJettyXml)
|
||||
{
|
||||
super(parentShell);
|
||||
setShellStyle(SWT.SHELL_TRIM
|
||||
| getDefaultOrientation() | SWT.RESIZE);
|
||||
setBlockOnOpen(true);
|
||||
_lastValidatedString = currentJettyXml;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the "OK" button
|
||||
*/
|
||||
public Button getGoForItButton() {
|
||||
return _okButton;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The new jetty.xml contents or null if there was no modification.
|
||||
*/
|
||||
protected String getNewJettyXml() {
|
||||
return _isDirty ? _lastValidatedString : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoked to update UI based on user input.
|
||||
*
|
||||
*/
|
||||
protected void validateInput() {
|
||||
String text = _textField.getText();
|
||||
if (text.equals(_lastValidatedString)) {
|
||||
return;
|
||||
}
|
||||
_isDirty = true;
|
||||
_lastValidatedString = text;
|
||||
Button ok = getGoForItButton();
|
||||
ok.setEnabled(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected void configureShell(Shell newShell, String jettyHome) {
|
||||
super.configureShell(newShell);
|
||||
_jettyHome = jettyHome;
|
||||
newShell.setText(JettyLauncherMessages.JettyXmlEditDialog_Edit_jetty_xml_title);
|
||||
newShell.setSize(600, 400);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected Control createDialogArea(Composite parent) {
|
||||
Composite composite = (Composite)super.createDialogArea(parent);
|
||||
GridLayout gridLayout = new GridLayout();
|
||||
gridLayout.numColumns = 1;
|
||||
composite.setLayout(gridLayout);
|
||||
Label label = new Label(composite, SWT.NONE);
|
||||
String msg = JettyLauncherMessages.bind(
|
||||
JettyLauncherMessages.JettyXmlEditDialog_Edit_jetty_xml,
|
||||
_jettyHome + File.separatorChar + "etc" + File.separatorChar + "jetty.xml");
|
||||
label.setText(msg);
|
||||
|
||||
_textField = new Text(composite, SWT.MULTI | SWT.BORDER /*| SWT.WRAP*/ | SWT.H_SCROLL | SWT.V_SCROLL);
|
||||
_textField.addKeyListener(new KeyListener() {
|
||||
public void keyReleased(KeyEvent e) {
|
||||
validateInput();
|
||||
}
|
||||
public void keyPressed(KeyEvent e) {
|
||||
}
|
||||
});
|
||||
if (_lastValidatedString != null) {
|
||||
_textField.setText(_lastValidatedString);
|
||||
}
|
||||
GridData gridData = new GridData();
|
||||
gridData.horizontalAlignment = GridData.FILL;
|
||||
gridData.verticalAlignment = GridData.FILL;
|
||||
gridData.grabExcessHorizontalSpace = true;
|
||||
gridData.grabExcessVerticalSpace = true;
|
||||
_textField.setLayoutData(gridData);
|
||||
// _textField.setSize(500, 500);
|
||||
// status label
|
||||
_statusLabel = new Label(composite, SWT.NONE);
|
||||
_statusLabel.setText(" "); //$NON-NLS-1$
|
||||
gridData = new GridData();
|
||||
gridData.horizontalAlignment = GridData.FILL;
|
||||
gridData.grabExcessHorizontalSpace = true;
|
||||
_statusLabel.setLayoutData(gridData);
|
||||
|
||||
|
||||
return composite;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
protected void createButtonsForButtonBar(Composite parent) {
|
||||
createButton(parent, IDialogConstants.CANCEL_ID, JettyLauncherMessages.JettyXmlEditDialog_Cancel, false);
|
||||
_okButton = createButton(parent, IDialogConstants.OK_ID,
|
||||
JettyLauncherMessages.JettyXmlEditDialog_OK, true);
|
||||
_okButton.setEnabled(false);
|
||||
|
||||
//call validate input before the user has to type something.
|
||||
//it will decide on the state of the create button.
|
||||
validateInput();
|
||||
}
|
||||
|
||||
// @Override
|
||||
// public boolean close() {
|
||||
// _text = getText();
|
||||
// return super.close();
|
||||
// }
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
Manifest-Version: 1.0
|
||||
Bundle-ManifestVersion: 2
|
||||
Bundle-Name: Projecttemplate
|
||||
Bundle-SymbolicName: org.eclipse.jetty.osgi.pde.templates;singleton:=true
|
||||
Bundle-Version: 7.0.0.qualifier
|
||||
Bundle-Activator: org.eclipse.jetty.osgi.pde.templates.JettyProjectTemplateActivator
|
||||
Bundle-Vendor: Intalio Inc
|
||||
Require-Bundle: org.eclipse.ui,
|
||||
org.eclipse.core.runtime,
|
||||
org.eclipse.pde.ui;bundle-version="3.5.0",
|
||||
org.eclipse.pde.ui.templates;bundle-version="3.4.100",
|
||||
org.eclipse.core.resources;bundle-version="3.5.0"
|
||||
Bundle-RequiredExecutionEnvironment: J2SE-1.5
|
||||
Bundle-ActivationPolicy: lazy
|
|
@ -0,0 +1,7 @@
|
|||
source.. = src/main/java/
|
||||
output.. = target/classes/
|
||||
bin.includes = META-INF/,\
|
||||
.,\
|
||||
plugin.xml,\
|
||||
templates_3.4/,\
|
||||
icons/
|
Binary file not shown.
After Width: | Height: | Size: 815 B |
|
@ -0,0 +1,53 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<?eclipse version="3.4"?>
|
||||
<!--
|
||||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
//
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
-->
|
||||
<plugin>
|
||||
<extension
|
||||
point="org.eclipse.pde.ui.pluginContent">
|
||||
<wizard
|
||||
class="org.eclipse.jetty.osgi.pde.templates.HelloRFC66WebappNewWizard"
|
||||
icon="$nl$/icons/jetty.png"
|
||||
id="org.eclipse.jetty.osgi.pde.templates.HelloRFC66WebappNewWizard"
|
||||
java="true"
|
||||
name="Hello RFC-66 Web-application"
|
||||
pureOSGi="true"
|
||||
rcp="false"
|
||||
requiresActivator="false"
|
||||
ui-content="false">
|
||||
<description>
|
||||
Simple web-application embedded inside an OSGi bundle.
|
||||
A single servlet declared in /WEB-INF/web.xml
|
||||
</description>
|
||||
</wizard>
|
||||
<wizard
|
||||
class="org.eclipse.jetty.osgi.pde.templates.TwoWebappsOneServletHandlerNewWizard"
|
||||
icon="$nl$/icons/jetty.png"
|
||||
id="org.eclipse.jetty.osgi.pde.templates.TwoWebappsOneServletHandlerNewWizard"
|
||||
java="true"
|
||||
name="Multiple Jetty webapps embedded in an OSGi bundle"
|
||||
pureOSGi="true"
|
||||
rcp="false"
|
||||
requiresActivator="false"
|
||||
ui-content="false">
|
||||
<description>
|
||||
Two webapps and one servlet handler configured via 3 jetty context files.
|
||||
</description>
|
||||
</wizard>
|
||||
</extension>
|
||||
|
||||
</plugin>
|
|
@ -0,0 +1,109 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.pde.templates;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
import org.eclipse.core.runtime.Platform;
|
||||
import org.eclipse.jface.wizard.Wizard;
|
||||
import org.eclipse.pde.core.plugin.IPluginReference;
|
||||
import org.eclipse.pde.ui.templates.OptionTemplateSection;
|
||||
|
||||
/**
|
||||
* Simple abstract implementation of OptionTemplateSection suitable for templates defined
|
||||
* in this bundle.
|
||||
*/
|
||||
public abstract class AbstractJettyPDETemplateSection extends OptionTemplateSection
|
||||
{
|
||||
|
||||
public AbstractJettyPDETemplateSection()
|
||||
{
|
||||
super.setPageCount(getNumberOfPagesToCreateCount());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The location of the installation of this current bundle.
|
||||
*/
|
||||
protected URL getInstallURL() {
|
||||
return JettyProjectTemplateActivator.getDefault().getBundle().getEntry("/");
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The properties files for this bundle.
|
||||
*/
|
||||
protected ResourceBundle getPluginResourceBundle() {
|
||||
return Platform.getResourceBundle(
|
||||
JettyProjectTemplateActivator.getDefault().getBundle());
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls internalAddPages.
|
||||
* Takes care of calling markPagesAdded as required by the super implementation.
|
||||
*/
|
||||
public final void addPages(Wizard wizard)
|
||||
{
|
||||
super.markPagesAdded();
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually add the pages to the wizard here.
|
||||
* @param wizard
|
||||
*/
|
||||
protected abstract void internalAddPages(Wizard wizard);
|
||||
|
||||
/**
|
||||
* @return the number of pages that will be added here. By default 1.
|
||||
*/
|
||||
protected int getNumberOfPagesToCreateCount()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null By default we don't declare extension points.
|
||||
* This is for OSGi bundles not eclipse plugins.
|
||||
*/
|
||||
public String getUsedExtensionPoint()
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return true: inherit from parent wizard
|
||||
*/
|
||||
public boolean isDependentOnParentWizard()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 1 by default we don't not do anything fancy with the progress monitors.
|
||||
*/
|
||||
public int getNumberOfWorkUnits()
|
||||
{
|
||||
return super.getNumberOfWorkUnits() + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false by default we don't generate multiple projects at once right now.
|
||||
*/
|
||||
public IPluginReference[] getDependencies(String schemaVersion)
|
||||
{
|
||||
return new IPluginReference[0];
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.pde.templates;
|
||||
|
||||
import org.eclipse.pde.ui.IFieldData;
|
||||
import org.eclipse.pde.ui.templates.NewPluginTemplateWizard;
|
||||
|
||||
/**
|
||||
* Base template wizard: set the Import-Packages header in the generated MANIFEST.MF
|
||||
* to import the javax.servlet and javax.servlet.http
|
||||
*/
|
||||
public abstract class AbstractOSGiWebappNewWizard extends NewPluginTemplateWizard
|
||||
{
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.pde.ui.templates.AbstractNewPluginTemplateWizard#init(org.eclipse.pde.ui.IFieldData)
|
||||
*/
|
||||
public void init(IFieldData data)
|
||||
{
|
||||
super.init(data);
|
||||
setWindowTitle("Webapp(s) embedded in an OSGi bundle");
|
||||
}
|
||||
|
||||
/**
|
||||
* In these default examples, the only dependency are the servlet's packages.
|
||||
*/
|
||||
public String[] getImportPackages()
|
||||
{
|
||||
return new String[] {"javax.servlet;version=\"2.5.0\"", //$NON-NLS-1$
|
||||
"javax.servlet.http;version=\"2.5.0\""}; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.pde.templates;
|
||||
|
||||
import org.eclipse.pde.ui.IFieldData;
|
||||
import org.eclipse.pde.ui.templates.ITemplateSection;
|
||||
import org.eclipse.pde.ui.templates.NewPluginTemplateWizard;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class HelloRFC66WebappNewWizard extends AbstractOSGiWebappNewWizard
|
||||
{
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.pde.ui.templates.AbstractNewPluginTemplateWizard#init(org.eclipse.pde.ui.IFieldData)
|
||||
*/
|
||||
public void init(IFieldData data) {
|
||||
super.init(data);
|
||||
setWindowTitle("Basic webapp embedded in an OSGi bundle");
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.pde.ui.templates.NewPluginTemplateWizard#createTemplateSections()
|
||||
*/
|
||||
public ITemplateSection[] createTemplateSections() {
|
||||
return new ITemplateSection[] {new HelloRFC66WebappTemplate()};
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.pde.templates;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.jface.wizard.Wizard;
|
||||
import org.eclipse.jface.wizard.WizardPage;
|
||||
|
||||
/**
|
||||
* Template to generate a simple hello wold webapp embedded in an OSGi bundle.
|
||||
*/
|
||||
public class HelloRFC66WebappTemplate extends AbstractJettyPDETemplateSection
|
||||
{
|
||||
|
||||
public static final String GREETINGS = "greetings";
|
||||
public static final String CONTEXT_PATH = "contextPath"; //$NON-NLS-1$
|
||||
|
||||
public HelloRFC66WebappTemplate()
|
||||
{
|
||||
addOption(GREETINGS,"Greetings message", "Howdy!",0);
|
||||
addOption(CONTEXT_PATH,"Web-ContextPath","/hello",0); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
protected void internalAddPages(Wizard wizard)
|
||||
{
|
||||
WizardPage page = createPage(0, null);//no help for now
|
||||
page.setTitle("Hello World RFC66 Webapp");
|
||||
page.setDescription("Creates a webapp embedded in an OSGi bundle");
|
||||
wizard.addPage(page);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return 'helloRFC66Webapp' used to locate the base folder that
|
||||
* contains the template files.
|
||||
*/
|
||||
public String getSectionId()
|
||||
{
|
||||
return "helloRFC66Webapp"; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add the Web-ContextPath to the MANIFEST.MF as required by RFC66
|
||||
*/
|
||||
protected void updateModel(IProgressMonitor monitor)
|
||||
{
|
||||
setManifestHeader("Web-ContextPath", String.valueOf(getOptions(0)[1].getValue())); //$NON-NLS-1$ //$NON-NLS-2$]
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.pde.ui.templates.ITemplateSection#getFoldersToInclude()
|
||||
*/
|
||||
public String[] getNewFiles() {
|
||||
return new String[] {"WEB-INF/web.xml"};
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.pde.templates;
|
||||
|
||||
import org.eclipse.ui.plugin.AbstractUIPlugin;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
/**
|
||||
* The activator class controls the plug-in life cycle
|
||||
*/
|
||||
public class JettyProjectTemplateActivator extends AbstractUIPlugin {
|
||||
|
||||
// The plug-in ID
|
||||
public static final String PLUGIN_ID = "org.eclipse.jetty.osgi.pde.projecttemplate";
|
||||
|
||||
// The shared instance
|
||||
private static JettyProjectTemplateActivator plugin;
|
||||
|
||||
/**
|
||||
* The constructor
|
||||
*/
|
||||
public JettyProjectTemplateActivator()
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception
|
||||
{
|
||||
super.start(context);
|
||||
plugin = this;
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception
|
||||
{
|
||||
plugin = null;
|
||||
super.stop(context);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the shared instance
|
||||
*
|
||||
* @return the shared instance
|
||||
*/
|
||||
public static JettyProjectTemplateActivator getDefault()
|
||||
{
|
||||
return plugin;
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.pde.templates;
|
||||
|
||||
import org.eclipse.pde.ui.IFieldData;
|
||||
import org.eclipse.pde.ui.templates.ITemplateSection;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public class TwoWebappsOneServletHandlerNewWizard extends AbstractOSGiWebappNewWizard
|
||||
{
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.pde.ui.templates.AbstractNewPluginTemplateWizard#init(org.eclipse.pde.ui.IFieldData)
|
||||
*/
|
||||
public void init(IFieldData data) {
|
||||
super.init(data);
|
||||
setWindowTitle("Two Webapps and one servlet embedded in an OSGi bundle");
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.pde.ui.templates.NewPluginTemplateWizard#createTemplateSections()
|
||||
*/
|
||||
public ITemplateSection[] createTemplateSections() {
|
||||
return new ITemplateSection[] {new TwoWebappsOneServletHandlerTemplate()};
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
// ========================================================================
|
||||
// Copyright (c) 2009 Intalio, Inc.
|
||||
// ------------------------------------------------------------------------
|
||||
// All rights reserved. This program and the accompanying materials
|
||||
// are made available under the terms of the Eclipse Public License v1.0
|
||||
// and Apache License v2.0 which accompanies this distribution.
|
||||
// The Eclipse Public License is available at
|
||||
// http://www.eclipse.org/legal/epl-v10.html
|
||||
// The Apache License v2.0 is available at
|
||||
// http://www.opensource.org/licenses/apache2.0.php
|
||||
// You may elect to redistribute this code under either of these licenses.
|
||||
// Contributors:
|
||||
// Hugues Malphettes - initial API and implementation
|
||||
// ========================================================================
|
||||
package org.eclipse.jetty.osgi.pde.templates;
|
||||
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.jface.wizard.Wizard;
|
||||
import org.eclipse.jface.wizard.WizardPage;
|
||||
|
||||
/**
|
||||
* Template that generates jetty webapps.
|
||||
*/
|
||||
public class TwoWebappsOneServletHandlerTemplate extends AbstractJettyPDETemplateSection
|
||||
{
|
||||
|
||||
public static final String GREETINGS = "greetings"; //$NON-NLS-1$
|
||||
public static final String CONTEXT_PATH_APP_1 = "contextPathApp1"; //$NON-NLS-1$
|
||||
public static final String CONTEXT_PATH_APP_2 = "contextPathApp2"; //$NON-NLS-1$
|
||||
|
||||
public TwoWebappsOneServletHandlerTemplate()
|
||||
{
|
||||
addOption(GREETINGS,"Greetings message", "Howdy!",0);
|
||||
addOption(CONTEXT_PATH_APP_1,"Webapp 1 Context Path","/app1",0); //$NON-NLS-1$
|
||||
addOption(CONTEXT_PATH_APP_2,"Webapp 2 Context Path","/app2",0); //$NON-NLS-1$
|
||||
}
|
||||
|
||||
public void internalAddPages(Wizard wizard)
|
||||
{
|
||||
WizardPage page = createPage(0, null);
|
||||
page.setTitle("Two webapps and one servlet in an OSGi bundle");
|
||||
page.setDescription("Creates multiple jetty webapps embedded in an OSGi bundle");
|
||||
wizard.addPage(page);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
*
|
||||
* @see org.eclipse.pde.ui.templates.OptionTemplateSection#getSectionId()
|
||||
*/
|
||||
public String getSectionId()
|
||||
{
|
||||
return "twoWebappsOneServletHandler"; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add the Jetty-ContextFilePath to the MANIFEST.MF as required for
|
||||
* jetty-osgi to be able to identify the embedded webapps.
|
||||
*/
|
||||
protected void updateModel(IProgressMonitor monitor)
|
||||
{
|
||||
setManifestHeader("Jetty-ContextFilePath",
|
||||
"jettycontexts/myservlet.xml, " + //$NON-NLS-1$ //$NON-NLS-2$
|
||||
"jettycontexts/app1.xml, jettycontexts/app2.xml"); //$NON-NLS-1$ //$NON-NLS-2$
|
||||
}
|
||||
|
||||
/* (non-Javadoc)
|
||||
* @see org.eclipse.pde.ui.templates.ITemplateSection#getFoldersToInclude()
|
||||
*/
|
||||
public String[] getNewFiles() {
|
||||
return new String[] {"war1/WEB-INF/web.xml",
|
||||
"war2/WEB-INF/web.xml", //$NON-NLS-1$ //$NON-NLS-2$
|
||||
"jettycontexts/app1.xml", "jettycontexts/app2.xml", //$NON-NLS-1$ //$NON-NLS-2$
|
||||
"jettycontexts/myservlet.xml"}; //$NON-NLS-1$
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<web-app
|
||||
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
|
||||
version="2.5">
|
||||
|
||||
<display-name>Hello Webapp</display-name>
|
||||
<servlet>
|
||||
<servlet-name>theservlet</servlet-name>
|
||||
<servlet-class>$packageName$.Servlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>theservlet</servlet-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
</web-app>
|
|
@ -0,0 +1,24 @@
|
|||
package $packageName$;
|
||||
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
public class $activator$ implements BundleActivator {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception {
|
||||
System.out.println("$startMessage$");
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
System.out.println("$stopMessage$");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
package $packageName$;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class Servlet extends HttpServlet {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public void init(ServletConfig config) throws ServletException {
|
||||
super.init(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void service(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
resp.getWriter().write("$greetings$");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
package $packageName$;
|
||||
|
||||
import org.osgi.framework.BundleActivator;
|
||||
import org.osgi.framework.BundleContext;
|
||||
|
||||
public class $activator$ implements BundleActivator {
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void start(BundleContext context) throws Exception {
|
||||
System.out.println("$startMessage$");
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
|
||||
*/
|
||||
public void stop(BundleContext context) throws Exception {
|
||||
System.out.println("$stopMessage$");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package $packageName$;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.servlet.ServletConfig;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
|
||||
public class Servlet extends HttpServlet {
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Override
|
||||
public void init(ServletConfig config) throws ServletException {
|
||||
super.init(config);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void service(HttpServletRequest req, HttpServletResponse resp)
|
||||
throws ServletException, IOException {
|
||||
resp.getWriter().write(req.getContextPath() + ": $greetings$");
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
<Set name="contextPath">$contextPathApp1$</Set>
|
||||
<Set name="war"><Property name="this.bundle.install"/>/war2</Set>
|
||||
</Configure>
|
|
@ -0,0 +1,6 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
<Configure class="org.eclipse.jetty.webapp.WebAppContext">
|
||||
<Set name="contextPath">$contextPathApp2$</Set>
|
||||
<Set name="war"><Property name="this.bundle.install"/>/war2</Set>
|
||||
</Configure>
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<!DOCTYPE Configure PUBLIC "-//Jetty//Configure//EN" "http://www.eclipse.org/jetty/configure.dtd">
|
||||
<Configure class="org.eclipse.jetty.servlet.ServletContextHandler">
|
||||
<Call name="addServlet">
|
||||
<Arg>$packageName$.Servlet</Arg>
|
||||
<Arg>/theservlet</Arg>
|
||||
</Call>
|
||||
</Configure>
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<web-app
|
||||
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
|
||||
version="2.5">
|
||||
|
||||
<display-name>Hello Webapp</display-name>
|
||||
<servlet>
|
||||
<servlet-name>theservlet</servlet-name>
|
||||
<servlet-class>$packageName$.Servlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>theservlet</servlet-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
</web-app>
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||
<web-app
|
||||
xmlns="http://java.sun.com/xml/ns/javaee"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
|
||||
version="2.5">
|
||||
|
||||
<display-name>Hello Webapp</display-name>
|
||||
<servlet>
|
||||
<servlet-name>theservlet</servlet-name>
|
||||
<servlet-class>$packageName$.Servlet</servlet-class>
|
||||
<load-on-startup>1</load-on-startup>
|
||||
</servlet>
|
||||
<servlet-mapping>
|
||||
<servlet-name>theservlet</servlet-name>
|
||||
<url-pattern>/*</url-pattern>
|
||||
</servlet-mapping>
|
||||
|
||||
</web-app>
|
|
@ -30,6 +30,7 @@ jetty-7.0.1-SNAPSHOT
|
|||
+ Promoted Jetty WebApp Verifier from Sandbox
|
||||
+ Refactored continuation test harnessess
|
||||
+ Fixed client abort asocciation
|
||||
+ CQ-3581 jetty OSGi contribution
|
||||
|
||||
jetty-7.0.0.v20091005 5 October 2009
|
||||
291340 Race condition in onException() notifications
|
||||
|
|
Loading…
Reference in New Issue