From f830e2c4692200e45805ae9e2a024b0839328a15 Mon Sep 17 00:00:00 2001 From: Heng Sin Low Date: Fri, 11 Jan 2013 11:49:46 +0800 Subject: [PATCH] IDEMPIERE-546 Integrate Apache Felix Web Console. Accessible at osgi/system/console using the administrator login. --- lib/artifacts.xml | 25 +- lib/content.xml | 130 +++++++++- .../http/servlet/internal/Activator.java | 55 ++--- .../servlet/internal/HttpServiceProxy.java | 223 ++++++++++++++++++ .../internal/HttpServiceProxyFactory.java | 89 +++++++ .../http/servlet/internal/ProxyServlet.java | 7 + .../servletbridge/internal/Activator.java | 8 - .../META-INF/MANIFEST.MF | 5 +- .../equinox/servletbridge/BridgeServlet.java | 119 ++-------- org.adempiere.server-feature/feature.xml | 11 + org.adempiere.server-feature/server.product | 8 +- .../server.product.functionaltest.launch | 6 +- .../server.product.launch | 6 +- org.adempiere.webstore.servlet/plugin.xml | 72 ++++-- org.adempiere.webstore/META-INF/MANIFEST.MF | 5 +- org.adempiere.webstore/WEB-INF/web.xml | 4 +- org.adempiere.webstore/build.properties | 5 +- org.adempiere.webstore/plugin.xml | 12 + .../src/org/adempiere/webstore/Activator.java | 39 +++ .../webstore/DefaultHttpContext.java | 33 +++ .../.project | 17 ++ .../build.properties | 1 + .../feature.xml | 47 ++++ org.idempiere.felix.webconsole/.classpath | 7 + org.idempiere.felix.webconsole/.project | 33 +++ .../.settings/org.eclipse.jdt.core.prefs | 7 + .../.settings/org.eclipse.pde.core.prefs | 3 + .../META-INF/MANIFEST.MF | 29 +++ .../OSGI-INF/securityprovider.xml | 7 + .../WEB-INF/web.xml | 37 +++ .../build.properties | 7 + .../idempiere/felix/webconsole/Activator.java | 30 +++ .../webconsole/SecurityProviderImpl.java | 48 ++++ org.zkoss.zk.library/META-INF/MANIFEST.MF | 18 +- 34 files changed, 949 insertions(+), 204 deletions(-) create mode 100644 org.adempiere.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceProxy.java create mode 100644 org.adempiere.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceProxyFactory.java create mode 100644 org.adempiere.webstore/plugin.xml create mode 100644 org.adempiere.webstore/src/org/adempiere/webstore/Activator.java create mode 100644 org.adempiere.webstore/src/org/adempiere/webstore/DefaultHttpContext.java create mode 100644 org.idempiere.felix.webconsole-feature/.project create mode 100644 org.idempiere.felix.webconsole-feature/build.properties create mode 100644 org.idempiere.felix.webconsole-feature/feature.xml create mode 100644 org.idempiere.felix.webconsole/.classpath create mode 100644 org.idempiere.felix.webconsole/.project create mode 100644 org.idempiere.felix.webconsole/.settings/org.eclipse.jdt.core.prefs create mode 100644 org.idempiere.felix.webconsole/.settings/org.eclipse.pde.core.prefs create mode 100644 org.idempiere.felix.webconsole/META-INF/MANIFEST.MF create mode 100644 org.idempiere.felix.webconsole/OSGI-INF/securityprovider.xml create mode 100644 org.idempiere.felix.webconsole/WEB-INF/web.xml create mode 100644 org.idempiere.felix.webconsole/build.properties create mode 100644 org.idempiere.felix.webconsole/src/org/idempiere/felix/webconsole/Activator.java create mode 100644 org.idempiere.felix.webconsole/src/org/idempiere/felix/webconsole/SecurityProviderImpl.java diff --git a/lib/artifacts.xml b/lib/artifacts.xml index e71089ceb5..b24c12ab67 100644 --- a/lib/artifacts.xml +++ b/lib/artifacts.xml @@ -2,7 +2,7 @@ - + @@ -10,7 +10,14 @@ - + + + + + + + + @@ -18,6 +25,20 @@ + + + + + + + + + + + + + + diff --git a/lib/content.xml b/lib/content.xml index e78a905931..a645b8d285 100644 --- a/lib/content.xml +++ b/lib/content.xml @@ -2,10 +2,10 @@ - + - + @@ -57,6 +57,132 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Bundle-SymbolicName: org.apache.felix.webconsole Bundle-Version: 4.0.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Bundle-SymbolicName: org.apache.felix.webconsole.plugins.packageadmin Bundle-Version: 1.0.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Bundle-SymbolicName: org.apache.felix.webconsole.plugins.memoryusage Bundle-Version: 1.0.4 + + + + diff --git a/org.adempiere.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/Activator.java b/org.adempiere.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/Activator.java index db2d4931ea..bb51de7b5b 100644 --- a/org.adempiere.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/Activator.java +++ b/org.adempiere.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/Activator.java @@ -13,7 +13,6 @@ 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; @@ -25,52 +24,22 @@ public class Activator implements BundleActivator { 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>(); + private static ServiceRegistration serviceRegistration; public void start(BundleContext bundleContext) throws Exception { - startHttpServiceProxy(bundleContext); + context = bundleContext; + serviceRegistration = 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 = 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); + private static synchronized ServiceRegistration startHttpServiceProxy(BundleContext bundleContext) { + HttpServiceProxyFactory factory = new HttpServiceProxyFactory(); + 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); @@ -79,10 +48,16 @@ public class Activator implements BundleActivator { return context.registerService(HTTP_SERVICES_CLASSES, factory, serviceProperties); } + + private static synchronized void stopHttpServiceProxy(BundleContext bundleContext) { + serviceRegistration.unregister(); + } + static synchronized void addProxyServlet(ProxyServlet proxyServlet) { + HttpServiceProxyFactory.registerServletDelegate(proxyServlet.getHttpContext(), proxyServlet); + } +// static synchronized void removeProxyServlet(ProxyServlet proxyServlet) { - ServiceRegistration registration = serviceRegistrations.remove(proxyServlet); - if (registration != null) - registration.unregister(); + HttpServiceProxyFactory.unregisterServletDelegate(proxyServlet); } } diff --git a/org.adempiere.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceProxy.java b/org.adempiere.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceProxy.java new file mode 100644 index 0000000000..f156fdead9 --- /dev/null +++ b/org.adempiere.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceProxy.java @@ -0,0 +1,223 @@ +/****************************************************************************** + * Copyright (C) 2013 Heng Sin Low * + * Copyright (C) 2013 Trek Global * + * This program is free software; you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program is distributed in the hope * + * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the GNU General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + *****************************************************************************/ +package org.eclipse.equinox.http.servlet.internal; + +import java.util.ArrayList; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import javax.servlet.Filter; +import javax.servlet.Servlet; +import javax.servlet.ServletException; + +import org.eclipse.equinox.http.servlet.ExtendedHttpService; +import org.osgi.framework.Bundle; +import org.osgi.service.http.HttpContext; +import org.osgi.service.http.HttpService; +import org.osgi.service.http.NamespaceException; + +/** + * @author hengsin + * + */ +public class HttpServiceProxy implements HttpService, ExtendedHttpService { + + private Bundle bundle; + + private Map filterMap = new HashMap(); + private HttpServiceProxyFactory factory; + private List filters = new ArrayList(); + private List servlets = new ArrayList(); + private List resources = new ArrayList(); + + public HttpServiceProxy(Bundle bundle, HttpServiceProxyFactory httpServiceProxyFactory) { + this.bundle = bundle; + this.factory = httpServiceProxyFactory; + } + + /* (non-Javadoc) + * @see org.eclipse.equinox.http.servlet.ExtendedHttpService#registerFilter(java.lang.String, javax.servlet.Filter, java.util.Dictionary, org.osgi.service.http.HttpContext) + */ + @Override + public void registerFilter(String alias, Filter filter, + Dictionary initparams, HttpContext context) + throws ServletException, NamespaceException { + String httpContextClass = context != null ? context.getClass().getName() : DefaultHttpContext.class.getName(); + HttpService delegate = factory.getHttpServiceDelegate(bundle, httpContextClass); + if (delegate != null && delegate instanceof ExtendedHttpService) { + ((ExtendedHttpService)delegate).registerFilter(alias, filter, initparams, context); + filterMap.put(filter, (ExtendedHttpService) delegate); + } else { + filters.add(new FilterEntry(alias, filter, initparams, context)); + } + } + + /* (non-Javadoc) + * @see org.eclipse.equinox.http.servlet.ExtendedHttpService#unregisterFilter(javax.servlet.Filter) + */ + @Override + public void unregisterFilter(Filter filter) { + ExtendedHttpService service = filterMap.get(filter); + if (service != null) { + service.unregisterFilter(filter); + } + } + + /* (non-Javadoc) + * @see org.osgi.service.http.HttpService#registerServlet(java.lang.String, javax.servlet.Servlet, java.util.Dictionary, org.osgi.service.http.HttpContext) + */ + @SuppressWarnings("rawtypes") + @Override + public void registerServlet(String alias, Servlet servlet, + Dictionary initparams, HttpContext context) + throws ServletException, NamespaceException { + String httpContextClass = context != null ? context.getClass().getName() : DefaultHttpContext.class.getName(); + HttpService delegate = factory.getHttpServiceDelegate(bundle, httpContextClass); + if (delegate != null ) { + delegate.registerServlet(alias, servlet, initparams, context); + } else { + servlets.add(new ServletEntry(alias, servlet, initparams, context)); + } + } + + /* (non-Javadoc) + * @see org.osgi.service.http.HttpService#registerResources(java.lang.String, java.lang.String, org.osgi.service.http.HttpContext) + */ + @Override + public void registerResources(String alias, String name, HttpContext context) + throws NamespaceException { + String httpContextClass = context != null ? context.getClass().getName() : DefaultHttpContext.class.getName(); + HttpService delegate = factory.getHttpServiceDelegate(bundle, httpContextClass); + if (delegate != null ) { + delegate.registerResources(alias, name, context); + } else { + resources.add(new ResourceEntry(alias, name, context)); + } + } + + /** + * process registration that happens before the start of http service delegate + * @param httpContext + * @throws ServletException + * @throws NamespaceException + */ + protected void processPendingRegistration(String httpContext) throws ServletException, NamespaceException { + if (!filters.isEmpty()) { + List list = new ArrayList(); + list.addAll(filters); + filters.clear(); + for (FilterEntry e : list) { + if (e.getHttpContext().equals(httpContext)) { + registerFilter(e.alias, e.filter, e.initparams, e.context); + } else { + filters.add(e); + } + } + } + + if (!servlets.isEmpty()) { + List list = new ArrayList(); + list.addAll(servlets); + servlets.clear(); + for (ServletEntry e : list) { + if (e.getHttpContext().equals(httpContext)) { + registerServlet(e.alias, e.servlet, e.initparams, e.context); + } else { + servlets.add(e); + } + } + } + + if (!resources.isEmpty()) { + List list = new ArrayList(); + list.addAll(resources); + resources.clear(); + for (ResourceEntry e : list) { + if (e.getHttpContext().equals(httpContext)) { + registerResources(e.alias, e.name, e.context); + } else { + resources.add(e); + } + } + } + } + + /* (non-Javadoc) + * @see org.osgi.service.http.HttpService#unregister(java.lang.String) + */ + @Override + public void unregister(String alias) { + } + + /* (non-Javadoc) + * @see org.osgi.service.http.HttpService#createDefaultHttpContext() + */ + @Override + public HttpContext createDefaultHttpContext() { + return new DefaultHttpContext(bundle); + } + + class Entry { + protected HttpContext context; + + protected Entry(HttpContext context) { + this.context = context; + } + + protected String getHttpContext() { + return context != null ? context.getClass().getName() : DefaultHttpContext.class.getName(); + } + } + + class FilterEntry extends Entry { + protected String alias; + protected Filter filter; + protected Dictionary initparams; + + protected FilterEntry(String alias, Filter filter, + Dictionary initparams, HttpContext context) { + super(context); + this.alias = alias; + this.filter = filter; + this.initparams = initparams; + } + } + + class ServletEntry extends Entry { + protected String alias; + protected Servlet servlet; + protected Dictionary initparams; + protected ServletEntry(String alias, Servlet servlet, + Dictionary initparams, HttpContext context) { + super(context); + this.alias = alias; + this.servlet = servlet; + this.initparams = initparams; + this.context = context; + } + } + + class ResourceEntry extends Entry { + protected String alias; + protected String name; + + protected ResourceEntry(String alias, String name, HttpContext context) { + super(context); + this.alias = alias; + this.name = name; + } + } +} diff --git a/org.adempiere.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceProxyFactory.java b/org.adempiere.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceProxyFactory.java new file mode 100644 index 0000000000..937dd9d112 --- /dev/null +++ b/org.adempiere.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/HttpServiceProxyFactory.java @@ -0,0 +1,89 @@ +/****************************************************************************** + * Copyright (C) 2013 Heng Sin Low * + * Copyright (C) 2013 Trek Global * + * This program is free software; you can redistribute it and/or modify it * + * under the terms version 2 of the GNU General Public License as published * + * by the Free Software Foundation. This program is distributed in the hope * + * that it will be useful, but WITHOUT ANY WARRANTY; without even the implied * + * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * + * See the GNU General Public License for more details. * + * You should have received a copy of the GNU General Public License along * + * with this program; if not, write to the Free Software Foundation, Inc., * + * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * + *****************************************************************************/ +package org.eclipse.equinox.http.servlet.internal; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.osgi.framework.Bundle; +import org.osgi.framework.ServiceFactory; +import org.osgi.framework.ServiceRegistration; +import org.osgi.service.http.HttpService; + +/** + * + * @author hengsin + * + */ +public class HttpServiceProxyFactory implements ServiceFactory { + + private static Map delegateMap = new HashMap(); + private static List proxies = new ArrayList(); + + @Override + public HttpService getService(Bundle bundle, + ServiceRegistration registration) { + HttpServiceProxy service = new HttpServiceProxy(bundle, this); + proxies.add(service); + return service; + } + + @Override + public void ungetService(Bundle bundle, + ServiceRegistration registration, HttpService service) { + proxies.remove(service); + } + + /** + * + * @param httpContext + * @param proxy + * @return the previous value associated with the key or null if there was no mapping for key + */ + public static synchronized ProxyServlet registerServletDelegate(String httpContext, ProxyServlet proxy) { + ProxyServlet old = delegateMap.put(httpContext, proxy); + for(HttpServiceProxy p : proxies) { + try { + p.processPendingRegistration(httpContext); + } catch (Exception e) { + } + } + return old; + } + + /** + * @param proxy + * @return the proxy if it have been register previously + */ + public static synchronized ProxyServlet unregisterServletDelegate(ProxyServlet proxy) { + return delegateMap.remove(proxy.getHttpContext()); + } + + /** + * + * @param bundle + * @param httpContext + * @return http service delegate for httpContext ( if any ) + */ + public HttpService getHttpServiceDelegate(Bundle bundle, String httpContext) { + ProxyServlet proxy = delegateMap.get(httpContext); + if (proxy != null) + return new HttpServiceImpl(bundle, proxy); + else + return null; + } + +} diff --git a/org.adempiere.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/ProxyServlet.java b/org.adempiere.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/ProxyServlet.java index 308581195a..9b5bc22eff 100644 --- a/org.adempiere.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/ProxyServlet.java +++ b/org.adempiere.eclipse.equinox.http.servlet/src/org/eclipse/equinox/http/servlet/internal/ProxyServlet.java @@ -35,10 +35,14 @@ public class ProxyServlet extends HttpServlet implements Filter { private Map filterRegistrations = new HashMap(); //filter --> filter registration; private ProxyContext proxyContext; + private String httpContext; public void init(ServletConfig config) throws ServletException { super.init(config); proxyContext = new ProxyContext(config.getServletContext()); + httpContext = config.getInitParameter("HttpContext.ClassName"); + if (httpContext == null) + httpContext = DefaultHttpContext.class.getName(); Activator.addProxyServlet(this); } @@ -317,4 +321,7 @@ public class ProxyServlet extends HttpServlet implements Filter { } + public String getHttpContext() { + return httpContext; + } } diff --git a/org.adempiere.eclipse.equinox.http.servletbridge/src/org/eclipse/equinox/http/servletbridge/internal/Activator.java b/org.adempiere.eclipse.equinox.http.servletbridge/src/org/eclipse/equinox/http/servletbridge/internal/Activator.java index 97d35f34f8..1173751801 100644 --- a/org.adempiere.eclipse.equinox.http.servletbridge/src/org/eclipse/equinox/http/servletbridge/internal/Activator.java +++ b/org.adempiere.eclipse.equinox.http.servletbridge/src/org/eclipse/equinox/http/servletbridge/internal/Activator.java @@ -11,22 +11,14 @@ *******************************************************************************/ 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; } } diff --git a/org.adempiere.eclipse.equinox.servletbridge/META-INF/MANIFEST.MF b/org.adempiere.eclipse.equinox.servletbridge/META-INF/MANIFEST.MF index 03059fd20d..e9cb5247fb 100644 --- a/org.adempiere.eclipse.equinox.servletbridge/META-INF/MANIFEST.MF +++ b/org.adempiere.eclipse.equinox.servletbridge/META-INF/MANIFEST.MF @@ -9,6 +9,7 @@ Eclipse-SourceReferences: scm:cvs:pserver:dev.eclipse.org:/cvsroot/rt: 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" +Import-Package: javax.servlet;version="2.3.0", + javax.servlet.http;version="2.3.0", + org.eclipse.equinox.http.servlet;version="1.1.0" Bundle-ManifestVersion: 2 diff --git a/org.adempiere.eclipse.equinox.servletbridge/src/org/eclipse/equinox/servletbridge/BridgeServlet.java b/org.adempiere.eclipse.equinox.servletbridge/src/org/eclipse/equinox/servletbridge/BridgeServlet.java index f66b1dcc74..61388768f1 100644 --- a/org.adempiere.eclipse.equinox.servletbridge/src/org/eclipse/equinox/servletbridge/BridgeServlet.java +++ b/org.adempiere.eclipse.equinox.servletbridge/src/org/eclipse/equinox/servletbridge/BridgeServlet.java @@ -17,6 +17,8 @@ import java.io.IOException; import javax.servlet.*; import javax.servlet.http.*; +import org.eclipse.equinox.http.servlet.HttpServiceServlet; + /** * The BridgeServlet provides a means to bridge the servlet and OSGi * runtimes. This class has 3 main responsibilities: @@ -31,12 +33,9 @@ public class BridgeServlet extends HttpServlet { 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 static boolean delegateIsFilter; - private int delegateReferenceCount; + private boolean delegateIsFilter; /** * init() is called by the Servlet Container and used to instantiate the frameworkLauncher which MUST be an instance of FrameworkLauncher. @@ -44,14 +43,17 @@ public class BridgeServlet extends HttpServlet { */ public void init() throws ServletException { super.init(); - setInstance(this); + initDelegate(); } /** * destroy() is called by the Servlet Container and used to first stop and then destroy the framework. */ public void destroy() { - setInstance(null); + try { + initDelegate(); + } catch (ServletException e) { + } super.destroy(); } @@ -94,7 +96,7 @@ public class BridgeServlet extends HttpServlet { } } - HttpServlet servletReference = acquireDelegateReference(); + HttpServlet servletReference = delegate; if (servletReference == null) { // Cannot find the HttpServletService from OSGi registry services : if (chain != null) { @@ -106,14 +108,10 @@ public class BridgeServlet extends HttpServlet { 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(); + if (delegateIsFilter && chain != null) { + ((Filter) servletReference).doFilter(req, resp, chain); + } else { + servletReference.service(req, resp); } } } @@ -130,93 +128,10 @@ public class BridgeServlet extends HttpServlet { 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. - BridgeServlet.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; - BridgeServlet.delegateIsFilter = false; - while (instance.delegateReferenceCount != 0) { - try { - instance.wait(); - } catch (InterruptedException e) { - // keep waiting for all requests to finish - } - } - oldProxy.destroy(); - } + private void initDelegate() throws ServletException { + delegate = new HttpServiceServlet(); + delegate.init(getServletConfig()); + delegateIsFilter = (delegate instanceof Filter); } static class ExtensionMappingRequest extends HttpServletRequestWrapper { diff --git a/org.adempiere.server-feature/feature.xml b/org.adempiere.server-feature/feature.xml index 164f51f448..ea349c3b30 100644 --- a/org.adempiere.server-feature/feature.xml +++ b/org.adempiere.server-feature/feature.xml @@ -34,6 +34,10 @@ id="org.eclipse.gemini.web.feature" version="0.0.0"/> + + @@ -322,4 +326,11 @@ version="1.4.5" unpack="false"/> + + diff --git a/org.adempiere.server-feature/server.product b/org.adempiere.server-feature/server.product index 02556feaf6..43e285d515 100644 --- a/org.adempiere.server-feature/server.product +++ b/org.adempiere.server-feature/server.product @@ -35,9 +35,9 @@ - - - + + + @@ -53,6 +53,8 @@ + + diff --git a/org.adempiere.server-feature/server.product.functionaltest.launch b/org.adempiere.server-feature/server.product.functionaltest.launch index 63c408a4fc..bacc65cd7f 100644 --- a/org.adempiere.server-feature/server.product.functionaltest.launch +++ b/org.adempiere.server-feature/server.product.functionaltest.launch @@ -10,7 +10,7 @@ - + @@ -21,8 +21,8 @@ - - + + diff --git a/org.adempiere.server-feature/server.product.launch b/org.adempiere.server-feature/server.product.launch index f108c0b763..5466fcdaf2 100644 --- a/org.adempiere.server-feature/server.product.launch +++ b/org.adempiere.server-feature/server.product.launch @@ -16,13 +16,13 @@ - + - - + + diff --git a/org.adempiere.webstore.servlet/plugin.xml b/org.adempiere.webstore.servlet/plugin.xml index 34304cad87..70b4c6d3e4 100644 --- a/org.adempiere.webstore.servlet/plugin.xml +++ b/org.adempiere.webstore.servlet/plugin.xml @@ -3,100 +3,120 @@ - - + class="org.compiere.wstore.AdvertisementServlet" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.AssetServlet" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.BasketServlet" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.CheckOutServlet" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.Click" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.ExpenseServlet" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.Counter" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.InfoServlet" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.InvoiceServlet" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.LocationServlet" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.LoginServlet" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.NoteServlet" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.OrderServlet" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.PaymentServlet" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.ProductServlet" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.RegistrationServlet" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.RequestServlet" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.RfQServlet" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.SearchServlet" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.UpdateServlet" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.WorkflowServlet" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.EMailServlet" + httpcontextId="org.adempiere.webstore"> + class="org.compiere.wstore.IssueReportServlet" + httpcontextId="org.adempiere.webstore"> diff --git a/org.adempiere.webstore/META-INF/MANIFEST.MF b/org.adempiere.webstore/META-INF/MANIFEST.MF index eae46b4324..220b0b5ecc 100644 --- a/org.adempiere.webstore/META-INF/MANIFEST.MF +++ b/org.adempiere.webstore/META-INF/MANIFEST.MF @@ -49,4 +49,7 @@ Import-Package: javax.servlet;version="2.5.0", org.apache.taglibs.standard.tlv;version="1.1.2", org.eclipse.equinox.http.registry;version="1.0.0", org.eclipse.equinox.http.servlet;version="1.1.0", - org.eclipse.equinox.servletbridge;version="1.1.0" + org.eclipse.equinox.servletbridge;version="1.1.0", + org.osgi.framework;version="1.6.0", + org.osgi.service.http;version="1.2.1" +Bundle-Activator: org.adempiere.webstore.Activator diff --git a/org.adempiere.webstore/WEB-INF/web.xml b/org.adempiere.webstore/WEB-INF/web.xml index 4798df85ae..bb504be561 100644 --- a/org.adempiere.webstore/WEB-INF/web.xml +++ b/org.adempiere.webstore/WEB-INF/web.xml @@ -21,8 +21,8 @@ equinoxBridgeFilter org.eclipse.equinox.servletbridge.BridgeFilter - bundleSymbolicName - org.adempiere.webstore + HttpContext.ClassName + org.adempiere.webstore.DefaultHttpContext diff --git a/org.adempiere.webstore/build.properties b/org.adempiere.webstore/build.properties index 3928856be4..02ed860ca2 100644 --- a/org.adempiere.webstore/build.properties +++ b/org.adempiere.webstore/build.properties @@ -1,9 +1,12 @@ +output.. = build/ bin.includes = META-INF/,\ *.*,\ - WEB-INF/ + WEB-INF/,\ + plugin.xml bin.excludes = src/**,\ build/**,\ .settings/**,\ .classpath,\ .project,\ build.properties +source.. = src/ diff --git a/org.adempiere.webstore/plugin.xml b/org.adempiere.webstore/plugin.xml new file mode 100644 index 0000000000..6189a10cdd --- /dev/null +++ b/org.adempiere.webstore/plugin.xml @@ -0,0 +1,12 @@ + + + + + + + + + diff --git a/org.adempiere.webstore/src/org/adempiere/webstore/Activator.java b/org.adempiere.webstore/src/org/adempiere/webstore/Activator.java new file mode 100644 index 0000000000..1a1849b6bf --- /dev/null +++ b/org.adempiere.webstore/src/org/adempiere/webstore/Activator.java @@ -0,0 +1,39 @@ +/** + * + */ +package org.adempiere.webstore; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +/** + * @author hengsin + * + */ +public class Activator implements BundleActivator { + + static BundleContext bundleContext; + + /** + * default constructor + */ + public Activator() { + } + + /* (non-Javadoc) + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + @Override + public void start(BundleContext context) throws Exception { + bundleContext = context; + } + + /* (non-Javadoc) + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + @Override + public void stop(BundleContext context) throws Exception { + bundleContext = null; + } + +} diff --git a/org.adempiere.webstore/src/org/adempiere/webstore/DefaultHttpContext.java b/org.adempiere.webstore/src/org/adempiere/webstore/DefaultHttpContext.java new file mode 100644 index 0000000000..9c2c491d87 --- /dev/null +++ b/org.adempiere.webstore/src/org/adempiere/webstore/DefaultHttpContext.java @@ -0,0 +1,33 @@ +package org.adempiere.webstore; + +import java.io.IOException; +import java.net.URL; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.osgi.service.http.HttpContext; + +public class DefaultHttpContext implements HttpContext { + + public DefaultHttpContext() { + } + + @Override + public boolean handleSecurity(HttpServletRequest request, + HttpServletResponse response) throws IOException { + // default behaviour assumes the container has already performed authentication + return true; + } + + @Override + public URL getResource(String name) { + return Activator.bundleContext.getBundle().getResource(name); + } + + @Override + public String getMimeType(String name) { + return null; + } + +} diff --git a/org.idempiere.felix.webconsole-feature/.project b/org.idempiere.felix.webconsole-feature/.project new file mode 100644 index 0000000000..d3a13310cb --- /dev/null +++ b/org.idempiere.felix.webconsole-feature/.project @@ -0,0 +1,17 @@ + + + org.idempiere.felix.webconsole-feature + + + + + + org.eclipse.pde.FeatureBuilder + + + + + + org.eclipse.pde.FeatureNature + + diff --git a/org.idempiere.felix.webconsole-feature/build.properties b/org.idempiere.felix.webconsole-feature/build.properties new file mode 100644 index 0000000000..64f93a9f0b --- /dev/null +++ b/org.idempiere.felix.webconsole-feature/build.properties @@ -0,0 +1 @@ +bin.includes = feature.xml diff --git a/org.idempiere.felix.webconsole-feature/feature.xml b/org.idempiere.felix.webconsole-feature/feature.xml new file mode 100644 index 0000000000..2f1bc80dbd --- /dev/null +++ b/org.idempiere.felix.webconsole-feature/feature.xml @@ -0,0 +1,47 @@ + + + + + [Enter Feature Description here.] + + + + [Enter Copyright Description here.] + + + + [Enter License Description here.] + + + + + + + + + + + diff --git a/org.idempiere.felix.webconsole/.classpath b/org.idempiere.felix.webconsole/.classpath new file mode 100644 index 0000000000..ad32c83a78 --- /dev/null +++ b/org.idempiere.felix.webconsole/.classpath @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.idempiere.felix.webconsole/.project b/org.idempiere.felix.webconsole/.project new file mode 100644 index 0000000000..ccbfd09e26 --- /dev/null +++ b/org.idempiere.felix.webconsole/.project @@ -0,0 +1,33 @@ + + + org.idempiere.felix.webconsole + + + + + + org.eclipse.jdt.core.javabuilder + + + + + org.eclipse.pde.ManifestBuilder + + + + + org.eclipse.pde.SchemaBuilder + + + + + org.eclipse.pde.ds.core.builder + + + + + + org.eclipse.pde.PluginNature + org.eclipse.jdt.core.javanature + + diff --git a/org.idempiere.felix.webconsole/.settings/org.eclipse.jdt.core.prefs b/org.idempiere.felix.webconsole/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000000..c537b63063 --- /dev/null +++ b/org.idempiere.felix.webconsole/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,7 @@ +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 diff --git a/org.idempiere.felix.webconsole/.settings/org.eclipse.pde.core.prefs b/org.idempiere.felix.webconsole/.settings/org.eclipse.pde.core.prefs new file mode 100644 index 0000000000..f29e940a00 --- /dev/null +++ b/org.idempiere.felix.webconsole/.settings/org.eclipse.pde.core.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +pluginProject.extensions=false +resolve.requirebundle=false diff --git a/org.idempiere.felix.webconsole/META-INF/MANIFEST.MF b/org.idempiere.felix.webconsole/META-INF/MANIFEST.MF new file mode 100644 index 0000000000..68a87c4cdc --- /dev/null +++ b/org.idempiere.felix.webconsole/META-INF/MANIFEST.MF @@ -0,0 +1,29 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Web Console +Bundle-SymbolicName: org.idempiere.felix.webconsole +Bundle-Version: 1.0.0.qualifier +Bundle-Activator: org.idempiere.felix.webconsole.Activator +Bundle-ActivationPolicy: lazy +Bundle-RequiredExecutionEnvironment: JavaSE-1.6 +Import-Package: javax.servlet;version="2.5.0", + javax.servlet.http;version="2.5.0", + javax.servlet.jsp;version="2.1.0", + javax.servlet.jsp.el;version="2.1.0", + javax.servlet.jsp.jstl.core;version="1.1.2", + javax.servlet.jsp.jstl.fmt;version="1.1.2", + javax.servlet.jsp.jstl.sql;version="1.1.2", + javax.servlet.jsp.jstl.tlv;version="1.1.2", + javax.servlet.jsp.resources;version="2.1.0", + javax.servlet.jsp.tagext;version="2.1.0", + javax.servlet.resources;version="2.5.0", + org.apache.felix.webconsole;version="3.1.2", + org.compiere.model, + org.compiere.util, + org.eclipse.equinox.http.registry;version="1.0.0", + org.eclipse.equinox.http.servlet;version="1.1.0", + org.eclipse.equinox.servletbridge;version="1.1.0", + org.osgi.framework;version="1.6.0", + org.osgi.service.http;version="1.2.1" +Web-ContextPath: osgi +Service-Component: OSGI-INF/securityprovider.xml diff --git a/org.idempiere.felix.webconsole/OSGI-INF/securityprovider.xml b/org.idempiere.felix.webconsole/OSGI-INF/securityprovider.xml new file mode 100644 index 0000000000..ce6c4540bf --- /dev/null +++ b/org.idempiere.felix.webconsole/OSGI-INF/securityprovider.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/org.idempiere.felix.webconsole/WEB-INF/web.xml b/org.idempiere.felix.webconsole/WEB-INF/web.xml new file mode 100644 index 0000000000..780230413a --- /dev/null +++ b/org.idempiere.felix.webconsole/WEB-INF/web.xml @@ -0,0 +1,37 @@ + + + Web Console + + + equinoxBridgeFilter + org.eclipse.equinox.servletbridge.BridgeFilter + + HttpContext.ClassName + org.apache.felix.webconsole.internal.servlet.OsgiManagerHttpContext + + + + equinoxBridgeFilter + /* + + + + equinoxBridgeFilter + *.jsp + + + + 30 + + + + css + text/css + + + diff --git a/org.idempiere.felix.webconsole/build.properties b/org.idempiere.felix.webconsole/build.properties new file mode 100644 index 0000000000..3fa3261a1a --- /dev/null +++ b/org.idempiere.felix.webconsole/build.properties @@ -0,0 +1,7 @@ +output.. = bin/ +bin.includes = META-INF/,\ + .,\ + WEB-INF/,\ + OSGI-INF/securityprovider.xml +src.includes = WEB-INF/ +source.. = src/ diff --git a/org.idempiere.felix.webconsole/src/org/idempiere/felix/webconsole/Activator.java b/org.idempiere.felix.webconsole/src/org/idempiere/felix/webconsole/Activator.java new file mode 100644 index 0000000000..f2a1773af7 --- /dev/null +++ b/org.idempiere.felix.webconsole/src/org/idempiere/felix/webconsole/Activator.java @@ -0,0 +1,30 @@ +package org.idempiere.felix.webconsole; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; + +public class Activator implements BundleActivator { + + private static BundleContext context; + + static BundleContext getContext() { + return context; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext) + */ + public void start(BundleContext bundleContext) throws Exception { + Activator.context = bundleContext; + } + + /* + * (non-Javadoc) + * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext) + */ + public void stop(BundleContext bundleContext) throws Exception { + Activator.context = null; + } + +} diff --git a/org.idempiere.felix.webconsole/src/org/idempiere/felix/webconsole/SecurityProviderImpl.java b/org.idempiere.felix.webconsole/src/org/idempiere/felix/webconsole/SecurityProviderImpl.java new file mode 100644 index 0000000000..45b4345b6c --- /dev/null +++ b/org.idempiere.felix.webconsole/src/org/idempiere/felix/webconsole/SecurityProviderImpl.java @@ -0,0 +1,48 @@ +/** + * + */ +package org.idempiere.felix.webconsole; + +import org.apache.felix.webconsole.WebConsoleSecurityProvider; +import org.compiere.model.MUser; +import org.compiere.util.CLogger; +import org.compiere.util.Env; + +/** + * @author hengsin + * + */ +public class SecurityProviderImpl implements WebConsoleSecurityProvider { + + /** Logger */ + protected CLogger log = CLogger.getCLogger(getClass()); + + /* (non-Javadoc) + * @see org.apache.felix.webconsole.WebConsoleSecurityProvider#authenticate(java.lang.String, java.lang.String) + */ + @Override + public Object authenticate(String username, String password) { + MUser user = MUser.get(Env.getCtx(), username, password); + if (user == null) + { + log.warning ("User not found: '" + username); + return null; + } + if (!user.isAdministrator()) + { + log.warning ("Not a Sys Admin = " + username); + return null; + } + log.info ("Name=" + username); + return Boolean.TRUE; + } + + /* (non-Javadoc) + * @see org.apache.felix.webconsole.WebConsoleSecurityProvider#authorize(java.lang.Object, java.lang.String) + */ + @Override + public boolean authorize(Object resource, String role) { + return true; + } + +} diff --git a/org.zkoss.zk.library/META-INF/MANIFEST.MF b/org.zkoss.zk.library/META-INF/MANIFEST.MF index 6ac578e3d5..0c93cf1f0a 100644 --- a/org.zkoss.zk.library/META-INF/MANIFEST.MF +++ b/org.zkoss.zk.library/META-INF/MANIFEST.MF @@ -236,15 +236,15 @@ Export-Package: Lib, optparse, org.apache.commons.el, org.apache.commons.el.parser, - org.apache.commons.fileupload, - org.apache.commons.fileupload.disk, - org.apache.commons.fileupload.portlet, - org.apache.commons.fileupload.servlet, - org.apache.commons.fileupload.util, - org.apache.commons.io, - org.apache.commons.io.filefilter, - org.apache.commons.io.input, - org.apache.commons.io.output, + org.apache.commons.fileupload;version="1.2.2", + org.apache.commons.fileupload.disk;version="1.2.2", + org.apache.commons.fileupload.portlet;version="1.2.2", + org.apache.commons.fileupload.servlet;version="1.2.2", + org.apache.commons.fileupload.util;version="1.2.2", + org.apache.commons.io;version="2.1.0", + org.apache.commons.io.filefilter;version="2.1.0", + org.apache.commons.io.input;version="2.1.0", + org.apache.commons.io.output;version="2.1.0", org.apache.html.dom, org.apache.wml, org.apache.wml.dom,