Added patch equinox servlet bridge:

1) Filter support from http://angelozerr.wordpress.com/2010/09/08/osgi-equinox-in-a-servlet-container-step4/
2) Modify to work with OSGi web container ( geminiweb ) instead of normal servlet container
This commit is contained in:
Heng Sin Low 2011-01-11 01:00:26 +08:00
parent 30853d1196
commit cc5708c8d0
47 changed files with 2987 additions and 0 deletions

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.adempiere.eclipse.equinox.http.servlet</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,8 @@
#Fri Dec 24 14:42:06 MYT 2010
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6

View File

@ -0,0 +1,4 @@
#Fri Dec 24 14:42:06 MYT 2010
eclipse.preferences.version=1
pluginProject.extensions=false
resolve.requirebundle=false

View File

@ -0,0 +1,20 @@
Manifest-Version: 1.0
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: CDC-1.0/Foundation-1.0,J2SE-1.3
Bundle-SymbolicName: org.adempiere.eclipse.equinox.http.servlet
Eclipse-LazyStart: true
Eclipse-SourceReferences: scm:cvs:pserver:dev.eclipse.org:/cvsroot/rt:
org.eclipse.equinox/compendium/bundles/org.eclipse.equinox.http.servl
et;tag=v20100503
Bundle-Activator: org.eclipse.equinox.http.servlet.internal.Activator
Export-Package: org.eclipse.equinox.http.servlet;version="1.1.0"
Bundle-Version: 1.1.0.v20100503
Bundle-ActivationPolicy: lazy
Bundle-Vendor: %providerName
Bundle-Name: %bundleName
Comment-Header: Both Eclipse-LazyStart and Bundle-ActivationPolicy are
specified for compatibility with 3.2
Import-Package: javax.servlet;version="2.3",javax.servlet.http;version
="2.3",org.osgi.framework;version="1.3.0",org.osgi.service.http;versi
on="1.2.0"
Bundle-ManifestVersion: 2

View File

@ -0,0 +1,28 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<title>About</title>
</head>
<body lang="EN-US">
<h2>About This Content</h2>
<p>January 30, 2007</p>
<h3>License</h3>
<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
indicated below, the Content is provided to you under the terms and conditions of the
Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
apply to your use of any object code in the Content. Check the Redistributor's license that was
provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
indicated below, the terms and conditions of the EPL still apply to any source code in the Content
and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
</body>
</html>

View File

@ -0,0 +1,4 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.

View File

@ -0,0 +1,4 @@
##Source Bundle Localization
#Thu Jun 24 08:34:29 EDT 2010
bundleName=Http Services Servlet Source
providerName=Eclipse.org - Equinox

View File

@ -0,0 +1,55 @@
package org.eclipse.equinox.http.servlet;
import java.util.Dictionary;
import javax.servlet.Filter;
import javax.servlet.ServletException;
import org.osgi.service.http.*;
/**
* @since 1.1
*/
public interface ExtendedHttpService extends HttpService {
/**
* @param alias name in the URI namespace at which the filter is registered
* @param filter the filter object to register
* @param initparams initialization arguments for the filter or
* <code>null</code> if there are none. This argument is used by the
* filter's <code>FilterConfig</code> object.
* @param context the <code>HttpContext</code> object for the registered
* filter, or <code>null</code> if a default <code>HttpContext</code> is
* to be created and used.
* @throws javax.servlet.ServletException if the filter's <code>init</code>
* method throws an exception, or the given filter object has
* already been registered at a different alias.
* @throws java.lang.IllegalArgumentException if any of the arguments are
* invalid
*/
public void registerFilter(String alias, Filter filter, Dictionary initparams, HttpContext context) throws ServletException, NamespaceException;
/**
* Unregisters a previous filter registration done by the
* <code>registerFilter</code> method.
*
* <p>
* After this call, the registered filter will no
* longer be available. The Http Service must call the <code>destroy</code>
* method of the filter before returning.
* <p>
* If the bundle which performed the registration is stopped or otherwise
* "unget"s the Http Service without calling {@link #unregisterFilter} then the Http
* Service must automatically unregister the filter registration. However, the
* <code>destroy</code> method of the filter will not be called in this case since
* the bundle may be stopped.
* {@link #unregisterFilter} must be explicitly called to cause the
* <code>destroy</code> method of the filter to be called. This can be done
* in the <code>BundleActivator.stop</code> method of the
* bundle registering the filter.
*
* @param filter the filter object to unregister
* @throws java.lang.IllegalArgumentException if there is no registration
* for the filter or the calling bundle was not the bundle which
* registered the filter.
*/
public void unregisterFilter(Filter filter);
}

View File

@ -0,0 +1,25 @@
/*******************************************************************************
* Copyright (c) 2005, 2008 Cognos Incorporated, IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
*******************************************************************************/
package org.eclipse.equinox.http.servlet;
import org.eclipse.equinox.http.servlet.internal.ProxyServlet;
/**
* The HttpServiceServlet is the "public" side of a Servlet that when registered (and init() called) in a servlet container
* will in-turn register and provide an OSGi Http Service implementation.
* This class is not meant for extending or even using directly and is purely meant for registering
* in a servlet container.
* @noextend This class is not intended to be subclassed by clients.
*/
public class HttpServiceServlet extends ProxyServlet {
private static final long serialVersionUID = -3647550992964861187L;
}

View File

@ -0,0 +1,88 @@
/*******************************************************************************
* Copyright (c) 2005, 2007 Cognos Incorporated, IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
*******************************************************************************/
package org.eclipse.equinox.http.servlet.internal;
import java.util.*;
import javax.servlet.ServletConfig;
import org.eclipse.equinox.http.servlet.ExtendedHttpService;
import org.osgi.framework.*;
import org.osgi.service.http.HttpService;
public class Activator implements BundleActivator {
private static final String DEFAULT_SERVICE_DESCRIPTION = "Equinox Servlet Bridge"; //$NON-NLS-1$
private static final String DEFAULT_SERVICE_VENDOR = "Eclipse.org"; //$NON-NLS-1$
private static final String[] HTTP_SERVICES_CLASSES = new String[] {HttpService.class.getName(), ExtendedHttpService.class.getName()};
private static BundleContext context;
private static Map serviceRegistrations = new HashMap();
public void start(BundleContext bundleContext) throws Exception {
startHttpServiceProxy(bundleContext);
}
public void stop(BundleContext bundleContext) throws Exception {
stopHttpServiceProxy(bundleContext);
}
private static synchronized void startHttpServiceProxy(BundleContext bundleContext) {
context = bundleContext;
Object[] proxyServlets = serviceRegistrations.keySet().toArray();
for (int i = 0; i < proxyServlets.length; ++i) {
ServiceRegistration registration = registerHttpService((ProxyServlet) proxyServlets[i]);
serviceRegistrations.put(proxyServlets[i], registration);
}
}
private static synchronized void stopHttpServiceProxy(BundleContext bundleContext) {
Object[] proxyServlets = serviceRegistrations.keySet().toArray();
for (int i = 0; i < proxyServlets.length; ++i) {
ServiceRegistration registration = (ServiceRegistration) serviceRegistrations.put(proxyServlets[i], null);
registration.unregister();
}
context = null;
}
static synchronized void addProxyServlet(ProxyServlet proxyServlet) {
ServiceRegistration registration = null;
if (context != null)
registration = registerHttpService(proxyServlet);
serviceRegistrations.put(proxyServlet, registration);
}
private static ServiceRegistration registerHttpService(ProxyServlet proxyServlet) {
HttpServiceFactory factory = new HttpServiceFactory(proxyServlet);
Dictionary serviceProperties = new Hashtable(2);
ServletConfig config = proxyServlet.getServletConfig();
Enumeration initparameterNames = config.getInitParameterNames();
while (initparameterNames.hasMoreElements()) {
String name = (String) initparameterNames.nextElement();
serviceProperties.put(name, config.getInitParameter(name));
}
if (serviceProperties.get(Constants.SERVICE_VENDOR) == null)
serviceProperties.put(Constants.SERVICE_VENDOR, DEFAULT_SERVICE_VENDOR);
if (serviceProperties.get(Constants.SERVICE_DESCRIPTION) == null)
serviceProperties.put(Constants.SERVICE_DESCRIPTION, DEFAULT_SERVICE_DESCRIPTION);
return context.registerService(HTTP_SERVICES_CLASSES, factory, serviceProperties);
}
static synchronized void removeProxyServlet(ProxyServlet proxyServlet) {
ServiceRegistration registration = (ServiceRegistration) serviceRegistrations.remove(proxyServlet);
if (registration != null)
registration.unregister();
}
}

View File

@ -0,0 +1,42 @@
/*******************************************************************************
* Copyright (c) 2005, 2007 Cognos Incorporated, IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
*******************************************************************************/
package org.eclipse.equinox.http.servlet.internal;
import java.io.IOException;
import java.net.URL;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.osgi.framework.Bundle;
import org.osgi.service.http.HttpContext;
public class DefaultHttpContext implements HttpContext {
private Bundle bundle;
public DefaultHttpContext(Bundle bundle) {
this.bundle = bundle;
}
public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) throws IOException {
// default behaviour assumes the container has already performed authentication
return true;
}
public URL getResource(String name) {
return bundle.getResource(name);
}
public String getMimeType(String name) {
return null;
}
}

View File

@ -0,0 +1,30 @@
package org.eclipse.equinox.http.servlet.internal;
import java.io.IOException;
import java.util.List;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class FilterChainImpl implements FilterChain {
private List matchingFilterRegistrations;
private ServletRegistration registration;
private int filterIndex = 0;
private int filterCount;
public FilterChainImpl(List matchingFilterRegistrations, ServletRegistration registration) {
this.matchingFilterRegistrations = matchingFilterRegistrations;
this.registration = registration;
this.filterCount = matchingFilterRegistrations.size();
}
public void doFilter(ServletRequest request, ServletResponse response) throws IOException, ServletException {
if (filterIndex < filterCount) {
FilterRegistration filterRegistration = (FilterRegistration) matchingFilterRegistrations.get(filterIndex++);
filterRegistration.doFilter((HttpServletRequest) request, (HttpServletResponse) response, this);
return;
}
registration.service((HttpServletRequest) request, (HttpServletResponse) response);
}
}

View File

@ -0,0 +1,52 @@
/*******************************************************************************
* Copyright (c) 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.http.servlet.internal;
import java.util.*;
import javax.servlet.*;
public class FilterConfigImpl implements FilterConfig {
private static final Dictionary EMPTY_PARAMS = new Hashtable(0);
private static final String FILTER_NAME = "filter-name"; //$NON-NLS-1$
private Filter filter;
private Dictionary initparams;
private ServletContext servletContext;
public FilterConfigImpl(Filter filter, Dictionary initparams, ServletContext servletContext) {
this.filter = filter;
this.initparams = (initparams != null) ? initparams : EMPTY_PARAMS;
this.servletContext = servletContext;
}
/*
* @see javax.servlet.FilterConfig#getFilterName()
*
* The OSGi Http Service does not specify a way to set a filter name at the API level. This
* implementation will try to use the value of the "filter-name" initial parameter if available.
*/
public String getFilterName() {
String filterName = (String) initparams.get(FILTER_NAME);
return (filterName != null) ? filterName : filter.getClass().getName();
}
public ServletContext getServletContext() {
return servletContext;
}
public String getInitParameter(String name) {
return (String) initparams.get(name);
}
public Enumeration getInitParameterNames() {
return initparams.keys();
}
}

View File

@ -0,0 +1,112 @@
package org.eclipse.equinox.http.servlet.internal;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.osgi.service.http.HttpContext;
//This class wraps the filter object registered in the HttpService.registerFilter call, to manage the context classloader when handleRequests are being asked.
public class FilterRegistration extends Registration implements Comparable {
private static long nextSequenceNumber = 1L;
private final Filter filter; //The actual filter object registered against the http service. All filter requests will eventually be delegated to it.
private final HttpContext httpContext; //The context used during the registration of the filter
private final ClassLoader registeredContextClassLoader;
private final String prefix;
private final String suffix;
private final int priority;
private final long sequenceNumber;
public FilterRegistration(Filter filter, HttpContext context, String alias, int priority) {
this.filter = filter;
this.httpContext = context;
registeredContextClassLoader = Thread.currentThread().getContextClassLoader();
int lastSlash = alias.lastIndexOf('/');
String lastSegment = alias.substring(alias.lastIndexOf('/') + 1);
if (lastSegment.startsWith("*.")) { //$NON-NLS-1$
prefix = alias.substring(0, lastSlash);
suffix = lastSegment.substring(1);
} else {
prefix = alias.equals("/") ? "" : alias; //$NON-NLS-1$//$NON-NLS-2$
suffix = null;
}
this.priority = priority;
synchronized (FilterRegistration.class) {
this.sequenceNumber = nextSequenceNumber++;
}
}
public void destroy() {
ClassLoader original = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(registeredContextClassLoader);
super.destroy();
filter.destroy();
} finally {
Thread.currentThread().setContextClassLoader(original);
}
}
//Delegate the init call to the actual filter
public void init(FilterConfig filterConfig) throws ServletException {
ClassLoader original = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(registeredContextClassLoader);
filter.init(filterConfig);
} finally {
Thread.currentThread().setContextClassLoader(original);
}
}
//Delegate the handling of the request to the actual filter
public void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
ClassLoader original = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(registeredContextClassLoader);
if (httpContext.handleSecurity(request, response))
filter.doFilter(request, response, chain);
} finally {
Thread.currentThread().setContextClassLoader(original);
}
}
public Filter getFilter() {
return filter;
}
public HttpContext getHttpContext() {
return httpContext;
}
public boolean matches(String dispatchPathInfo) {
if (!dispatchPathInfo.startsWith(prefix))
return false;
// perfect match
if (prefix.length() == dispatchPathInfo.length())
return suffix == null;
// check the next character is a path separator
if (dispatchPathInfo.charAt(prefix.length()) != '/')
return false;
// check for an extension match
if (suffix == null)
return true;
return dispatchPathInfo.endsWith(suffix) && dispatchPathInfo.length() > prefix.length() + suffix.length();
}
public int compareTo(Object other) {
FilterRegistration otherFilterRegistration = (FilterRegistration) other;
int priorityDifference = priority - otherFilterRegistration.priority;
if (priorityDifference != 0)
return -priorityDifference;
return (sequenceNumber > otherFilterRegistration.sequenceNumber) ? 1 : -1;
}
}

View File

@ -0,0 +1,35 @@
/*******************************************************************************
* Copyright (c) 2005, 2007 Cognos Incorporated, IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
*******************************************************************************/
package org.eclipse.equinox.http.servlet.internal;
import org.osgi.framework.*;
// Factory to create http services. This is because the service needs to be customized for each bundle in order to implement the default resource lookups.
public class HttpServiceFactory implements ServiceFactory {
private ProxyServlet proxy;
public HttpServiceFactory(ProxyServlet proxy) {
this.proxy = proxy;
}
public Object getService(Bundle bundle, ServiceRegistration registration) {
return new HttpServiceImpl(bundle, proxy);
}
public void ungetService(Bundle bundle, ServiceRegistration registration, Object service) {
((HttpServiceImpl) service).shutdown();
}
}

View File

@ -0,0 +1,119 @@
/*******************************************************************************
* Copyright (c) 2005, 2010 Cognos Incorporated, IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
*******************************************************************************/
package org.eclipse.equinox.http.servlet.internal;
import java.util.*;
import javax.servlet.*;
import org.eclipse.equinox.http.servlet.ExtendedHttpService;
import org.osgi.framework.Bundle;
import org.osgi.service.http.*;
public class HttpServiceImpl implements HttpService, ExtendedHttpService {
private Bundle bundle; //The bundle associated with this instance of http service
private ProxyServlet proxy; //The proxy that does the dispatching of the incoming requests
private Set aliases = new HashSet(); //Aliases registered against this particular instance of the service
private Set filters = new HashSet(); //Filters registered against this particular instance of the service
private boolean shutdown = false; // We prevent use of this instance if HttpServiceFactory.ungetService has called unregisterAliases.
public HttpServiceImpl(Bundle bundle, ProxyServlet proxy) {
this.bundle = bundle;
this.proxy = proxy;
}
//Clean up method
synchronized void shutdown() {
for (Iterator it = aliases.iterator(); it.hasNext();) {
String alias = (String) it.next();
proxy.unregister(alias, false);
}
aliases.clear();
for (Iterator it = filters.iterator(); it.hasNext();) {
Filter filter = (Filter) it.next();
proxy.unregisterFilter(filter, false);
}
filters.clear();
shutdown = true;
}
private void checkShutdown() {
if (shutdown)
throw new IllegalStateException("Service instance is already shutdown"); //$NON-NLS-1$
}
/**
* @see HttpService#registerServlet(String, Servlet, Dictionary, HttpContext)
*/
public synchronized void registerServlet(String alias, Servlet servlet, Dictionary initparams, HttpContext context) throws ServletException, NamespaceException {
checkShutdown();
if (context == null) {
context = createDefaultHttpContext();
}
proxy.registerServlet(alias, servlet, initparams, context);
aliases.add(alias);
}
/**
* @see HttpService#registerResources(String, String, HttpContext)
*/
public synchronized void registerResources(String alias, String name, HttpContext context) throws NamespaceException {
checkShutdown();
if (context == null) {
context = createDefaultHttpContext();
}
proxy.registerResources(alias, name, context);
aliases.add(alias);
}
/**
* @see HttpService#unregister(String)
*/
public synchronized void unregister(String alias) {
checkShutdown();
if (aliases.remove(alias)) {
proxy.unregister(alias, true);
} else {
throw new IllegalArgumentException("Alias not found: " + alias); //$NON-NLS-1$
}
}
/**
* @see HttpService#createDefaultHttpContext()
*/
public synchronized HttpContext createDefaultHttpContext() {
checkShutdown();
return new DefaultHttpContext(bundle);
}
public void registerFilter(String alias, Filter filter, Dictionary initparams, HttpContext context) throws ServletException {
checkShutdown();
if (context == null) {
context = createDefaultHttpContext();
}
proxy.registerFilter(alias, filter, initparams, context);
filters.add(filter);
}
public void unregisterFilter(Filter filter) {
checkShutdown();
if (filters.remove(filter)) {
proxy.unregisterFilter(filter, true);
} else {
throw new IllegalArgumentException("Filter not found."); //$NON-NLS-1$
}
}
}

View File

@ -0,0 +1,194 @@
/*******************************************************************************
* Copyright (c) 2005, 2007 Cognos Incorporated, IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
* Angelo Zerr <angelo.zerr@gmail.com> - give the capability to use resources (JSP, HTML, Servlet...)
* from the Bridge webapp with HTTP Filter.
*******************************************************************************/
package org.eclipse.equinox.http.servlet.internal;
import javax.servlet.*;
import javax.servlet.http.*;
import org.osgi.service.http.HttpContext;
public class HttpServletRequestAdaptor extends HttpServletRequestWrapper {
private String alias;
private Servlet servlet;
private boolean isRequestDispatcherInclude;
private boolean calledByFilter;
static final String INCLUDE_REQUEST_URI_ATTRIBUTE = "javax.servlet.include.request_uri"; //$NON-NLS-1$
static final String INCLUDE_CONTEXT_PATH_ATTRIBUTE = "javax.servlet.include.context_path"; //$NON-NLS-1$
static final String INCLUDE_SERVLET_PATH_ATTRIBUTE = "javax.servlet.include.servlet_path"; //$NON-NLS-1$
static final String INCLUDE_PATH_INFO_ATTRIBUTE = "javax.servlet.include.path_info"; //$NON-NLS-1$
public HttpServletRequestAdaptor(HttpServletRequest req, String alias, Servlet servlet, FilterChain filterChain) {
super(req);
this.alias = alias;
this.servlet = servlet;
isRequestDispatcherInclude = req.getAttribute(HttpServletRequestAdaptor.INCLUDE_REQUEST_URI_ATTRIBUTE) != null;
this.calledByFilter = (filterChain != null);
}
public String getAuthType() {
String authType = (String) super.getAttribute(HttpContext.AUTHENTICATION_TYPE);
if (authType != null)
return authType;
return super.getAuthType();
}
public String getRemoteUser() {
String remoteUser = (String) super.getAttribute(HttpContext.REMOTE_USER);
if (remoteUser != null)
return remoteUser;
return super.getRemoteUser();
}
public String getPathInfo() {
String pathInfo = getPathInfo(super.getPathInfo(), super.getContextPath(), super.getRequestURI(), this.calledByFilter);
if (isRequestDispatcherInclude)
return pathInfo;
if (alias.equals("/")) { //$NON-NLS-1$
return pathInfo;
}
pathInfo = pathInfo.substring(alias.length());
if (pathInfo.length() == 0)
return null;
return pathInfo;
}
public String getServletPath() {
if (isRequestDispatcherInclude)
return super.getServletPath();
if (alias.equals("/")) { //$NON-NLS-1$
return ""; //$NON-NLS-1$
}
return alias;
}
public String getContextPath() {
if (isRequestDispatcherInclude)
return super.getContextPath();
if (!calledByFilter)
// Not called with HTTP Filter, servlet case.
return super.getContextPath() + super.getServletPath();
// HTTP Filter case.
return super.getContextPath();
}
public Object getAttribute(String attributeName) {
if (isRequestDispatcherInclude) {
if (attributeName.equals(HttpServletRequestAdaptor.INCLUDE_CONTEXT_PATH_ATTRIBUTE)) {
String contextPath = (String) super.getAttribute(HttpServletRequestAdaptor.INCLUDE_CONTEXT_PATH_ATTRIBUTE);
if (contextPath == null || contextPath.equals("/")) //$NON-NLS-1$
contextPath = ""; //$NON-NLS-1$
String servletPath = (String) super.getAttribute(HttpServletRequestAdaptor.INCLUDE_SERVLET_PATH_ATTRIBUTE);
if (servletPath == null || servletPath.equals("/")) //$NON-NLS-1$
servletPath = ""; //$NON-NLS-1$
return contextPath + servletPath;
} else if (attributeName.equals(HttpServletRequestAdaptor.INCLUDE_SERVLET_PATH_ATTRIBUTE)) {
if (alias.equals("/")) { //$NON-NLS-1$
return ""; //$NON-NLS-1$
}
return alias;
} else if (attributeName.equals(HttpServletRequestAdaptor.INCLUDE_PATH_INFO_ATTRIBUTE)) {
String pathInfo = (String) super.getAttribute(HttpServletRequestAdaptor.INCLUDE_PATH_INFO_ATTRIBUTE);
if (alias.equals("/")) { //$NON-NLS-1$
return pathInfo;
}
pathInfo = pathInfo.substring(alias.length());
if (pathInfo.length() == 0)
return null;
return pathInfo;
}
}
return super.getAttribute(attributeName);
}
public RequestDispatcher getRequestDispatcher(String arg0) {
return new RequestDispatcherAdaptor(super.getRequestDispatcher(super.getServletPath() + arg0));
}
public static String getDispatchPathInfo(HttpServletRequest req, FilterChain filterChain) {
if (req.getAttribute(INCLUDE_REQUEST_URI_ATTRIBUTE) != null)
return (String) req.getAttribute(INCLUDE_PATH_INFO_ATTRIBUTE);
return getPathInfo(req.getPathInfo(), req.getContextPath(), req.getRequestURI(), filterChain);
}
/**
* Returns the path info pathInfo if not null otherwise compute it (in Filter case) by using contextPath + requestURI.
*
* @param pathInfo the path info coming from the request.getPathInfo().
* @param contextPath the context path coming from the request.getContextPath().
* @param requestURI the request URI coming from the request.getRequestURI().
* @param filterChain the filter chain or null if this method is not called with Filter.
* @return the path info pathInfo if not null otherwise compute it (in Filter case) by using contextPath + requestURI.
*/
private static String getPathInfo(String pathInfo, String contextPath, String requestURI, FilterChain filterChain) {
return getPathInfo(pathInfo, contextPath, requestURI, filterChain != null);
}
/**
* Returns the path info pathInfo if not null otherwise compute it (in Filter case) by using contextPath + requestURI.
*
* @param pathInfo the path info coming from the request.getPathInfo().
* @param contextPath the context path coming from the request.getContextPath().
* @param requestURI the request URI coming from the request.getRequestURI().
* @param calledByFilter true if this method is called with Filter and false otherwise.
* @return the path info pathInfo if not null otherwise compute it (in Filter case) by using contextPath + requestURI.
*/
private static String getPathInfo(String pathInfo, String contextPath, String requestURI, boolean calledByFilter) {
if (pathInfo != null) {
return pathInfo;
}
if (!calledByFilter) {
// Not called with HTTP Filter, servlet case.
return null;
}
// HTTP Filter case, pathInfo is null, compute it by using contextPath and requestURI
return requestURI.substring(contextPath.length(), requestURI.length());
}
public static String getDispatchServletPath(HttpServletRequest req) {
if (req.getAttribute(INCLUDE_REQUEST_URI_ATTRIBUTE) != null) {
String servletPath = (String) req.getAttribute(INCLUDE_SERVLET_PATH_ATTRIBUTE);
return (servletPath == null) ? "" : servletPath; //$NON-NLS-1$
}
return req.getServletPath();
}
public HttpSession getSession() {
HttpSession session = super.getSession();
if (session != null)
return new HttpSessionAdaptor(session, servlet);
return null;
}
public HttpSession getSession(boolean create) {
HttpSession session = super.getSession(create);
if (session != null)
return new HttpSessionAdaptor(session, servlet);
return null;
}
}

View File

@ -0,0 +1,103 @@
/*******************************************************************************
* Copyright (c) 2005, 2007 Cognos Incorporated, IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
*******************************************************************************/
package org.eclipse.equinox.http.servlet.internal;
import java.util.Enumeration;
import javax.servlet.Servlet;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
// This class adapts HttpSessions in order to return the right ServletContext
public class HttpSessionAdaptor implements HttpSession {
private HttpSession session;
private Servlet servlet;
public HttpSessionAdaptor(HttpSession session, Servlet servlet) {
this.session = session;
this.servlet = servlet;
}
public ServletContext getServletContext() {
return servlet.getServletConfig().getServletContext();
}
public Object getAttribute(String arg0) {
return session.getAttribute(arg0);
}
public Enumeration getAttributeNames() {
return session.getAttributeNames();
}
public long getCreationTime() {
return session.getCreationTime();
}
public String getId() {
return session.getId();
}
public long getLastAccessedTime() {
return session.getLastAccessedTime();
}
public int getMaxInactiveInterval() {
return session.getMaxInactiveInterval();
}
/**@deprecated*/
public javax.servlet.http.HttpSessionContext getSessionContext() {
return session.getSessionContext();
}
/**@deprecated*/
public Object getValue(String arg0) {
return session.getValue(arg0);
}
/**@deprecated*/
public String[] getValueNames() {
return session.getValueNames();
}
public void invalidate() {
session.invalidate();
}
public boolean isNew() {
return session.isNew();
}
/**@deprecated*/
public void putValue(String arg0, Object arg1) {
session.putValue(arg0, arg1);
}
public void removeAttribute(String arg0) {
session.removeAttribute(arg0);
}
/**@deprecated*/
public void removeValue(String arg0) {
session.removeValue(arg0);
}
public void setAttribute(String arg0, Object arg1) {
session.setAttribute(arg0, arg1);
}
public void setMaxInactiveInterval(int arg0) {
session.setMaxInactiveInterval(arg0);
}
}

View File

@ -0,0 +1,135 @@
/*******************************************************************************
* Copyright (c) 2005, 2007 Cognos Incorporated, IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
*******************************************************************************/
package org.eclipse.equinox.http.servlet.internal;
import java.io.File;
import java.util.*;
import javax.servlet.FilterChain;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import org.osgi.service.http.HttpContext;
/**
* The ProxyContext provides something similar to a ServletContext for all servlets and resources under a particular ProxyServlet.
* In particular it holds and represent the concept of "context path" through the Proxy Servlets servlet path.
* The Http Service also requires a ServletContext namespaced by each individual HttpContext. The ProxyContext provides support for the
* attribute map of a ServletContext again namespaced by HttpContext as specified in the Http Service specification. The ContextAttributes
* are reference counted so that when the HttpContext is no longer referenced the associated context attributes can be
* garbage collected and the context temp dir deleteted.
*/
public class ProxyContext {
private static final String JAVAX_SERVLET_CONTEXT_TEMPDIR = "javax.servlet.context.tempdir"; //$NON-NLS-1$
private String servletPath;
private HashMap attributesMap = new HashMap();
File proxyContextTempDir;
public ProxyContext(ServletContext servletContext) {
File tempDir = (File) servletContext.getAttribute(JAVAX_SERVLET_CONTEXT_TEMPDIR);
if (tempDir != null) {
proxyContextTempDir = new File(tempDir, "proxytemp"); //$NON-NLS-1$
deleteDirectory(proxyContextTempDir);
proxyContextTempDir.mkdirs();
}
}
public void destroy() {
if (proxyContextTempDir != null)
deleteDirectory(proxyContextTempDir);
}
synchronized void initializeServletPath(HttpServletRequest req, FilterChain filterChain) {
if (servletPath == null) {
if (filterChain != null)
servletPath = "/";
else
servletPath = HttpServletRequestAdaptor.getDispatchServletPath(req);
}
}
synchronized String getServletPath() {
return servletPath;
}
synchronized void createContextAttributes(HttpContext httpContext) {
ContextAttributes attributes = (ContextAttributes) attributesMap.get(httpContext);
if (attributes == null) {
attributes = new ContextAttributes(httpContext);
attributesMap.put(httpContext, attributes);
}
attributes.addReference();
}
synchronized void destroyContextAttributes(HttpContext httpContext) {
ContextAttributes attributes = (ContextAttributes) attributesMap.get(httpContext);
attributes.removeReference();
if (attributes.referenceCount() == 0) {
attributesMap.remove(httpContext);
attributes.destroy();
}
}
synchronized Dictionary getContextAttributes(HttpContext httpContext) {
return (Dictionary) attributesMap.get(httpContext);
}
/**
* deleteDirectory is a convenience method to recursively delete a directory
* @param directory - the directory to delete.
* @return was the delete succesful
*/
protected static boolean deleteDirectory(File directory) {
if (directory.exists() && directory.isDirectory()) {
File[] files = directory.listFiles();
for (int i = 0; i < files.length; i++) {
if (files[i].isDirectory()) {
deleteDirectory(files[i]);
} else {
files[i].delete();
}
}
}
return directory.delete();
}
public class ContextAttributes extends Hashtable {
private static final long serialVersionUID = 1916670423277243587L;
private int referenceCount;
public ContextAttributes(HttpContext httpContext) {
if (proxyContextTempDir != null) {
File contextTempDir = new File(proxyContextTempDir, "hc_" + httpContext.hashCode()); //$NON-NLS-1$
contextTempDir.mkdirs();
put(JAVAX_SERVLET_CONTEXT_TEMPDIR, contextTempDir);
}
}
public void destroy() {
File contextTempDir = (File) get(JAVAX_SERVLET_CONTEXT_TEMPDIR);
if (contextTempDir != null)
deleteDirectory(contextTempDir);
}
public void addReference() {
referenceCount++;
}
public void removeReference() {
referenceCount--;
}
public int referenceCount() {
return referenceCount;
}
}
}

View File

@ -0,0 +1,320 @@
/*******************************************************************************
* Copyright (c) 2005, 2007 Cognos Incorporated, IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
* Angelo Zerr <angelo.zerr@gmail.com> - give the capability to use resources (JSP, HTML, Servlet...)
* from the Bridge webapp with HTTP Filter.
*******************************************************************************/
package org.eclipse.equinox.http.servlet.internal;
import java.io.IOException;
import java.security.AccessController;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.osgi.service.http.HttpContext;
import org.osgi.service.http.NamespaceException;
/**
* The ProxyServlet is the private side of a Servlet that when registered (and init() called) in a servlet container
* will in-turn register and provide an OSGi Http Service implementation.
* This class is not meant for extending or even using directly and is purely meant for registering
* in a servlet container.
*/
public class ProxyServlet extends HttpServlet implements Filter {
private static final long serialVersionUID = 4117456123807468871L;
private Map servletRegistrations = new HashMap(); //alias --> servlet registration
private Set registeredServlets = new HashSet(); //All the servlets objects that have been registered
private Map filterRegistrations = new HashMap(); //filter --> filter registration;
private ProxyContext proxyContext;
public void init(ServletConfig config) throws ServletException {
super.init(config);
proxyContext = new ProxyContext(config.getServletContext());
Activator.addProxyServlet(this);
}
public void destroy() {
Activator.removeProxyServlet(this);
proxyContext.destroy();
proxyContext = null;
super.destroy();
}
/**
* @see HttpServlet#service(ServletRequest, ServletResponse)
*/
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
process(req, resp, null);
}
protected void process(HttpServletRequest req, HttpServletResponse resp, FilterChain filterChain) throws ServletException, IOException {
proxyContext.initializeServletPath(req, filterChain);
String alias = HttpServletRequestAdaptor.getDispatchPathInfo(req, filterChain);
if (alias == null)
alias = "/"; //$NON-NLS-1$
// perfect match
if (processAlias(req, resp, alias, null, filterChain))
return;
String extensionAlias = findExtensionAlias(alias);
alias = alias.substring(0, alias.lastIndexOf('/'));
// longest path match
while (alias.length() != 0) {
if (processAlias(req, resp, alias, extensionAlias, filterChain))
return;
alias = alias.substring(0, alias.lastIndexOf('/'));
}
// default handler match
if (extensionAlias != null)
extensionAlias = extensionAlias.substring(1); // remove the leading '/'
if (processAlias(req, resp, "/", extensionAlias, filterChain)) //Handle '/' aliases //$NON-NLS-1$
return;
// Cannot find the Servlet or Filter from the OSGi registry services :
if (filterChain != null) {
// Delegate the HTTP request to the Web server container.
filterChain.doFilter(req, resp);
} else {
// Send HTTP 4040 Error.
resp.sendError(HttpServletResponse.SC_NOT_FOUND, "ProxyServlet: " + req.getRequestURI()); //$NON-NLS-1$
}
}
private String findExtensionAlias(String alias) {
String lastSegment = alias.substring(alias.lastIndexOf('/') + 1);
int dot = lastSegment.lastIndexOf('.');
if (dot == -1)
return null;
String extension = lastSegment.substring(dot + 1);
if (extension.length() == 0)
return null;
return "/*." + extension; //$NON-NLS-1$
}
private boolean processAlias(HttpServletRequest req, HttpServletResponse resp, String alias, String extensionAlias, FilterChain filterChain) throws ServletException, IOException {
ServletRegistration registration = null;
List matchingFilterRegistrations = Collections.EMPTY_LIST;
String dispatchPathInfo = HttpServletRequestAdaptor.getDispatchPathInfo(req, filterChain);
synchronized (this) {
if (extensionAlias == null)
registration = (ServletRegistration) servletRegistrations.get(alias);
else {
registration = (ServletRegistration) servletRegistrations.get(alias + extensionAlias);
if (registration != null) {
// for regular ServletRegistrations extensions should be handled on the full alias
if (!(registration.getServlet() instanceof ResourceServlet))
alias = HttpServletRequestAdaptor.getDispatchPathInfo(req, filterChain);
} else
registration = (ServletRegistration) servletRegistrations.get(alias);
}
if (registration != null) {
registration.addReference();
if (!filterRegistrations.isEmpty()) {
matchingFilterRegistrations = new ArrayList();
for (Iterator it = filterRegistrations.values().iterator(); it.hasNext();) {
FilterRegistration filterRegistration = (FilterRegistration) it.next();
if (filterRegistration.matches(dispatchPathInfo)) {
matchingFilterRegistrations.add(filterRegistration);
filterRegistration.addReference();
}
}
}
}
}
if (registration != null) {
try {
HttpServletRequest wrappedRequest = new HttpServletRequestAdaptor(req, alias, registration.getServlet(), filterChain);
if (matchingFilterRegistrations.isEmpty()) {
registration.service(wrappedRequest, resp);
} else {
Collections.sort(matchingFilterRegistrations);
FilterChain chain = new FilterChainImpl(matchingFilterRegistrations, registration);
chain.doFilter(wrappedRequest, resp);
}
} finally {
registration.removeReference();
for (Iterator it = matchingFilterRegistrations.iterator(); it.hasNext();) {
FilterRegistration filterRegistration = (FilterRegistration) it.next();
filterRegistration.removeReference();
}
}
return true;
}
return false;
}
//Effective unregistration of servlet and resources as defined in HttpService#unregister()
synchronized void unregister(String alias, boolean destroy) {
ServletRegistration removedRegistration = (ServletRegistration) servletRegistrations.remove(alias);
if (removedRegistration != null) {
registeredServlets.remove(removedRegistration.getServlet());
try {
if (destroy)
removedRegistration.destroy();
} finally {
proxyContext.destroyContextAttributes(removedRegistration.getHttpContext());
}
}
}
//Effective registration of the servlet as defined HttpService#registerServlet()
synchronized void registerServlet(String alias, Servlet servlet, Dictionary initparams, HttpContext httpContext) throws ServletException, NamespaceException {
checkAlias(alias);
if (servletRegistrations.containsKey(alias))
throw new NamespaceException("The alias '" + alias + "' is already in use."); //$NON-NLS-1$//$NON-NLS-2$
if (servlet == null)
throw new IllegalArgumentException("Servlet cannot be null"); //$NON-NLS-1$
if (registeredServlets.contains(servlet))
throw new ServletException("This servlet has already been registered."); //$NON-NLS-1$
ServletRegistration registration = new ServletRegistration(servlet, httpContext);
ServletContext wrappedServletContext = new ServletContextAdaptor(proxyContext, getServletContext(), httpContext, AccessController.getContext());
ServletConfig servletConfig = new ServletConfigImpl(servlet, initparams, wrappedServletContext);
boolean initialized = false;
proxyContext.createContextAttributes(httpContext);
try {
registration.init(servletConfig);
initialized = true;
} finally {
if (!initialized)
proxyContext.destroyContextAttributes(httpContext);
}
registeredServlets.add(servlet);
servletRegistrations.put(alias, registration);
}
//Effective registration of the resources as defined HttpService#registerResources()
synchronized void registerResources(String alias, String name, HttpContext httpContext) throws NamespaceException {
checkName(name);
Servlet resourceServlet = new ResourceServlet(name, httpContext, AccessController.getContext());
try {
registerServlet(alias, resourceServlet, null, httpContext);
} catch (ServletException e) {
throw new IllegalStateException("Unexpected ServletException throw when registering resources at alias " + alias + "."); //$NON-NLS-1$//$NON-NLS-2$
}
}
private void checkName(String name) {
if (name == null)
throw new IllegalArgumentException("Name cannot be null"); //$NON-NLS-1$
if (name.endsWith("/") && !name.equals("/")) //$NON-NLS-1$ //$NON-NLS-2$
throw new IllegalArgumentException("Invalid Name '" + name + "'"); //$NON-NLS-1$//$NON-NLS-2$
}
private void checkAlias(String alias) {
if (alias == null)
throw new IllegalArgumentException("Alias cannot be null"); //$NON-NLS-1$
if (!alias.startsWith("/") || (alias.endsWith("/") && !alias.equals("/"))) //$NON-NLS-1$ //$NON-NLS-2$//$NON-NLS-3$
throw new IllegalArgumentException("Invalid alias '" + alias + "'"); //$NON-NLS-1$//$NON-NLS-2$
}
public synchronized void unregisterFilter(Filter filter, boolean destroy) {
FilterRegistration removedRegistration = (FilterRegistration) filterRegistrations.remove(filter);
if (removedRegistration != null) {
try {
if (destroy)
removedRegistration.destroy();
} finally {
proxyContext.destroyContextAttributes(removedRegistration.getHttpContext());
}
}
}
public synchronized void registerFilter(String alias, Filter filter, Dictionary initparams, HttpContext httpContext) throws ServletException {
checkAlias(alias);
if (filter == null)
throw new IllegalArgumentException("Filter cannot be null"); //$NON-NLS-1$
if (filterRegistrations.containsKey(filter))
throw new ServletException("This filter has already been registered."); //$NON-NLS-1$
int filterPriority = findFilterPriority(initparams);
FilterRegistration registration = new FilterRegistration(filter, httpContext, alias, filterPriority);
ServletContext wrappedServletContext = new ServletContextAdaptor(proxyContext, getServletContext(), httpContext, AccessController.getContext());
FilterConfig filterConfig = new FilterConfigImpl(filter, initparams, wrappedServletContext);
boolean initialized = false;
proxyContext.createContextAttributes(httpContext);
try {
registration.init(filterConfig);
initialized = true;
} finally {
if (!initialized)
proxyContext.destroyContextAttributes(httpContext);
}
filterRegistrations.put(filter, registration);
}
private int findFilterPriority(Dictionary initparams) {
if (initparams == null)
return 0;
String filterPriority = (String) initparams.get("filter-priority"); //$NON-NLS-1$
if (filterPriority == null)
return 0;
try {
int result = Integer.parseInt(filterPriority);
if (result >= -1000 && result <= 1000)
return result;
} catch (NumberFormatException e) {
// fall through
}
throw new IllegalArgumentException("filter-priority must be an integer between -1000 and 1000 but was: " + filterPriority); //$NON-NLS-1$
}
public void init(FilterConfig filterConfig) throws ServletException {
ServletConfig servletConfig = new ServletConfigAdaptor(filterConfig);
this.init(servletConfig);
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
process(req, resp, chain);
}
private static class ServletConfigAdaptor implements ServletConfig {
private FilterConfig filterConfig;
public ServletConfigAdaptor(FilterConfig filterConfig) {
this.filterConfig = filterConfig;
}
public String getInitParameter(String arg0) {
return filterConfig.getInitParameter(arg0);
}
public Enumeration getInitParameterNames() {
return filterConfig.getInitParameterNames();
}
public ServletContext getServletContext() {
return filterConfig.getServletContext();
}
public String getServletName() {
return filterConfig.getFilterName();
}
}
}

View File

@ -0,0 +1,45 @@
/*******************************************************************************
* Copyright (c) 2005, 2007 Cognos Incorporated, IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
*******************************************************************************/
package org.eclipse.equinox.http.servlet.internal;
public abstract class Registration {
protected int referenceCount;
public synchronized void addReference() {
++referenceCount;
}
public synchronized void removeReference() {
--referenceCount;
if (referenceCount == 0) {
notifyAll();
}
}
public synchronized void destroy() {
boolean interrupted = false;
try {
while (referenceCount != 0) {
try {
wait();
} catch (InterruptedException e) {
// wait until the servlet is inactive but save the interrupted status
interrupted = true;
}
}
} finally {
if (interrupted)
Thread.currentThread().interrupt(); //restore the interrupted state
}
}
}

View File

@ -0,0 +1,39 @@
/*******************************************************************************
* Copyright (c) 2005, 2007 Cognos Incorporated, IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
*******************************************************************************/
package org.eclipse.equinox.http.servlet.internal;
import java.io.IOException;
import javax.servlet.*;
//This class unwraps the request so it can be processed by the underlying servlet container.
public class RequestDispatcherAdaptor implements RequestDispatcher {
private RequestDispatcher requestDispatcher;
public RequestDispatcherAdaptor(RequestDispatcher requestDispatcher) {
this.requestDispatcher = requestDispatcher;
}
public void forward(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
if (req instanceof HttpServletRequestAdaptor)
req = ((HttpServletRequestAdaptor) req).getRequest();
requestDispatcher.forward(req, resp);
}
public void include(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
if (req instanceof HttpServletRequestAdaptor)
req = ((HttpServletRequestAdaptor) req).getRequest();
requestDispatcher.include(req, resp);
}
}

View File

@ -0,0 +1,188 @@
/*******************************************************************************
* Copyright (c) 2005-2007 Cognos Incorporated, IBM Corporation and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
* Angelo Zerr <angelo.zerr@gmail.com> - give the capability to use resources (JSP, HTML, Servlet...)
* from the Bridge webapp with HTTP Filter.
*******************************************************************************/
package org.eclipse.equinox.http.servlet.internal;
import java.io.*;
import java.net.URL;
import java.net.URLConnection;
import java.security.*;
import javax.servlet.http.*;
import org.osgi.service.http.HttpContext;
public class ResourceServlet extends HttpServlet {
private static final long serialVersionUID = 3586876493076122102L;
private static final String LAST_MODIFIED = "Last-Modified"; //$NON-NLS-1$
private static final String IF_MODIFIED_SINCE = "If-Modified-Since"; //$NON-NLS-1$
private static final String IF_NONE_MATCH = "If-None-Match"; //$NON-NLS-1$
private static final String ETAG = "ETag"; //$NON-NLS-1$
private String internalName;
HttpContext httpContext;
private AccessControlContext acc;
public ResourceServlet(String internalName, HttpContext context, AccessControlContext acc) {
this.internalName = internalName;
if (internalName.equals("/")) { //$NON-NLS-1$
this.internalName = ""; //$NON-NLS-1$
}
this.httpContext = context;
this.acc = acc;
}
public void service(HttpServletRequest req, final HttpServletResponse resp) throws IOException {
String method = req.getMethod();
if (method.equals("GET") || method.equals("POST") || method.equals("HEAD")) { //$NON-NLS-1$//$NON-NLS-2$ //$NON-NLS-3$
String pathInfo = HttpServletRequestAdaptor.getDispatchPathInfo(req, null);
if (pathInfo == null)
pathInfo = ""; //$NON-NLS-1$
String resourcePath = internalName + pathInfo;
URL resourceURL = httpContext.getResource(resourcePath);
if (resourceURL != null)
writeResource(req, resp, resourcePath, resourceURL);
else
resp.sendError(HttpServletResponse.SC_NOT_FOUND, "ProxyServlet: " + req.getRequestURI()); //$NON-NLS-1$
} else {
resp.setStatus(HttpServletResponse.SC_METHOD_NOT_ALLOWED);
}
}
private void writeResource(final HttpServletRequest req, final HttpServletResponse resp, final String resourcePath, final URL resourceURL) throws IOException {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws Exception {
URLConnection connection = resourceURL.openConnection();
long lastModified = connection.getLastModified();
int contentLength = connection.getContentLength();
String etag = null;
if (lastModified != -1 && contentLength != -1)
etag = "W/\"" + contentLength + "-" + lastModified + "\""; //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
// Check for cache revalidation.
// We should prefer ETag validation as the guarantees are stronger and all HTTP 1.1 clients should be using it
String ifNoneMatch = req.getHeader(IF_NONE_MATCH);
if (ifNoneMatch != null && etag != null && ifNoneMatch.indexOf(etag) != -1) {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
return Boolean.TRUE;
}
long ifModifiedSince = req.getDateHeader(IF_MODIFIED_SINCE);
// for purposes of comparison we add 999 to ifModifiedSince since the fidelity
// of the IMS header generally doesn't include milli-seconds
if (ifModifiedSince > -1 && lastModified > 0 && lastModified <= (ifModifiedSince + 999)) {
resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
return Boolean.TRUE;
}
// return the full contents regularly
if (contentLength != -1)
resp.setContentLength(contentLength);
String contentType = httpContext.getMimeType(resourcePath);
if (contentType == null)
contentType = getServletConfig().getServletContext().getMimeType(resourcePath);
if (contentType != null)
resp.setContentType(contentType);
if (lastModified > 0)
resp.setDateHeader(LAST_MODIFIED, lastModified);
if (etag != null)
resp.setHeader(ETAG, etag);
if (contentLength != 0) {
// open the input stream
InputStream is = null;
try {
is = connection.getInputStream();
// write the resource
try {
OutputStream os = resp.getOutputStream();
int writtenContentLength = writeResourceToOutputStream(is, os);
if (contentLength == -1 || contentLength != writtenContentLength)
resp.setContentLength(writtenContentLength);
} catch (IllegalStateException e) { // can occur if the response output is already open as a Writer
Writer writer = resp.getWriter();
writeResourceToWriter(is, writer);
// Since ContentLength is a measure of the number of bytes contained in the body
// of a message when we use a Writer we lose control of the exact byte count and
// defer the problem to the Servlet Engine's Writer implementation.
}
} catch (FileNotFoundException e) {
// FileNotFoundException may indicate the following scenarios
// - url is a directory
// - url is not accessible
sendError(resp, HttpServletResponse.SC_FORBIDDEN);
} catch (SecurityException e) {
// SecurityException may indicate the following scenarios
// - url is not accessible
sendError(resp, HttpServletResponse.SC_FORBIDDEN);
} finally {
if (is != null)
try {
is.close();
} catch (IOException e) {
// ignore
}
}
}
return Boolean.TRUE;
}
}, acc);
} catch (PrivilegedActionException e) {
throw (IOException) e.getException();
}
}
void sendError(final HttpServletResponse resp, int sc) throws IOException {
try {
// we need to reset headers for 302 and 403
resp.reset();
resp.sendError(sc);
} catch (IllegalStateException e) {
// this could happen if the response has already been committed
}
}
int writeResourceToOutputStream(InputStream is, OutputStream os) throws IOException {
byte[] buffer = new byte[8192];
int bytesRead = is.read(buffer);
int writtenContentLength = 0;
while (bytesRead != -1) {
os.write(buffer, 0, bytesRead);
writtenContentLength += bytesRead;
bytesRead = is.read(buffer);
}
return writtenContentLength;
}
void writeResourceToWriter(InputStream is, Writer writer) throws IOException {
Reader reader = new InputStreamReader(is);
try {
char[] buffer = new char[8192];
int charsRead = reader.read(buffer);
while (charsRead != -1) {
writer.write(buffer, 0, charsRead);
charsRead = reader.read(buffer);
}
} finally {
if (reader != null) {
reader.close(); // will also close input stream
}
}
}
}

View File

@ -0,0 +1,53 @@
/*******************************************************************************
* Copyright (c) 2005, 2007 Cognos Incorporated, IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
*******************************************************************************/
package org.eclipse.equinox.http.servlet.internal;
import java.util.*;
import javax.servlet.*;
public class ServletConfigImpl implements ServletConfig {
private static final Dictionary EMPTY_PARAMS = new Hashtable(0);
private static final String SERVLET_NAME = "servlet-name"; //$NON-NLS-1$
private Servlet servlet;
private Dictionary initparams;
private ServletContext servletContext;
public ServletConfigImpl(Servlet servlet, Dictionary initparams, ServletContext servletContext) {
this.servlet = servlet;
this.initparams = (initparams != null) ? initparams : EMPTY_PARAMS;
this.servletContext = servletContext;
}
/*
* @see javax.servlet.ServletConfig#getServletName()
*
* The OSGi Http Service does not specify a way to set a servlet name at the API level. This
* implementation will try to use the value of the "servlet-name" initial parameter if available.
*/
public String getServletName() {
String servletName = (String) initparams.get(SERVLET_NAME);
return (servletName != null) ? servletName : servlet.getClass().getName();
}
public ServletContext getServletContext() {
return servletContext;
}
public String getInitParameter(String name) {
return (String) initparams.get(name);
}
public Enumeration getInitParameterNames() {
return initparams.keys();
}
}

View File

@ -0,0 +1,186 @@
/*******************************************************************************
* Copyright (c) 2005, 2007 Cognos Incorporated, IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
*******************************************************************************/
package org.eclipse.equinox.http.servlet.internal;
import java.io.*;
import java.lang.reflect.Method;
import java.net.URL;
import java.security.*;
import java.util.*;
import javax.servlet.*;
import org.osgi.service.http.HttpContext;
public class ServletContextAdaptor implements ServletContext {
private ServletContext servletContext;
HttpContext httpContext;
private AccessControlContext acc;
private ProxyContext proxyContext;
public ServletContextAdaptor(ProxyContext proxyContext, ServletContext servletContext, HttpContext httpContext, AccessControlContext acc) {
this.servletContext = servletContext;
this.httpContext = httpContext;
this.acc = acc;
this.proxyContext = proxyContext;
}
/**
* @see javax.servlet.ServletContext#getResourcePaths(java.lang.String)
*
* This method was added in the Servlet 2.3 API however the OSGi HttpService currently does not provide
* support for this method in the HttpContext interface. To support "getResourcePaths(...) this
* implementation uses reflection to check for and then call the associated HttpContext.getResourcePaths(...)
* method opportunistically. Null is returned if the method is not present or fails.
*/
public Set getResourcePaths(String name) {
if (name == null || !name.startsWith("/")) //$NON-NLS-1$
return null;
try {
Method getResourcePathsMethod = httpContext.getClass().getMethod("getResourcePaths", new Class[] {String.class}); //$NON-NLS-1$
if (!getResourcePathsMethod.isAccessible())
getResourcePathsMethod.setAccessible(true);
return (Set) getResourcePathsMethod.invoke(httpContext, new Object[] {name});
} catch (Exception e) {
// ignore
}
return null;
}
public Object getAttribute(String attributeName) {
Dictionary attributes = proxyContext.getContextAttributes(httpContext);
return attributes.get(attributeName);
}
public Enumeration getAttributeNames() {
Dictionary attributes = proxyContext.getContextAttributes(httpContext);
return attributes.keys();
}
public void setAttribute(String attributeName, Object attributeValue) {
Dictionary attributes = proxyContext.getContextAttributes(httpContext);
attributes.put(attributeName, attributeValue);
}
public void removeAttribute(String attributeName) {
Dictionary attributes = proxyContext.getContextAttributes(httpContext);
attributes.remove(attributeName);
}
public String getMimeType(String name) {
String mimeType = httpContext.getMimeType(name);
return (mimeType != null) ? mimeType : servletContext.getMimeType(name);
}
public URL getResource(final String name) {
try {
return (URL) AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws Exception {
return httpContext.getResource(name);
}
}, acc);
} catch (PrivilegedActionException e) {
log(e.getException().getMessage(), e.getException());
}
return null;
}
public InputStream getResourceAsStream(String name) {
URL url = getResource(name);
if (url != null) {
try {
return url.openStream();
} catch (IOException e) {
log("Error opening stream for resource '" + name + "'", e); //$NON-NLS-1$ //$NON-NLS-2$
}
}
return null;
}
public ServletContext getContext(String arg0) {
return servletContext.getContext(arg0);
}
public String getInitParameter(String arg0) {
return servletContext.getInitParameter(arg0);
}
public Enumeration getInitParameterNames() {
return servletContext.getInitParameterNames();
}
public int getMajorVersion() {
return servletContext.getMajorVersion();
}
public int getMinorVersion() {
return servletContext.getMinorVersion();
}
public RequestDispatcher getNamedDispatcher(String arg0) {
return new RequestDispatcherAdaptor(servletContext.getNamedDispatcher(arg0));
}
public String getRealPath(String arg0) {
return servletContext.getRealPath(arg0);
}
public RequestDispatcher getRequestDispatcher(String arg0) {
return new RequestDispatcherAdaptor(servletContext.getRequestDispatcher(proxyContext.getServletPath() + arg0));
}
public String getServerInfo() {
return servletContext.getServerInfo();
}
/**@deprecated*/
public Servlet getServlet(String arg0) throws ServletException {
return servletContext.getServlet(arg0);
}
public String getServletContextName() {
return servletContext.getServletContextName();
}
/**@deprecated*/
public Enumeration getServletNames() {
return servletContext.getServletNames();
}
/**@deprecated*/
public Enumeration getServlets() {
return servletContext.getServlets();
}
/**@deprecated*/
public void log(Exception arg0, String arg1) {
servletContext.log(arg0, arg1);
}
public void log(String arg0, Throwable arg1) {
servletContext.log(arg0, arg1);
}
public void log(String arg0) {
servletContext.log(arg0);
}
// Added in Servlet 2.5
public String getContextPath() {
try {
Method getContextPathMethod = servletContext.getClass().getMethod("getContextPath", null); //$NON-NLS-1$
return (String) getContextPathMethod.invoke(servletContext, null) + proxyContext.getServletPath();
} catch (Exception e) {
// ignore
}
return null;
}
}

View File

@ -0,0 +1,74 @@
/*******************************************************************************
* Copyright (c) 2005-2007 Cognos Incorporated, IBM Corporation and others
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
*******************************************************************************/
package org.eclipse.equinox.http.servlet.internal;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.osgi.service.http.HttpContext;
//This class wraps the servlet object registered in the HttpService.registerServlet call, to manage the context classloader when handleRequests are being asked.
public class ServletRegistration extends Registration {
private Servlet servlet; //The actual servlet object registered against the http service. All requests will eventually be delegated to it.
private HttpContext httpContext; //The context used during the registration of the servlet
private ClassLoader registeredContextClassLoader;
public ServletRegistration(Servlet servlet, HttpContext context) {
this.servlet = servlet;
this.httpContext = context;
registeredContextClassLoader = Thread.currentThread().getContextClassLoader();
}
public void destroy() {
ClassLoader original = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(registeredContextClassLoader);
super.destroy();
servlet.destroy();
} finally {
Thread.currentThread().setContextClassLoader(original);
}
}
//Delegate the init call to the actual servlet
public void init(ServletConfig servletConfig) throws ServletException {
ClassLoader original = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(registeredContextClassLoader);
servlet.init(servletConfig);
} finally {
Thread.currentThread().setContextClassLoader(original);
}
}
//Delegate the handling of the request to the actual servlet
public void service(HttpServletRequest req, HttpServletResponse resp) throws IOException, ServletException {
ClassLoader original = Thread.currentThread().getContextClassLoader();
try {
Thread.currentThread().setContextClassLoader(registeredContextClassLoader);
if (httpContext.handleSecurity(req, resp))
servlet.service(req, resp);
} finally {
Thread.currentThread().setContextClassLoader(original);
}
}
public Servlet getServlet() {
return servlet;
}
public HttpContext getHttpContext() {
return httpContext;
}
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.adempiere.eclipse.equinox.http.servletbridge</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,8 @@
#Fri Dec 24 14:43:16 MYT 2010
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6

View File

@ -0,0 +1,4 @@
#Fri Dec 24 14:43:16 MYT 2010
eclipse.preferences.version=1
pluginProject.extensions=false
resolve.requirebundle=false

View File

@ -0,0 +1,18 @@
Manifest-Version: 1.0
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: CDC-1.0/Foundation-1.0,J2SE-1.3
Bundle-Name: %bundleName
Bundle-SymbolicName: org.adempiere.eclipse.equinox.http.servletbridge;singleton:=true
Eclipse-SourceReferences: scm:cvs:pserver:dev.eclipse.org:/cvsroot/rt:
org.eclipse.equinox/server-side/bundles/org.eclipse.equinox.http.serv
letbridge;tag=v20100503
Bundle-Activator: org.eclipse.equinox.http.servletbridge.internal.Acti
vator
Bundle-Version: 1.0.200.v20100503
Import-Package: javax.servlet;version="2.3",javax.servlet.http;version
="2.3",org.eclipse.equinox.http.servlet;version="1.0.0",org.eclipse.e
quinox.servletbridge;version="1.0.0",org.osgi.framework;version="1.3.
0",org.osgi.service.http;version="1.2.0"
Bundle-ManifestVersion: 2

View File

@ -0,0 +1,28 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<title>About</title>
</head>
<body lang="EN-US">
<h2>About This Content</h2>
<p>January 30, 2007</p>
<h3>License</h3>
<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
indicated below, the Content is provided to you under the terms and conditions of the
Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
apply to your use of any object code in the Content. Check the Redistributor's license that was
provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
indicated below, the terms and conditions of the EPL still apply to any source code in the Content
and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
</body>
</html>

View File

@ -0,0 +1,4 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.

View File

@ -0,0 +1,4 @@
##Source Bundle Localization
#Thu Jun 24 08:29:00 EDT 2010
bundleName=Servletbridge Http Service Source
providerName=Eclipse.org - Equinox

View File

@ -0,0 +1,32 @@
/*******************************************************************************
* Copyright (c) 2005, 2007 Cognos Incorporated, IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
*******************************************************************************/
package org.eclipse.equinox.http.servletbridge.internal;
import org.eclipse.equinox.http.servlet.HttpServiceServlet;
import org.eclipse.equinox.servletbridge.BridgeServlet;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
public class Activator implements BundleActivator {
private HttpServiceServlet httpServiceServlet;
public void start(BundleContext context) throws Exception {
httpServiceServlet = new HttpServiceServlet();
BridgeServlet.registerServletDelegate(httpServiceServlet);
}
public void stop(BundleContext context) throws Exception {
BridgeServlet.unregisterServletDelegate(httpServiceServlet);
httpServiceServlet = null;
}
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>org.adempiere.eclipse.equinox.servletbridge</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.ManifestBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.pde.SchemaBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.pde.PluginNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>

View File

@ -0,0 +1,8 @@
#Fri Dec 24 14:44:01 MYT 2010
eclipse.preferences.version=1
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6
org.eclipse.jdt.core.compiler.compliance=1.6
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
org.eclipse.jdt.core.compiler.source=1.6

View File

@ -0,0 +1,4 @@
#Fri Dec 24 14:44:01 MYT 2010
eclipse.preferences.version=1
pluginProject.extensions=false
resolve.requirebundle=false

View File

@ -0,0 +1,14 @@
Manifest-Version: 1.0
Bundle-Vendor: %providerName
Bundle-Localization: plugin
Bundle-RequiredExecutionEnvironment: CDC-1.0/Foundation-1.0,J2SE-1.3
Bundle-Name: %bundleName
Bundle-SymbolicName: org.adempiere.eclipse.equinox.servletbridge;singleton:=true
Eclipse-SourceReferences: scm:cvs:pserver:dev.eclipse.org:/cvsroot/rt:
org.eclipse.equinox/server-side/bundles/org.eclipse.equinox.servletbr
idge;tag=v20100503
Bundle-Version: 1.2.0.v20100503
Export-Package: org.eclipse.equinox.servletbridge;version="1.1.0"
Import-Package: javax.servlet;version="2.3.0",javax.servlet.http;versi
on="2.3.0"
Bundle-ManifestVersion: 2

View File

@ -0,0 +1,28 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"/>
<title>About</title>
</head>
<body lang="EN-US">
<h2>About This Content</h2>
<p>January 30, 2007</p>
<h3>License</h3>
<p>The Eclipse Foundation makes available all content in this plug-in (&quot;Content&quot;). Unless otherwise
indicated below, the Content is provided to you under the terms and conditions of the
Eclipse Public License Version 1.0 (&quot;EPL&quot;). A copy of the EPL is available
at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
For purposes of the EPL, &quot;Program&quot; will mean the Content.</p>
<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is
being redistributed by another party (&quot;Redistributor&quot;) and different terms and conditions may
apply to your use of any object code in the Content. Check the Redistributor's license that was
provided with the Content. If no such license exists, contact the Redistributor. Unless otherwise
indicated below, the terms and conditions of the EPL still apply to any source code in the Content
and such source code may be obtained at <a href="http://www.eclipse.org">http://www.eclipse.org</a>.</p>
</body>
</html>

View File

@ -0,0 +1,4 @@
source.. = src/
output.. = bin/
bin.includes = META-INF/,\
.

View File

@ -0,0 +1,4 @@
##Source Bundle Localization
#Thu Jun 24 08:29:00 EDT 2010
bundleName=Servletbridge Source
providerName=Eclipse.org - Equinox

View File

@ -0,0 +1,89 @@
/*******************************************************************************
* Copyright (c) 2010 Angelo Zerr and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Angelo Zerr <angelo.zerr@gmail.com> - give the capability to use resources (JSP, HTML, Servlet...)
* from the Bridge webapp with HTTP Filter.
*******************************************************************************/
package org.eclipse.equinox.servletbridge;
import java.io.IOException;
import java.util.Enumeration;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* {@link BridgeServlet} which implements HTTP {@link Filter} to declare "BridgeServlet" as an HTTP Filter (see >=2.3 Servlet spec):
*
* <pre>
* <filter id="bridge">
* <filter-name>equinoxbridgeservlet</filter-name>
* <filter-class>org.eclipse.equinox.servletbridge.BridgeFilter</filter-class>
* </filter>
* ...
* <filter-mapping>
<filter-name>equinoxbridgeservlet</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
* </pre>
*
*/
public class BridgeFilter extends BridgeServlet implements Filter {
private static final long serialVersionUID = 1309373924501049438L;
private ServletConfigAdaptor servletConfig;
public void init(FilterConfig filterConfig) throws ServletException {
this.servletConfig = new ServletConfigAdaptor(filterConfig);
super.init();
}
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
// Call process class with FilterChain.
super.process(req, resp, chain);
}
public ServletConfig getServletConfig() {
return servletConfig;
}
/**
*
* Class which adapt {@link FilterConfig} to a {@link ServletConfig}.
*
*/
private static class ServletConfigAdaptor implements ServletConfig {
private FilterConfig filterConfig;
public ServletConfigAdaptor(FilterConfig filterConfig) {
this.filterConfig = filterConfig;
}
public String getInitParameter(String arg0) {
return filterConfig.getInitParameter(arg0);
}
public Enumeration getInitParameterNames() {
return filterConfig.getInitParameterNames();
}
public ServletContext getServletContext() {
return filterConfig.getServletContext();
}
public String getServletName() {
return filterConfig.getFilterName();
}
}
}

View File

@ -0,0 +1,279 @@
/*******************************************************************************
* Copyright (c) 2005, 2008 Cognos Incorporated, IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cognos Incorporated - initial API and implementation
* IBM Corporation - bug fixes and enhancements
* Angelo Zerr <angelo.zerr@gmail.com> - give the capability to use resources (JSP, HTML, Servlet...)
* from the Bridge webapp with HTTP Filter.
*******************************************************************************/
package org.eclipse.equinox.servletbridge;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* The BridgeServlet provides a means to bridge the servlet and OSGi
* runtimes. This class has 3 main responsibilities:
* 1) Control the lifecycle of the associated FrameworkLauncher in line with its own lifecycle
* 2) Provide a servlet "hook" that allows all servlet requests to be delegated to the registered servlet
* 3) Provide means to manually control the framework lifecycle
*/
public class BridgeServlet extends HttpServlet {
static final String INCLUDE_REQUEST_URI_ATTRIBUTE = "javax.servlet.include.request_uri"; //$NON-NLS-1$
static final String INCLUDE_SERVLET_PATH_ATTRIBUTE = "javax.servlet.include.servlet_path"; //$NON-NLS-1$
static final String INCLUDE_PATH_INFO_ATTRIBUTE = "javax.servlet.include.path_info"; //$NON-NLS-1$
private static final long serialVersionUID = 2825667412474494674L;
private static BridgeServlet instance;
private static HttpServlet servletDelegateInstance;
private HttpServlet delegate;
// true if current HttpServlet is an HTTP Filter and false otherwise.
private boolean delegateIsFilter;
private int delegateReferenceCount;
/**
* init() is called by the Servlet Container and used to instantiate the frameworkLauncher which MUST be an instance of FrameworkLauncher.
* After instantiating the framework init, deploy, and start are called.
*/
public void init() throws ServletException {
super.init();
setInstance(this);
}
/**
* destroy() is called by the Servlet Container and used to first stop and then destroy the framework.
*/
public void destroy() {
setInstance(null);
super.destroy();
}
/**
* service is called by the Servlet Container and will first determine if the request is a
* framework control and will otherwise try to delegate to the registered servlet delegate
*
*/
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
process(req, resp, null);
}
/**
* Search from OSGi registry the servlet, ressources... to executed according the path of the HTTP request. If no service are founded :
* <ul>
* <li>if {@link FilterChain} is not null : {@link FilterChain#doFilter(javax.servlet.ServletRequest, javax.servlet.ServletResponse)} is called.</li>
* <li>otherwise throw 404 error.</li>
* </ul>
*
* @param req
* @param resp
* @param chain
* @throws ServletException
* @throws IOException
*/
protected void process(HttpServletRequest req, HttpServletResponse resp, FilterChain chain) throws ServletException, IOException {
String pathInfo = getDispatchPathInfo(req, chain);
// Check if this is being handled by an extension mapping
if (pathInfo == null && isExtensionMapping(req.getServletPath()))
req = new ExtensionMappingRequest(req);
if (req.getAttribute(INCLUDE_REQUEST_URI_ATTRIBUTE) == null) {
} else {
String includePathInfo = (String) req.getAttribute(INCLUDE_PATH_INFO_ATTRIBUTE);
// Check if this is being handled by an extension mapping
if (includePathInfo == null || includePathInfo.length() == 0) {
String servletPath = (String) req.getAttribute(INCLUDE_SERVLET_PATH_ATTRIBUTE);
if (isExtensionMapping(servletPath))
req = new IncludedExtensionMappingRequest(req);
}
}
HttpServlet servletReference = acquireDelegateReference();
if (servletReference == null) {
// Cannot find the HttpServletService from OSGi registry services :
if (chain != null) {
// Delegate the HTTP request to the Web server container.
chain.doFilter(req, resp);
} else {
// Send HTTP 4040 Error.
resp.sendError(HttpServletResponse.SC_NOT_FOUND, "BridgeServlet: " + req.getRequestURI()); //$NON-NLS-1$
}
} else {
try {
if (delegateIsFilter && chain != null) {
((Filter) servletReference).doFilter(req, resp, chain);
} else {
servletReference.service(req, resp);
}
} finally {
releaseDelegateReference();
}
}
}
private boolean isExtensionMapping(String servletPath) {
if (servletPath == null)
return false;
String lastSegment = servletPath;
int lastSlash = servletPath.lastIndexOf('/');
if (lastSlash != -1)
lastSegment = servletPath.substring(lastSlash + 1);
return lastSegment.indexOf('.') != -1;
}
private static synchronized void setInstance(BridgeServlet servlet) {
if ((instance != null) && (servlet != null))
throw new IllegalStateException("instance already set"); //$NON-NLS-1$
instance = servlet;
if (instance == null)
servletDelegateInstance = null;
else if (servletDelegateInstance != null)
registerServletDelegate(servletDelegateInstance);
}
private synchronized void releaseDelegateReference() {
--delegateReferenceCount;
notifyAll();
}
private synchronized HttpServlet acquireDelegateReference() {
if (delegate != null)
++delegateReferenceCount;
return delegate;
}
/**
* registerServletDelegate is the hook method called from inside the OSGi runtime to register
* a servlet for which all future servlet calls will be delegated. If not null and no delegate
* is currently registered, init(ServletConfig) will be called on the servletDelegate before
* returning.
* @param servletDelegate - the servlet to register for delegation
*/
public static synchronized void registerServletDelegate(HttpServlet servletDelegate) {
if (instance == null) {
servletDelegateInstance = servletDelegate;
return;
}
servletDelegateInstance = null;
if (servletDelegate == null)
throw new NullPointerException("cannot register a null servlet delegate"); //$NON-NLS-1$
synchronized (instance) {
if (instance.delegate != null)
throw new IllegalStateException("A Servlet Proxy is already registered"); //$NON-NLS-1$
try {
// cache the flag if HttpServlet servlet delegate is an HTTP Filter.
instance.delegateIsFilter = (servletDelegate instanceof Filter);
// initialize the servlet delegate.
servletDelegate.init(instance.getServletConfig());
} catch (ServletException e) {
instance.getServletContext().log("Error initializing servlet delegate", e); //$NON-NLS-1$
return;
}
instance.delegate = servletDelegate;
}
}
/**
* unregisterServletDelegate is the hook method called from inside the OSGi runtime to unregister a delegate.
* If the servletDelegate matches the current registered delegate destroy() is called on the servletDelegate.
* destroy() will not be called until the delegate is finished servicing any previous requests.
* @param servletDelegate - the servlet to unregister
*/
public static synchronized void unregisterServletDelegate(HttpServlet servletDelegate) {
if (instance == null) {
// shutdown already
return;
}
synchronized (instance) {
if (instance.delegate == null)
throw new IllegalStateException("No servlet delegate is registered"); //$NON-NLS-1$
if (instance.delegate != servletDelegate)
throw new IllegalStateException("Servlet delegate does not match registered servlet delegate"); //$NON-NLS-1$
HttpServlet oldProxy = instance.delegate;
instance.delegate = null;
instance.delegateIsFilter = false;
while (instance.delegateReferenceCount != 0) {
try {
instance.wait();
} catch (InterruptedException e) {
// keep waiting for all requests to finish
}
}
oldProxy.destroy();
}
}
static class ExtensionMappingRequest extends HttpServletRequestWrapper {
public ExtensionMappingRequest(HttpServletRequest req) {
super(req);
}
public String getPathInfo() {
return super.getServletPath();
}
public String getServletPath() {
return ""; //$NON-NLS-1$
}
}
static class IncludedExtensionMappingRequest extends HttpServletRequestWrapper {
public IncludedExtensionMappingRequest(HttpServletRequest req) {
super(req);
}
public Object getAttribute(String attributeName) {
if (attributeName.equals(INCLUDE_SERVLET_PATH_ATTRIBUTE)) {
return ""; //$NON-NLS-1$
} else if (attributeName.equals(INCLUDE_PATH_INFO_ATTRIBUTE)) {
String servletPath = (String) super.getAttribute(INCLUDE_SERVLET_PATH_ATTRIBUTE);
return servletPath;
}
return super.getAttribute(attributeName);
}
}
/**
* Returns the path info of the HTTP request.
*
* @param req
* @param chain
* @return the path info of the HTTP request.
*/
private static String getDispatchPathInfo(HttpServletRequest req, FilterChain chain) {
// if (req.getAttribute(INCLUDE_REQUEST_URI_ATTRIBUTE) != null)
// return (String) req.getAttribute(INCLUDE_PATH_INFO_ATTRIBUTE);
String pathInfo = req.getPathInfo();
if (pathInfo != null) {
return pathInfo;
}
if (chain == null) {
return null;
}
// HTTP Filter case, pathInfo is null, compute it by using contextPath and requestURI
String contextPath = req.getContextPath();
String requestURI = req.getRequestURI();
return requestURI.substring(contextPath.length(), requestURI.length());
}
}

View File

@ -0,0 +1,391 @@
/*******************************************************************************
* Copyright (c) 2008, 2009 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
/**
* The java.net.URLClassLoader class allows one to load resources from arbitrary URLs and in particular is optimized to handle
* "jar" URLs. Unfortunately for jar files this optimization ends up holding the file open which ultimately prevents the file from
* being deleted or update until the VM is shutdown.
*
* The CloseableURLClassLoader is meant to replace the URLClassLoader and provides an additional method to allow one to "close" any
* resources left open. In the current version the CloseableURLClassLoader will only ensure the closing of jar file resources. The
* jar handling behavior in this class will also provides a construct to allow one to turn off jar file verification in performance
* sensitive situations where the verification us not necessary.
*
* also see https://bugs.eclipse.org/bugs/show_bug.cgi?id=190279
*/
package org.eclipse.equinox.servletbridge;
import java.io.*;
import java.net.*;
import java.security.*;
import java.util.*;
import java.util.jar.*;
import java.util.jar.Attributes.Name;
public class CloseableURLClassLoader extends URLClassLoader {
static final String DOT_CLASS = ".class"; //$NON-NLS-1$
static final String BANG_SLASH = "!/"; //$NON-NLS-1$
static final String JAR = "jar"; //$NON-NLS-1$
// @GuardedBy("loaders")
final ArrayList loaders = new ArrayList(); // package private to avoid synthetic access.
// @GuardedBy("loaders")
private final ArrayList loaderURLs = new ArrayList(); // note: protected by loaders
// @GuardedBy("loaders")
boolean closed = false; // note: protected by loaders, package private to avoid synthetic access.
private final AccessControlContext context;
private final boolean verifyJars;
private static class CloseableJarURLConnection extends JarURLConnection {
private final JarFile jarFile;
// @GuardedBy("this")
private JarEntry entry;
public CloseableJarURLConnection(URL url, JarFile jarFile) throws MalformedURLException {
super(url);
this.jarFile = jarFile;
}
public void connect() throws IOException {
internalGetEntry();
}
private synchronized JarEntry internalGetEntry() throws IOException {
if (entry != null)
return entry;
entry = jarFile.getJarEntry(getEntryName());
if (entry == null)
throw new FileNotFoundException(getEntryName());
return entry;
}
public InputStream getInputStream() throws IOException {
return jarFile.getInputStream(internalGetEntry());
}
/**
* @throws IOException
* Documented to avoid warning
*/
public JarFile getJarFile() throws IOException {
return jarFile;
}
public JarEntry getJarEntry() throws IOException {
return internalGetEntry();
}
}
private static class CloseableJarURLStreamHandler extends URLStreamHandler {
private final JarFile jarFile;
public CloseableJarURLStreamHandler(JarFile jarFile) {
this.jarFile = jarFile;
}
protected URLConnection openConnection(URL u) throws IOException {
return new CloseableJarURLConnection(u, jarFile);
}
protected void parseURL(URL u, String spec, int start, int limit) {
setURL(u, JAR, null, 0, null, null, spec.substring(start, limit), null, null);
}
}
private static class CloseableJarFileLoader {
private final JarFile jarFile;
private final Manifest manifest;
private final CloseableJarURLStreamHandler jarURLStreamHandler;
private final String jarFileURLPrefixString;
public CloseableJarFileLoader(File file, boolean verify) throws IOException {
this.jarFile = new JarFile(file, verify);
this.manifest = jarFile.getManifest();
this.jarURLStreamHandler = new CloseableJarURLStreamHandler(jarFile);
this.jarFileURLPrefixString = file.toURL().toString() + BANG_SLASH;
}
public URL getURL(String name) {
if (jarFile.getEntry(name) != null)
try {
return new URL(JAR, null, -1, jarFileURLPrefixString + name, jarURLStreamHandler);
} catch (MalformedURLException e) {
// ignore
}
return null;
}
public Manifest getManifest() {
return manifest;
}
public void close() {
try {
jarFile.close();
} catch (IOException e) {
// ignore
}
}
}
/**
* @param urls the array of URLs to use for loading resources
* @see URLClassLoader
*/
public CloseableURLClassLoader(URL[] urls) {
this(urls, ClassLoader.getSystemClassLoader(), true);
}
/**
* @param urls the URLs from which to load classes and resources
* @param parent the parent class loader used for delegation
* @see URLClassLoader
*/
public CloseableURLClassLoader(URL[] urls, ClassLoader parent) {
this(excludeFileJarURLS(urls), parent, true);
}
/**
* @param urls the URLs from which to load classes and resources
* @param parent the parent class loader used for delegation
* @param verifyJars flag to determine if jar file verification should be performed
* @see URLClassLoader
*/
public CloseableURLClassLoader(URL[] urls, ClassLoader parent, boolean verifyJars) {
super(excludeFileJarURLS(urls), parent);
this.context = AccessController.getContext();
this.verifyJars = verifyJars;
for (int i = 0; i < urls.length; i++) {
if (isFileJarURL(urls[i])) {
loaderURLs.add(urls[i]);
safeAddLoader(urls[i]);
}
}
}
// @GuardedBy("loaders")
private void safeAddLoader(URL url) {
String path = url.getPath();
File file = new File(path);
if (file.exists()) {
try {
loaders.add(new CloseableJarFileLoader(file, verifyJars));
} catch (IOException e) {
// ignore
}
}
}
private static URL[] excludeFileJarURLS(URL[] urls) {
ArrayList urlList = new ArrayList();
for (int i = 0; i < urls.length; i++) {
if (!isFileJarURL(urls[i]))
urlList.add(urls[i]);
}
return (URL[]) urlList.toArray(new URL[urlList.size()]);
}
private static boolean isFileJarURL(URL url) {
if (!url.getProtocol().equals("file")) //$NON-NLS-1$
return false;
String path = url.getPath();
if (path != null && path.endsWith("/")) //$NON-NLS-1$
return false;
return true;
}
/* (non-Javadoc)
* @see java.net.URLClassLoader#findClass(java.lang.String)
*/
protected Class findClass(final String name) throws ClassNotFoundException {
try {
Class clazz = (Class) AccessController.doPrivileged(new PrivilegedExceptionAction() {
public Object run() throws ClassNotFoundException {
String resourcePath = name.replace('.', '/') + DOT_CLASS;
CloseableJarFileLoader loader = null;
URL resourceURL = null;
synchronized (loaders) {
if (closed)
return null;
for (Iterator iterator = loaders.iterator(); iterator.hasNext();) {
loader = (CloseableJarFileLoader) iterator.next();
resourceURL = loader.getURL(resourcePath);
if (resourceURL != null)
break;
}
}
if (resourceURL != null) {
try {
return defineClass(name, resourceURL, loader.getManifest());
} catch (IOException e) {
throw new ClassNotFoundException(name, e);
}
}
return null;
}
}, context);
if (clazz != null)
return clazz;
} catch (PrivilegedActionException e) {
throw (ClassNotFoundException) e.getException();
}
return super.findClass(name);
}
// package private to avoid synthetic access.
Class defineClass(String name, URL resourceURL, Manifest manifest) throws IOException {
JarURLConnection connection = (JarURLConnection) resourceURL.openConnection();
int lastDot = name.lastIndexOf('.');
if (lastDot != -1) {
String packageName = name.substring(0, lastDot + 1);
Package pkg = getPackage(packageName);
if (pkg != null) {
checkForSealedPackage(pkg, packageName, manifest, connection.getJarFileURL());
} else {
definePackage(packageName, manifest, connection.getJarFileURL());
}
}
JarEntry entry = connection.getJarEntry();
byte[] bytes = new byte[(int) entry.getSize()];
DataInputStream is = null;
try {
is = new DataInputStream(connection.getInputStream());
is.readFully(bytes, 0, bytes.length);
CodeSource cs = new CodeSource(connection.getJarFileURL(), entry.getCertificates());
return defineClass(name, bytes, 0, bytes.length, cs);
} finally {
if (is != null)
try {
is.close();
} catch (IOException e) {
// ignore
}
}
}
private void checkForSealedPackage(Package pkg, String packageName, Manifest manifest, URL jarFileURL) {
if (pkg.isSealed() && !pkg.isSealed(jarFileURL))
throw new SecurityException("The package '" + packageName + "' was previously loaded and is already sealed."); //$NON-NLS-1$ //$NON-NLS-2$
String entryPath = packageName.replace('.', '/') + "/"; //$NON-NLS-1$
Attributes entryAttributes = manifest.getAttributes(entryPath);
String sealed = null;
if (entryAttributes != null)
sealed = entryAttributes.getValue(Name.SEALED);
if (sealed == null) {
Attributes mainAttributes = manifest.getMainAttributes();
if (mainAttributes != null)
sealed = mainAttributes.getValue(Name.SEALED);
}
if (Boolean.valueOf(sealed).booleanValue())
throw new SecurityException("The package '" + packageName + "' was previously loaded unsealed. Cannot seal package."); //$NON-NLS-1$ //$NON-NLS-2$
}
/* (non-Javadoc)
* @see java.net.URLClassLoader#findResource(java.lang.String)
*/
public URL findResource(final String name) {
URL url = (URL) AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
synchronized (loaders) {
if (closed)
return null;
for (Iterator iterator = loaders.iterator(); iterator.hasNext();) {
CloseableJarFileLoader loader = (CloseableJarFileLoader) iterator.next();
URL resourceURL = loader.getURL(name);
if (resourceURL != null)
return resourceURL;
}
}
return null;
}
}, context);
if (url != null)
return url;
return super.findResource(name);
}
/* (non-Javadoc)
* @see java.net.URLClassLoader#findResources(java.lang.String)
*/
public Enumeration findResources(final String name) throws IOException {
final List resources = new ArrayList();
AccessController.doPrivileged(new PrivilegedAction() {
public Object run() {
synchronized (loaders) {
if (closed)
return null;
for (Iterator iterator = loaders.iterator(); iterator.hasNext();) {
CloseableJarFileLoader loader = (CloseableJarFileLoader) iterator.next();
URL resourceURL = loader.getURL(name);
if (resourceURL != null)
resources.add(resourceURL);
}
}
return null;
}
}, context);
Enumeration e = super.findResources(name);
while (e.hasMoreElements())
resources.add(e.nextElement());
return Collections.enumeration(resources);
}
/**
* The "close" method is called when the class loader is no longer needed and we should close any open resources.
* In particular this method will close the jar files associated with this class loader.
*/
public void close() {
synchronized (loaders) {
if (closed)
return;
for (Iterator iterator = loaders.iterator(); iterator.hasNext();) {
CloseableJarFileLoader loader = (CloseableJarFileLoader) iterator.next();
loader.close();
}
closed = true;
}
}
/* (non-Javadoc)
* @see java.net.URLClassLoader#addURL(java.net.URL)
*/
protected void addURL(URL url) {
synchronized (loaders) {
if (isFileJarURL(url)) {
if (closed)
throw new IllegalStateException("Cannot add url. CloseableURLClassLoader is closed."); //$NON-NLS-1$
loaderURLs.add(url);
safeAddLoader(url);
return;
}
}
super.addURL(url);
}
/* (non-Javadoc)
* @see java.net.URLClassLoader#getURLs()
*/
public URL[] getURLs() {
List result = new ArrayList();
synchronized (loaders) {
result.addAll(loaderURLs);
}
result.addAll(Arrays.asList(super.getURLs()));
return (URL[]) result.toArray(new URL[result.size()]);
}
}