diff options
author | Roberto E. Escobar | 2014-06-02 23:35:33 +0000 |
---|---|---|
committer | Roberto E. Escobar | 2014-08-28 23:58:29 +0000 |
commit | fc1724d32fd8d2e3e5c8c1e004c7a2b249a99c24 (patch) | |
tree | c67f98e860ff8c5bc0d6933f157a0d1bba493d34 /plugins/org.eclipse.osee.jaxrs.server | |
parent | 72b171ca3a58dd69dcdf4b40d2ed0bbdaad40730 (diff) | |
download | org.eclipse.osee-fc1724d32fd8d2e3e5c8c1e004c7a2b249a99c24.tar.gz org.eclipse.osee-fc1724d32fd8d2e3e5c8c1e004c7a2b249a99c24.tar.xz org.eclipse.osee-fc1724d32fd8d2e3e5c8c1e004c7a2b249a99c24.zip |
feature[ats_ATS58837]: Add dynamic JAX-RS base context configuration
Change-Id: I05d487061353e5a18907efcde629af193dff08b8
Diffstat (limited to 'plugins/org.eclipse.osee.jaxrs.server')
31 files changed, 1346 insertions, 711 deletions
diff --git a/plugins/org.eclipse.osee.jaxrs.server/META-INF/MANIFEST.MF b/plugins/org.eclipse.osee.jaxrs.server/META-INF/MANIFEST.MF index f85bdecf7cc..e09aee57fe3 100644 --- a/plugins/org.eclipse.osee.jaxrs.server/META-INF/MANIFEST.MF +++ b/plugins/org.eclipse.osee.jaxrs.server/META-INF/MANIFEST.MF @@ -6,28 +6,29 @@ Bundle-Version: 0.18.0.qualifier Bundle-RequiredExecutionEnvironment: JavaSE-1.6 Service-Component: OSGI-INF/*.xml Import-Package: com.google.common.io, + com.sun.jersey.api.container.filter;version="1.18.0", com.sun.jersey.api.container.filter.servlet;version="1.18.0", - com.sun.jersey.api.core, + com.sun.jersey.api.core;version="1.18.0", com.sun.jersey.api.model;version="1.18.0", - com.sun.jersey.api.wadl.config, - com.sun.jersey.server.wadl, - com.sun.jersey.server.wadl.generators, - com.sun.jersey.server.wadl.generators.resourcedoc, - com.sun.jersey.server.wadl.generators.resourcedoc.model, - com.sun.jersey.server.wadl.generators.resourcedoc.xhtml, + com.sun.jersey.api.wadl.config;version="1.18.0", + com.sun.jersey.server.wadl;version="1.18.0", + com.sun.jersey.server.wadl.generators;version="1.18.0", + com.sun.jersey.server.wadl.generators.resourcedoc;version="1.18.0", + com.sun.jersey.server.wadl.generators.resourcedoc.model;version="1.18.0", + com.sun.jersey.server.wadl.generators.resourcedoc.xhtml;version="1.18.0", com.sun.jersey.spi.container;version="1.18.0", - com.sun.jersey.spi.container.servlet, + com.sun.jersey.spi.container.servlet;version="1.18.0", + javax.annotation.security;version="1.1.0", javax.servlet;version="2.5.0", javax.servlet.http;version="2.5.0", javax.ws.rs, javax.ws.rs.core, javax.ws.rs.ext, - org.eclipse.osee.executor.admin, org.eclipse.osee.authorization.admin, org.eclipse.osee.framework.jdk.core.type, org.eclipse.osee.framework.jdk.core.util, - org.eclipse.osee.logger, org.eclipse.osee.jaxrs, + org.eclipse.osee.logger, org.osgi.framework, org.osgi.service.http Bundle-Vendor: Eclipse Open System Engineering Environment diff --git a/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.admin.application.xml b/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.admin.application.xml new file mode 100644 index 00000000000..96661993edc --- /dev/null +++ b/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.admin.application.xml @@ -0,0 +1,8 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop"> + <implementation class="org.eclipse.osee.jaxrs.server.internal.JaxRsAdminApplication" /> + <service> + <provide interface="javax.ws.rs.core.Application"/> + </service> + <reference bind="setJaxRsApplicationRegistry" cardinality="1..1" interface="org.eclipse.osee.jaxrs.server.internal.applications.JaxRsApplicationRegistry" name="JaxRsApplicationRegistry" policy="static"/> +</scr:component> diff --git a/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.application.manager.xml b/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.application.manager.xml index ceeb783b31d..b037334b642 100644 --- a/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.application.manager.xml +++ b/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.application.manager.xml @@ -1,23 +1,7 @@ <?xml version="1.0" encoding="UTF-8"?> -<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop" enabled="true" immediate="true"> - <implementation class="org.eclipse.osee.jaxrs.server.internal.RestServletManager"/> - - <reference interface="org.osgi.service.http.HttpService" name="HttpService" - cardinality="1..1" - policy="static" - bind="setHttpService" /> - - <reference interface="org.eclipse.osee.logger.Log" name="Log" - cardinality="1..1" - policy="static" - bind="setLogger" /> - - - <reference interface="javax.ws.rs.core.Application" name="Application" - cardinality="1..n" - policy="dynamic" - bind="addApplication" - unbind="removeApplication" /> - <reference bind="setExecutorAdmin" cardinality="1..1" interface="org.eclipse.osee.executor.admin.ExecutorAdmin" name="ExecutorAdmin" policy="static"/> - <reference bind="setAuthorizationAdmin" cardinality="1..1" interface="org.eclipse.osee.authorization.admin.AuthorizationAdmin" name="AuthorizationAdmin" policy="static"/> +<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" configuration-policy="optional" deactivate="stop" enabled="true" immediate="true" modified="update"> + <implementation class="org.eclipse.osee.jaxrs.server.internal.JaxRsApplicationManager" /> + + <reference interface="javax.ws.rs.core.Application" name="Application" cardinality="1..n" policy="dynamic" bind="addApplication" unbind="removeApplication" /> + <reference bind="setJaxRsApplicationRegistry" cardinality="1..1" interface="org.eclipse.osee.jaxrs.server.internal.applications.JaxRsApplicationRegistry" name="JaxRsApplicationRegistry" policy="static" unbind="unsetJaxRsApplicationRegistry"/> </scr:component> diff --git a/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.application.registry.xml b/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.application.registry.xml new file mode 100644 index 00000000000..6cf025dfa7b --- /dev/null +++ b/plugins/org.eclipse.osee.jaxrs.server/OSGI-INF/jaxrs.application.registry.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="UTF-8"?> +<scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" activate="start" deactivate="stop"> + <implementation class="org.eclipse.osee.jaxrs.server.internal.applications.JaxRsApplicationRegistry" /> + <service> + <provide interface="org.eclipse.osee.jaxrs.server.internal.applications.JaxRsApplicationRegistry"/> + </service> + <reference bind="setHttpService" cardinality="1..1" interface="org.osgi.service.http.HttpService" name="HttpService" policy="static" /> + <reference bind="setLogger" cardinality="1..1" interface="org.eclipse.osee.logger.Log" name="Log" policy="static"/> + <reference bind="setAuthorizationAdmin" cardinality="1..1" interface="org.eclipse.osee.authorization.admin.AuthorizationAdmin" name="AuthorizationAdmin" policy="static"/> +</scr:component> diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/BundleHttpContext.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/BundleHttpContext.java deleted file mode 100644 index 6169f91ef4a..00000000000 --- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/BundleHttpContext.java +++ /dev/null @@ -1,55 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004, 2007 Boeing. - * 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: - * Boeing - initial API and implementation - *******************************************************************************/ -package org.eclipse.osee.jaxrs.server.internal; - -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; - -/** - * @author Roberto E. Escobar - */ -public class BundleHttpContext implements HttpContext { - - private final ObjectProvider<Iterable<Bundle>> bundlesProvider; - - public BundleHttpContext(ObjectProvider<Iterable<Bundle>> bundlesProvider) { - this.bundlesProvider = bundlesProvider; - } - - @Override - public URL getResource(String path) { - // find first bundle that has an entry for the path - URL toReturn = null; - Iterable<Bundle> bundles = bundlesProvider.get(); - for (Bundle bundle : bundles) { - toReturn = bundle.getEntry(path); - if (toReturn != null) { - return toReturn; - } - } - return toReturn; - } - - @Override - public String getMimeType(String name) { - return null; - } - - @Override - public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) { - // Assume the container has already performed authentication - return true; - } - -}
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsAdminApplication.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsAdminApplication.java new file mode 100644 index 00000000000..bf031667601 --- /dev/null +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsAdminApplication.java @@ -0,0 +1,47 @@ +/******************************************************************************* + * Copyright (c) 2014 Boeing. + * 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: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.jaxrs.server.internal; + +import java.util.LinkedHashSet; +import java.util.Set; +import javax.ws.rs.ApplicationPath; +import javax.ws.rs.core.Application; +import org.eclipse.osee.jaxrs.server.internal.applications.JaxRsApplicationRegistry; +import org.eclipse.osee.jaxrs.server.internal.resources.ApplicationResource; + +/** + * @author Roberto E. Escobar + */ +@ApplicationPath("jaxrs-admin") +public class JaxRsAdminApplication extends Application { + + private final Set<Object> singletons = new LinkedHashSet<Object>(); + + private JaxRsApplicationRegistry registry; + + public void setJaxRsApplicationRegistry(JaxRsApplicationRegistry registry) { + this.registry = registry; + } + + public void start() { + singletons.add(new ApplicationResource(registry)); + } + + public void stop() { + singletons.clear(); + } + + @Override + public Set<Object> getSingletons() { + return singletons; + } + +}
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsApplicationManager.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsApplicationManager.java new file mode 100644 index 00000000000..e10ef7e8f73 --- /dev/null +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsApplicationManager.java @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2014 Boeing. + * 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: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.jaxrs.server.internal; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicReference; +import javax.ws.rs.core.Application; +import org.eclipse.osee.jaxrs.server.internal.applications.JaxRsApplicationRegistry; +import org.osgi.framework.Bundle; +import org.osgi.framework.ServiceReference; + +/** + * @author Roberto E. Escobar + */ +public final class JaxRsApplicationManager { + + private final List<ServiceReference<Application>> pendingReg = new ArrayList<ServiceReference<Application>>(); + private final AtomicReference<JaxRsApplicationRegistry> registryRef = + new AtomicReference<JaxRsApplicationRegistry>(); + private volatile JaxRsConfiguration config; + + public void setJaxRsApplicationRegistry(JaxRsApplicationRegistry registry) { + registryRef.set(registry); + } + + public void unsetJaxRsApplicationRegistry(JaxRsApplicationRegistry registry) { + registryRef.set(null); + } + + private JaxRsApplicationRegistry getRegistry() { + return registryRef.get(); + } + + public void start(Map<String, Object> props) throws Exception { + update(props); + final JaxRsApplicationRegistry registry = getRegistry(); + synchronized (pendingReg) { + Iterator<ServiceReference<Application>> iterator = pendingReg.iterator(); + while (iterator.hasNext()) { + ServiceReference<Application> reference = iterator.next(); + register(registry, reference); + iterator.remove(); + } + } + } + + public void stop() { + JaxRsApplicationRegistry registry = getRegistry(); + if (registry != null) { + registry.deregisterAll(); + } + } + + public void update(Map<String, Object> props) { + config = JaxRsConfiguration.fromProperties(props).build(); + JaxRsApplicationRegistry registry = getRegistry(); + if (registry != null) { + registry.configure(config); + } + } + + public void addApplication(ServiceReference<Application> reference) throws Exception { + JaxRsApplicationRegistry registry = getRegistry(); + if (registry != null) { + register(registry, reference); + } else { + synchronized (pendingReg) { + pendingReg.add(reference); + } + } + } + + public void removeApplication(ServiceReference<Application> reference) { + JaxRsApplicationRegistry registry = getRegistry(); + if (registry != null) { + String componentName = JaxRsUtils.getComponentName(reference); + registry.deregister(componentName); + } else { + synchronized (pendingReg) { + pendingReg.remove(reference); + } + } + } + + private void register(JaxRsApplicationRegistry registry, ServiceReference<Application> reference) throws Exception { + String componentName = JaxRsUtils.getComponentName(reference); + Bundle bundle = reference.getBundle(); + Application application = bundle.getBundleContext().getService(reference); + String contextName = JaxRsUtils.getApplicationPath(componentName, application); + registry.register(componentName, contextName, bundle, application); + } + +} diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsConfiguration.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsConfiguration.java new file mode 100644 index 00000000000..53e0c65eec8 --- /dev/null +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsConfiguration.java @@ -0,0 +1,63 @@ +/******************************************************************************* + * Copyright (c) 2014 Boeing. + * 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: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.jaxrs.server.internal; + +import java.util.Map; + +/** + * @author Roberto E. Escobar + */ +public class JaxRsConfiguration { + + private String baseContext; + + private JaxRsConfiguration() { + //Builder class + } + + public String getBaseContext() { + return baseContext; + } + + public static JaxRsConfigurationBuilder newBuilder() { + return new JaxRsConfigurationBuilder(); + } + + public static JaxRsConfigurationBuilder fromProperties(Map<String, Object> props) { + return newBuilder().properties(props); + } + + @Override + public String toString() { + return "JaxRsConfiguration [baseContext=" + baseContext + "]"; + } + + public static final class JaxRsConfigurationBuilder { + private String baseContext; + + public JaxRsConfiguration build() { + JaxRsConfiguration config = new JaxRsConfiguration(); + config.baseContext = baseContext; + return config; + } + + public JaxRsConfigurationBuilder properties(Map<String, Object> props) { + baseContext(JaxRsUtils.get(props, JaxRsConstants.JAXRS_BASE_CONTEXT, JaxRsConstants.DEFAULT_JAXRS_BASE_CONTEXT)); + return this; + } + + public JaxRsConfigurationBuilder baseContext(String contextName) { + this.baseContext = JaxRsUtils.normalize(contextName); + return this; + } + + } +} diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsConstants.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsConstants.java new file mode 100644 index 00000000000..35c0f20917b --- /dev/null +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsConstants.java @@ -0,0 +1,32 @@ +/******************************************************************************* + * Copyright (c) 2014 Boeing. + * 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: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.jaxrs.server.internal; + +/** + * @author Roberto E. Escobar + */ +public final class JaxRsConstants { + + private JaxRsConstants() { + // Constants class + } + + public static final String NAMESPACE = "jaxrs.server"; + + private static String qualify(String value) { + return String.format("%s.%s", NAMESPACE, value); + } + + public static final String DEFAULT_JAXRS_BASE_CONTEXT = "/"; + + public static final String JAXRS_BASE_CONTEXT = qualify("base.context"); + +} diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/RestServiceUtils.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsUtils.java index 511080ea75a..a9504f06fee 100644 --- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/RestServiceUtils.java +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsUtils.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2007 Boeing. + * Copyright (c) 2014 Boeing. * 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 @@ -11,7 +11,6 @@ package org.eclipse.osee.jaxrs.server.internal; import java.util.Collection; -import java.util.HashMap; import java.util.Map; import javax.ws.rs.ApplicationPath; import javax.ws.rs.core.Application; @@ -21,9 +20,9 @@ import org.osgi.framework.ServiceReference; /** * @author Roberto E. Escobar */ -public final class RestServiceUtils { +public final class JaxRsUtils { - private RestServiceUtils() { + private JaxRsUtils() { // Utility class } @@ -50,7 +49,7 @@ public final class RestServiceUtils { Class<? extends Application> clazz = application.getClass(); ApplicationPath applicationPath = clazz.getAnnotation(ApplicationPath.class); if (applicationPath != null) { - toReturn = normalize(applicationPath.value()); + toReturn = JaxRsUtils.normalize(applicationPath.value()); } return toReturn; } @@ -70,7 +69,7 @@ public final class RestServiceUtils { return !isNullOrEmpty(app.getClasses()) || !isNullOrEmpty(app.getSingletons()); } - private static String normalize(String contextName) { + public static String normalize(String contextName) { return contextName != null && !contextName.startsWith("/") ? "/" + contextName : contextName; } @@ -78,11 +77,13 @@ public final class RestServiceUtils { return collection == null || collection.isEmpty(); } - public static Map<String, String> toMap(String componentName, String contextName) { - Map<String, String> data = new HashMap<String, String>(); - data.put("component.name", componentName); - data.put("context.name", contextName); - return data; + public static String get(Map<String, Object> props, String key, String defaultValue) { + String toReturn = defaultValue; + Object object = props != null ? props.get(key) : null; + if (object != null) { + toReturn = String.valueOf(object); + } + return toReturn; } } diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/ObjectProvider.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsVisitable.java index 99aaf392c7f..3712e4b012e 100644 --- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/ObjectProvider.java +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsVisitable.java @@ -13,8 +13,8 @@ package org.eclipse.osee.jaxrs.server.internal; /** * @author Roberto E. Escobar */ -public interface ObjectProvider<T> { +public interface JaxRsVisitable { - T get(); + void accept(JaxRsVisitor visitor); -} +}
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsVisitor.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsVisitor.java new file mode 100644 index 00000000000..eee0d55de43 --- /dev/null +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/JaxRsVisitor.java @@ -0,0 +1,45 @@ +/******************************************************************************* + * Copyright (c) 2014 Boeing. + * 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: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.jaxrs.server.internal; + +import javax.ws.rs.core.Application; +import org.osgi.framework.Bundle; + +/** + * @author Roberto E. Escobar + */ +public class JaxRsVisitor { + + public void onStartRegistry() { + // + } + + public void onServletContext(String servletContext, int numberOfAppContexts) { + // + } + + public void onStartApplicationContainer(String applicationContext, int size) { + // + } + + public void onApplication(String applicationContext, String componentName, Bundle bundle, Application application) { + // + } + + public void onEndApplicationContainer() { + // + } + + public void onEndRegistry() { + // + } + +}
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/RestComponentFactory.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/RestComponentFactory.java deleted file mode 100644 index 5870d61e691..00000000000 --- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/RestComponentFactory.java +++ /dev/null @@ -1,86 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Boeing. - * 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: - * Boeing - initial API and implementation - *******************************************************************************/ -package org.eclipse.osee.jaxrs.server.internal; - -import java.util.Collections; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; -import org.eclipse.osee.jaxrs.server.internal.filters.SecureResourceFilterFactory; -import org.eclipse.osee.jaxrs.server.internal.filters.SecurityContextFilter; -import org.eclipse.osee.jaxrs.server.internal.resources.ApplicationsResource; -import org.eclipse.osee.logger.Log; -import org.osgi.framework.Bundle; -import com.sun.jersey.api.core.DefaultResourceConfig; -import com.sun.jersey.api.core.ResourceConfig; -import com.sun.jersey.spi.container.ResourceFilterFactory; -import com.sun.jersey.spi.container.servlet.ServletContainer; - -/** - * @author Roberto E. Escobar - */ -public class RestComponentFactory { - private final Log logger; - private final SecurityContextFilter securityContextFilter; - - private List<Object> defaultSingletonResources; - - public RestComponentFactory(Log logger, SecurityContextFilter securityContextFilter) { - super(); - this.logger = logger; - this.securityContextFilter = securityContextFilter; - } - - public List<ResourceFilterFactory> getResourceFilterFactories() { - SecureResourceFilterFactory filterFactory = new SecureResourceFilterFactory(logger, securityContextFilter); - return Collections.<ResourceFilterFactory> singletonList(filterFactory); - } - - public List<Object> getResourceSingletons() { - if (defaultSingletonResources == null) { - GenericExceptionMapper exceptionMapper = new GenericExceptionMapper(logger); - defaultSingletonResources = Collections.<Object> singletonList(exceptionMapper); - } - return defaultSingletonResources; - } - - public RestServletContainer createContainer(String context) throws Exception { - DefaultResourceConfig config = new DefaultResourceConfig(); - - for (Object resource : getResourceSingletons()) { - config.getSingletons().add(resource); - } - - Map<String, Bundle> bundleMap = new ConcurrentHashMap<String, Bundle>(); - ObjectProvider<Iterable<Bundle>> provider = newBundleProvider(bundleMap); - config.getProperties().put(ResourceConfig.PROPERTY_RESOURCE_FILTER_FACTORIES, getResourceFilterFactories()); - - BundleHttpContext bundleContext = new BundleHttpContext(provider); - BundleWadlGeneratorConfig wadlGenerator = new BundleWadlGeneratorConfig(logger, provider); - - ApplicationsResource resource = new ApplicationsResource(provider); - config.getSingletons().add(resource); - - ServletContainer container = new ServletContainer(config); - return new RestServletContainer(logger, context, bundleMap, container, config, bundleContext, wadlGenerator); - } - - private ObjectProvider<Iterable<Bundle>> newBundleProvider(final Map<String, Bundle> bundleMap) { - return new ObjectProvider<Iterable<Bundle>>() { - - @Override - public Iterable<Bundle> get() { - return bundleMap.values(); - } - }; - } - -} diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/RestServletContainer.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/RestServletContainer.java deleted file mode 100644 index 43e10443624..00000000000 --- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/RestServletContainer.java +++ /dev/null @@ -1,113 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Boeing. - * 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: - * Boeing - initial API and implementation - *******************************************************************************/ -package org.eclipse.osee.jaxrs.server.internal; - -import java.util.Map; -import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; -import javax.ws.rs.core.Application; -import org.eclipse.osee.logger.Log; -import org.osgi.framework.Bundle; -import org.osgi.service.http.HttpContext; -import com.sun.jersey.api.core.DefaultResourceConfig; -import com.sun.jersey.api.core.ResourceConfig; -import com.sun.jersey.spi.container.servlet.ServletContainer; - -/** - * @author David W. Miller - */ -public class RestServletContainer { - private final Map<String, Application> applications = new ConcurrentHashMap<String, Application>(); - - private final Log logger; - private final String baseContext; - private final Map<String, Bundle> bundles; - private final ServletContainer container; - private final DefaultResourceConfig resourceConfig; - private final HttpContext context; - private final BundleWadlGeneratorConfig wadl; - - public RestServletContainer(Log logger, String baseContext, Map<String, Bundle> bundles, ServletContainer container, DefaultResourceConfig resourceConfig, HttpContext context, BundleWadlGeneratorConfig wadl) { - super(); - this.logger = logger; - this.baseContext = baseContext; - this.bundles = bundles; - this.container = container; - this.resourceConfig = resourceConfig; - this.context = context; - this.wadl = wadl; - } - - public String getContext() { - return baseContext; - } - - public void addApplication(String key, Bundle bundle, Application application) { - logger.debug("Add - servlet context[%s] - application[%s]", getContext(), key); - applications.put(key, application); - resourceConfig.add(application); - bundles.put(key, bundle); - updateWadlSupport(); - } - - private void updateWadlSupport() { - Map<String, Object> properties = resourceConfig.getProperties(); - if (wadl.hasExtendedWadl()) { - properties.put(ResourceConfig.PROPERTY_WADL_GENERATOR_CONFIG, wadl); - } else { - properties.remove(ResourceConfig.PROPERTY_WADL_GENERATOR_CONFIG); - } - } - - public void removeApplication(String key) { - logger.debug("Remove - servlet context[%s] - application[%s]", getContext(), key); - Application remove = applications.remove(key); - if (remove != null) { - removeResources(resourceConfig.getClasses(), remove.getClasses()); - removeResources(resourceConfig.getSingletons(), remove.getSingletons()); - } - Bundle bundle = bundles.remove(key); - if (bundle != null) { - updateWadlSupport(); - } - } - - public void cleanUp() { - for (String key : applications.keySet()) { - removeApplication(key); - } - } - - private void removeResources(Set<?> set, Set<?> toRemove) { - set.removeAll(toRemove); - } - - public boolean isEmpty() { - return applications.isEmpty(); - } - - public void destroy() { - getContainer().destroy(); - } - - public void reload() { - getContainer().reload(); - } - - public ServletContainer getContainer() { - return container; - } - - public HttpContext getHttpContext() { - return context; - } - -} diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/RestServletManager.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/RestServletManager.java deleted file mode 100644 index 4a961dce797..00000000000 --- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/RestServletManager.java +++ /dev/null @@ -1,175 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2004, 2007 Boeing. - * 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: - * Boeing - initial API and implementation - *******************************************************************************/ -package org.eclipse.osee.jaxrs.server.internal; - -import java.util.HashSet; -import java.util.Set; -import java.util.concurrent.Future; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicReference; -import javax.ws.rs.core.Application; -import org.eclipse.osee.authorization.admin.AuthorizationAdmin; -import org.eclipse.osee.executor.admin.CancellableCallable; -import org.eclipse.osee.executor.admin.ExecutorAdmin; -import org.eclipse.osee.jaxrs.server.internal.filters.SecurityContextFilter; -import org.eclipse.osee.jaxrs.server.internal.filters.SecurityContextProviderImpl; -import org.eclipse.osee.logger.Log; -import org.osgi.framework.ServiceReference; -import org.osgi.service.http.HttpService; - -/** - * @author Roberto E. Escobar - */ -public class RestServletManager { - - private static final ApplicationEntry END_OF_QUEUE = new ApplicationEntry(Op.END_OF_QUEUE, null); - - private final LinkedBlockingQueue<ApplicationEntry> pending = new LinkedBlockingQueue<ApplicationEntry>(); - - private HttpService httpService; - private Log logger; - private ExecutorAdmin executorAdmin; - private AuthorizationAdmin authorizationAdmin; - - private final AtomicReference<RestServletRegistry> registryRef = new AtomicReference<RestServletRegistry>(); - private final AtomicReference<Future<?>> futureRef = new AtomicReference<Future<?>>(); - - public void setHttpService(HttpService httpService) { - this.httpService = httpService; - } - - public void setLogger(Log logger) { - this.logger = logger; - } - - public void setExecutorAdmin(ExecutorAdmin executorAdmin) { - this.executorAdmin = executorAdmin; - } - - public void setAuthorizationAdmin(AuthorizationAdmin authorizationAdmin) { - this.authorizationAdmin = authorizationAdmin; - } - - public void start() throws Exception { - SecurityContextProvider contextProvider = new SecurityContextProviderImpl(logger, authorizationAdmin); - SecurityContextFilter securityFilter = new SecurityContextFilter(contextProvider); - - RestComponentFactory factory = new RestComponentFactory(logger, securityFilter); - RestServletRegistry newRegistry = new RestServletRegistry(logger, httpService, factory); - RestServletRegistry registry = registryRef.getAndSet(newRegistry); - if (registry != null) { - registry.cleanUp(); - } - - CancellableCallable<Void> callable = newRegistrationHelper(); - Future<?> newFuture = executorAdmin.schedule(callable); - Future<?> future = futureRef.getAndSet(newFuture); - stopWorker(future); - } - - public void stop() { - pending.offer(END_OF_QUEUE); - Future<?> future = futureRef.getAndSet(null); - stopWorker(future); - - RestServletRegistry registry = registryRef.getAndSet(null); - if (registry != null) { - registry.cleanUp(); - } - } - - private void stopWorker(Future<?> future) { - if (future != null) { - try { - future.get(3, TimeUnit.SECONDS); - } catch (Exception ex) { - logger.warn(ex, "Error waiting for registration worker to complete"); - future.cancel(true); - } - } - } - - public void addApplication(ServiceReference<Application> reference) { - pending.offer(new ApplicationEntry(Op.ADD, reference)); - } - - public void removeApplication(ServiceReference<Application> reference) { - pending.offer(new ApplicationEntry(Op.REMOVE, reference)); - } - - private CancellableCallable<Void> newRegistrationHelper() { - return new CancellableCallable<Void>() { - @Override - public Void call() throws Exception { - logger.debug("Start - REST Application Registration Helper"); - boolean isEndOfQueue = false; - while (!isEndOfQueue) { - Set<ApplicationEntry> toProcess = new HashSet<ApplicationEntry>(); - ApplicationEntry entry = pending.take(); - pending.drainTo(toProcess); - toProcess.add(entry); - - for (ApplicationEntry item : toProcess) { - checkForCancelled(); - - RestServletRegistry registry = registryRef.get(); - if (registry != null) { - ServiceReference<Application> reference = item.getReference(); - switch (item.getOp()) { - case ADD: - registry.register(reference); - break; - case REMOVE: - registry.deregister(reference); - break; - default: - isEndOfQueue = true; - break; - } - } else { - logger.debug("Registry was null while worker was processing [reg/de-reg]-istrations"); - isEndOfQueue = true; - } - } - } - logger.debug("Stop - REST Application Registration Helper"); - return null; - } - }; - } - - private static enum Op { - ADD, - REMOVE, - END_OF_QUEUE; - } - - private static final class ApplicationEntry { - private final Op op; - private final ServiceReference<Application> reference; - - public ApplicationEntry(Op op, ServiceReference<Application> reference) { - super(); - this.op = op; - this.reference = reference; - } - - public Op getOp() { - return op; - } - - public ServiceReference<Application> getReference() { - return reference; - } - - } -} diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/RestServletRegistry.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/RestServletRegistry.java deleted file mode 100644 index c8e9ca7944d..00000000000 --- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/RestServletRegistry.java +++ /dev/null @@ -1,146 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2013 Boeing. - * 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: - * Boeing - initial API and implementation - *******************************************************************************/ -package org.eclipse.osee.jaxrs.server.internal; - -import java.util.Iterator; -import java.util.concurrent.Callable; -import java.util.concurrent.ConcurrentHashMap; -import java.util.concurrent.FutureTask; -import javax.ws.rs.core.Application; -import org.eclipse.osee.framework.jdk.core.type.LazyObject; -import org.eclipse.osee.framework.jdk.core.util.Strings; -import org.eclipse.osee.logger.Log; -import org.osgi.framework.Bundle; -import org.osgi.framework.ServiceReference; -import org.osgi.service.http.HttpContext; -import org.osgi.service.http.HttpService; -import com.sun.jersey.spi.container.servlet.ServletContainer; - -/** - * @author Roberto E. Escobar - */ -public class RestServletRegistry { - - private final ConcurrentHashMap<String, LazyObject<RestServletContainer>> servlets = - new ConcurrentHashMap<String, LazyObject<RestServletContainer>>(); - private final ConcurrentHashMap<String, String> componentNameToApplicationPath = - new ConcurrentHashMap<String, String>(); - - private final Log logger; - private final HttpService httpService; - private final RestComponentFactory factory; - - public RestServletRegistry(Log logger, HttpService httpService, RestComponentFactory factory) { - super(); - this.logger = logger; - this.httpService = httpService; - this.factory = factory; - } - - public void register(ServiceReference<Application> reference) throws Exception { - String componentName = RestServiceUtils.getComponentName(reference); - - Bundle bundle = reference.getBundle(); - Application application = bundle.getBundleContext().getService(reference); - - String applicationPath = RestServiceUtils.getApplicationPath(componentName, application); - - LazyObject<RestServletContainer> provider = getProvider(applicationPath); - RestServletContainer container = provider.get(); - container.addApplication(componentName, bundle, application); - - componentNameToApplicationPath.put(componentName, applicationPath); - - container.reload(); - } - - public void deregister(ServiceReference<Application> reference) { - String componentName = RestServiceUtils.getComponentName(reference); - - String applicationPath = componentNameToApplicationPath.remove(componentName); - if (Strings.isValid(applicationPath)) { - LazyObject<RestServletContainer> provider = getProvider(applicationPath); - RestServletContainer container = provider.get(); - - container.removeApplication(componentName); - if (container.isEmpty()) { - removeContainer(provider); - } else { - container.reload(); - } - } - } - - public void cleanUp() { - Iterator<LazyObject<RestServletContainer>> iterator = servlets.values().iterator(); - while (iterator.hasNext()) { - LazyObject<RestServletContainer> provider = iterator.next(); - RestServletContainer container = provider.get(); - container.cleanUp(); - removeContainer(provider); - iterator.remove(); - } - servlets.clear(); - } - - private void removeContainer(LazyObject<RestServletContainer> provider) { - RestServletContainer container = provider.get(); - String contextName = container.getContext(); - - logger.debug("Remove - servlet context[%s]", contextName); - servlets.remove(contextName); - httpService.unregister(contextName); - container.destroy(); - provider.invalidate(); - } - - private LazyObject<RestServletContainer> getProvider(final String contextName) { - LazyObject<RestServletContainer> provider = servlets.get(contextName); - if (provider == null) { - LazyObject<RestServletContainer> newProvider = new ServletContainerProvider(contextName); - provider = servlets.putIfAbsent(contextName, newProvider); - if (provider == null) { - provider = newProvider; - } - } - return provider; - } - - private class ServletContainerProvider extends LazyObject<RestServletContainer> implements ObjectProvider<RestServletContainer> { - - private final String contextName; - - public ServletContainerProvider(String contextName) { - super(); - this.contextName = contextName; - } - - @Override - protected FutureTask<RestServletContainer> createLoaderTask() { - Callable<RestServletContainer> newCallable = new Callable<RestServletContainer>() { - @Override - public RestServletContainer call() throws Exception { - logger.debug("Add - servlet context[%s]", contextName); - RestServletContainer container = factory.createContainer(contextName); - - String name = container.getContext(); - ServletContainer servletContainer = container.getContainer(); - HttpContext httpContext = container.getHttpContext(); - - httpService.registerServlet(name, servletContainer, null, httpContext); - return container; - } - }; - return new FutureTask<RestServletContainer>(newCallable); - } - } - -} diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/applications/AbstractJaxRsApplicationContainer.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/applications/AbstractJaxRsApplicationContainer.java new file mode 100644 index 00000000000..2b2f5a7a1be --- /dev/null +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/applications/AbstractJaxRsApplicationContainer.java @@ -0,0 +1,129 @@ +/******************************************************************************* + * Copyright (c) 2014 Boeing. + * 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: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.jaxrs.server.internal.applications; + +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; +import javax.ws.rs.core.Application; +import org.eclipse.osee.jaxrs.server.internal.JaxRsVisitable; +import org.eclipse.osee.jaxrs.server.internal.JaxRsVisitor; +import org.osgi.framework.Bundle; + +/** + * @author Roberto E. Escobar + */ +public abstract class AbstractJaxRsApplicationContainer implements JaxRsVisitable { + + private final Map<String, JaxRsApplicationEntry> applications = + new ConcurrentHashMap<String, JaxRsApplicationEntry>(); + + private final String applicationContext; + + public AbstractJaxRsApplicationContainer(String applicationContext) { + super(); + this.applicationContext = applicationContext; + } + + public String getApplicationContext() { + return applicationContext; + } + + public void add(String key, Bundle bundle, Application application) { + JaxRsApplicationEntry entry = new JaxRsApplicationEntry(bundle, application); + applications.put(key, entry); + } + + public void remove(String key) { + applications.remove(key); + } + + public boolean isEmpty() { + return applications.isEmpty(); + } + + public int size() { + return applications.size(); + } + + @Override + public void accept(JaxRsVisitor visitor) { + visitor.onStartApplicationContainer(applicationContext, size()); + try { + for (Entry<String, JaxRsApplicationEntry> entry : applications.entrySet()) { + String componentName = entry.getKey(); + JaxRsApplicationEntry value = entry.getValue(); + Bundle bundle = value.getBundle(); + Application application = value.getApplication(); + visitor.onApplication(applicationContext, componentName, bundle, application); + } + } finally { + visitor.onEndApplicationContainer(); + } + } + + protected Application getApplication() { + Application toReturn = null; + if (applications.size() > 1) { + toReturn = newCompositeApplication(); + } else { + JaxRsApplicationEntry entry = getFirstEntry(); + toReturn = entry != null ? entry.getApplication() : null; + } + return toReturn; + } + + private JaxRsApplicationEntry getFirstEntry() { + return !applications.isEmpty() ? applications.values().iterator().next() : null; + } + + private final Application newCompositeApplication() { + final Set<Class<?>> classes = new LinkedHashSet<Class<?>>(); + final Set<Object> singletons = new LinkedHashSet<Object>(); + for (JaxRsApplicationEntry appEntry : applications.values()) { + Application application = appEntry.getApplication(); + classes.addAll(application.getClasses()); + singletons.addAll(application.getSingletons()); + } + return new Application() { + @Override + public Set<Class<?>> getClasses() { + return classes; + } + + @Override + public Set<Object> getSingletons() { + return singletons; + } + }; + } + + private final class JaxRsApplicationEntry { + private final Bundle bundle; + private final Application application; + + public JaxRsApplicationEntry(Bundle bundle, Application application) { + super(); + this.bundle = bundle; + this.application = application; + } + + public Bundle getBundle() { + return bundle; + } + + public Application getApplication() { + return application; + } + } +}
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/applications/AbstractJaxRsContainer.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/applications/AbstractJaxRsContainer.java new file mode 100644 index 00000000000..15d7c35b8dd --- /dev/null +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/applications/AbstractJaxRsContainer.java @@ -0,0 +1,181 @@ +/******************************************************************************* + * Copyright (c) 2014 Boeing. + * 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: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.jaxrs.server.internal.applications; + +import java.util.Dictionary; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; +import javax.servlet.http.HttpServlet; +import javax.ws.rs.core.Application; +import javax.ws.rs.core.Response.Status; +import org.eclipse.osee.jaxrs.OseeWebApplicationException; +import org.eclipse.osee.jaxrs.server.internal.JaxRsVisitable; +import org.eclipse.osee.jaxrs.server.internal.JaxRsVisitor; +import org.eclipse.osee.jaxrs.server.internal.applications.JaxRsApplicationRegistry.JaxRsContainer; +import org.eclipse.osee.logger.Log; +import org.osgi.framework.Bundle; +import org.osgi.service.http.HttpService; + +/** + * @author Roberto E. Escobar + */ +public abstract class AbstractJaxRsContainer<H extends HttpServlet, C extends AbstractJaxRsApplicationContainer> implements JaxRsContainer, JaxRsVisitable { + + private final Log logger; + private final HttpService httpService; + private final Dictionary<String, Object> props; + + private final ConcurrentHashMap<String, C> applications = new ConcurrentHashMap<String, C>(); + private final Map<String, String> componentToContext = new ConcurrentHashMap<String, String>(); + private final AtomicReference<String> servletContextName = new AtomicReference<String>(); + private final AtomicBoolean isRegistered = new AtomicBoolean(false); + + private volatile H baseJaxsRsServlet; + + public AbstractJaxRsContainer(Log logger, HttpService httpService, Dictionary<String, Object> props) { + super(); + this.logger = logger; + this.httpService = httpService; + this.props = props; + } + + protected HttpService getHttpService() { + return httpService; + } + + protected Dictionary<String, Object> getServletProperties() { + return props; + } + + @Override + public String getServletContext() { + return servletContextName.get(); + } + + @Override + public void setServletContext(String contextName) { + this.servletContextName.set(contextName); + } + + @Override + public boolean isEmpty() { + return applications.isEmpty(); + } + + @Override + public void accept(JaxRsVisitor visitor) { + visitor.onServletContext(getServletContext(), applications.size()); + for (C container : applications.values()) { + container.accept(visitor); + } + } + + protected abstract C createApplicationContainer(String applicationContext); + + protected abstract H createBaseJaxsRsServlet(JaxRsVisitable visitable); + + protected abstract void startContainer(C container); + + protected abstract void stopContainer(C container); + + private C getContextContainerInitIfNull(String applicationContext) { + C container = applications.get(applicationContext); + if (container == null) { + C newContainer = createApplicationContainer(applicationContext); + container = applications.putIfAbsent(applicationContext, newContainer); + if (container == null) { + container = newContainer; + } + } + return container; + } + + private C getContextContainerOrNull(String applicationContext) { + return applications.get(applicationContext); + } + + @Override + public synchronized void addApplication(String componentName, String applicationContext, Bundle bundle, Application application) { + logger.trace("Add Application - [%s] - application[%s]", this, componentName); + startServlet(); + C container = getContextContainerInitIfNull(applicationContext); + stopContainer(container); + container.add(componentName, bundle, application); + componentToContext.put(componentName, applicationContext); + try { + startContainer(container); + } catch (Exception ex) { + logger.error(ex, "Error activating application [%s] on [%s]", this, componentName); + } + } + + @Override + public synchronized void removeApplication(String componentName) { + logger.trace("Remove Application - [%s] - application[%s]", this, componentName); + String contextName = componentToContext.remove(componentName); + C container = getContextContainerOrNull(contextName); + if (container != null) { + stopContainer(container); + container.remove(componentName); + if (container.isEmpty()) { + applications.remove(contextName); + } else { + startContainer(container); + } + } + } + + @Override + public synchronized void start() { + startServlet(); + for (C container : applications.values()) { + startContainer(container); + } + } + + @Override + public synchronized void stop() { + for (C container : applications.values()) { + stopContainer(container); + } + stopServlet(); + } + + private void startServlet() { + if (!isRegistered.getAndSet(true)) { + baseJaxsRsServlet = createBaseJaxsRsServlet(this); + logger.trace("Register Servlet - [%s] - [%s]", this, baseJaxsRsServlet); + try { + String contextName = getServletContext(); + getHttpService().registerServlet(contextName, baseJaxsRsServlet, props, null); + } catch (Exception ex) { + throw new OseeWebApplicationException(ex, Status.INTERNAL_SERVER_ERROR, "Error registering servlet [%s] ", + servletContextName); + } + } + } + + private void stopServlet() { + if (isRegistered.getAndSet(false)) { + String contextName = getServletContext(); + logger.trace("De-register Servlet - [%s] - [%s]", this, baseJaxsRsServlet); + getHttpService().unregister(contextName); + baseJaxsRsServlet = null; + } + } + + @Override + public String toString() { + return "JaxRsContainerImpl [id=" + Integer.toHexString(hashCode()) + ", contextName=" + servletContextName + "]"; + } +}
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/applications/JaxRsApplicationRegistry.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/applications/JaxRsApplicationRegistry.java new file mode 100644 index 00000000000..454aed30496 --- /dev/null +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/applications/JaxRsApplicationRegistry.java @@ -0,0 +1,189 @@ +/******************************************************************************* + * Copyright (c) 2014 Boeing. + * 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: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.jaxrs.server.internal.applications; + +import java.util.Iterator; +import java.util.concurrent.ConcurrentHashMap; +import javax.ws.rs.core.Application; +import org.eclipse.osee.authorization.admin.AuthorizationAdmin; +import org.eclipse.osee.jaxrs.server.internal.JaxRsConfiguration; +import org.eclipse.osee.jaxrs.server.internal.JaxRsConstants; +import org.eclipse.osee.jaxrs.server.internal.JaxRsVisitable; +import org.eclipse.osee.jaxrs.server.internal.JaxRsVisitor; +import org.eclipse.osee.jaxrs.server.internal.ext.JerseyJaxRsFactory; +import org.eclipse.osee.jaxrs.server.internal.filters.SecurityContextFilter; +import org.eclipse.osee.jaxrs.server.internal.filters.SecurityContextProviderImpl; +import org.eclipse.osee.logger.Log; +import org.osgi.framework.Bundle; +import org.osgi.service.http.HttpService; + +/** + * @author Roberto E. Escobar + */ +public class JaxRsApplicationRegistry implements JaxRsVisitable { + + public static interface JaxRsContainerProvider { + + JaxRsContainer get(); + + JaxRsContainer unSet(); + + boolean hasContainer(); + } + + public static interface JaxRsContainer { + + String getServletContext(); + + void setServletContext(String contextName); + + void addApplication(String componentName, String applicationContext, Bundle bundle, Application application); + + void removeApplication(String componentName); + + boolean isEmpty(); + + void start(); + + void stop(); + + void accept(JaxRsVisitor visitor); + } + + private final ConcurrentHashMap<String, JaxRsContainerProvider> servlets = + new ConcurrentHashMap<String, JaxRsContainerProvider>(); + + private Log logger; + private HttpService httpService; + private AuthorizationAdmin authorizationAdmin; + + private JaxRsFactory factory; + private String baseContext = JaxRsConstants.DEFAULT_JAXRS_BASE_CONTEXT; + + public void setHttpService(HttpService httpService) { + this.httpService = httpService; + } + + public void setLogger(Log logger) { + this.logger = logger; + } + + public void setAuthorizationAdmin(AuthorizationAdmin authorizationAdmin) { + this.authorizationAdmin = authorizationAdmin; + } + + public void start() { + logger.trace("Starting [%s]...", getClass().getSimpleName()); + SecurityContextProviderImpl provider = new SecurityContextProviderImpl(logger, authorizationAdmin); + SecurityContextFilter filter = new SecurityContextFilter(provider); + + factory = new JerseyJaxRsFactory(logger, httpService, filter); + } + + public void stop() { + logger.trace("Stopping [%s]...", getClass().getSimpleName()); + this.factory = null; + } + + public String getBaseContext() { + return baseContext; + } + + public synchronized void configure(JaxRsConfiguration config) { + logger.trace("Configuring [%s]...", getClass().getSimpleName()); + final String oldBaseContext = baseContext; + final String newBaseContext = config.getBaseContext(); + if (!oldBaseContext.equals(newBaseContext)) { + logger.trace("Configuration Changed for [%s] - [%s]", getClass().getSimpleName(), config); + baseContext = newBaseContext; + JaxRsContainerProvider removed = servlets.remove(oldBaseContext); + if (removed != null) { + if (removed.hasContainer()) { + JaxRsContainer container = removed.get(); + container.stop(); + container.accept(new JaxRsVisitor() { + @Override + public void onApplication(String applicationContext, String componentName, Bundle bundle, Application application) { + final String contextName = getBaseContext(); + JaxRsContainer newContainer = getContainerInitIfNull(contextName); + newContainer.addApplication(componentName, applicationContext, bundle, application); + } + }); + } + } + } + } + + public void register(String componentName, String contextName, Bundle bundle, Application application) { + final String baseContext = getBaseContext(); + JaxRsContainer container = getContainerInitIfNull(baseContext); + container.addApplication(componentName, contextName, bundle, application); + } + + public void deregister(String componentName) { + final String contextName = getBaseContext(); + JaxRsContainer container = getContainerOrNull(contextName); + if (container != null) { + container.removeApplication(componentName); + if (container.isEmpty()) { + servlets.remove(contextName); + } + } + } + + public void deregisterAll() { + Iterator<JaxRsContainerProvider> iterator = servlets.values().iterator(); + while (iterator.hasNext()) { + JaxRsContainer container = iterator.next().get(); + if (container != null) { + container.stop(); + } + iterator.remove(); + } + } + + @Override + public void accept(JaxRsVisitor visitor) { + visitor.onStartRegistry(); + try { + for (JaxRsContainerProvider provider : servlets.values()) { + if (provider.hasContainer()) { + JaxRsContainer container = provider.get(); + container.accept(visitor); + } + } + } finally { + visitor.onEndRegistry(); + } + } + + private JaxRsContainer getContainerOrNull(String contextName) { + JaxRsContainer toReturn = null; + JaxRsContainerProvider reference = servlets.get(contextName); + if (reference != null) { + toReturn = reference.get(); + } + return toReturn; + } + + private JaxRsContainer getContainerInitIfNull(String contextName) { + JaxRsContainerProvider reference = servlets.get(contextName); + if (reference == null) { + JaxRsContainerProvider newContainer = factory.newJaxRsContainerProvider(contextName); + reference = servlets.putIfAbsent(contextName, newContainer); + if (reference == null) { + reference = newContainer; + } + } + return reference.get(); + } + +}
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/applications/JaxRsContainerProviderImpl.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/applications/JaxRsContainerProviderImpl.java new file mode 100644 index 00000000000..9724a4e966a --- /dev/null +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/applications/JaxRsContainerProviderImpl.java @@ -0,0 +1,58 @@ +/******************************************************************************* + * Copyright (c) 2014 Boeing. + * 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: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.jaxrs.server.internal.applications; + +import java.util.concurrent.Callable; +import java.util.concurrent.FutureTask; +import org.eclipse.osee.framework.jdk.core.type.LazyObject; +import org.eclipse.osee.jaxrs.server.internal.applications.JaxRsApplicationRegistry.JaxRsContainer; +import org.eclipse.osee.jaxrs.server.internal.applications.JaxRsApplicationRegistry.JaxRsContainerProvider; + +/** + * @author Roberto E. Escobar + */ +public final class JaxRsContainerProviderImpl extends LazyObject<JaxRsContainer> implements JaxRsContainerProvider { + + private final JaxRsFactory factory; + private final String contextName; + private volatile JaxRsContainer container; + + public JaxRsContainerProviderImpl(JaxRsFactory factory, String contextName) { + super(); + this.factory = factory; + this.contextName = contextName; + } + + @Override + protected FutureTask<JaxRsContainer> createLoaderTask() { + return new FutureTask<JaxRsApplicationRegistry.JaxRsContainer>(new Callable<JaxRsContainer>() { + @Override + public JaxRsContainer call() throws Exception { + container = factory.newJaxRsContainer(contextName); + return container; + } + }); + } + + @Override + public boolean hasContainer() { + return container != null; + } + + @Override + public JaxRsContainer unSet() { + JaxRsContainer oldContainer = container; + container = null; + invalidate(); + return oldContainer; + } + +}
\ No newline at end of file diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/applications/JaxRsFactory.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/applications/JaxRsFactory.java new file mode 100644 index 00000000000..425cdee68ca --- /dev/null +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/applications/JaxRsFactory.java @@ -0,0 +1,25 @@ +/******************************************************************************* + * Copyright (c) 2014 Boeing. + * 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: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.jaxrs.server.internal.applications; + +import org.eclipse.osee.jaxrs.server.internal.applications.JaxRsApplicationRegistry.JaxRsContainer; +import org.eclipse.osee.jaxrs.server.internal.applications.JaxRsApplicationRegistry.JaxRsContainerProvider; + +/** + * @author Roberto E. Escobar + */ +public interface JaxRsFactory { + + JaxRsContainerProvider newJaxRsContainerProvider(String contextName); + + JaxRsContainer newJaxRsContainer(String contextName); + +} diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/GenericExceptionMapper.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/exceptions/GenericExceptionMapper.java index 941a298f2f8..434eaf16747 100644 --- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/GenericExceptionMapper.java +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/exceptions/GenericExceptionMapper.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2013 Boeing. + * Copyright (c) 2014 Boeing. * 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 @@ -8,7 +8,7 @@ * Contributors: * Boeing - initial API and implementation *******************************************************************************/ -package org.eclipse.osee.jaxrs.server.internal; +package org.eclipse.osee.jaxrs.server.internal.exceptions; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.Response; diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/ext/JerseyJaxRsFactory.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/ext/JerseyJaxRsFactory.java new file mode 100644 index 00000000000..a18e890b776 --- /dev/null +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/ext/JerseyJaxRsFactory.java @@ -0,0 +1,210 @@ +/******************************************************************************* + * Copyright (c) 2014 Boeing. + * 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: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.jaxrs.server.internal.ext; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Dictionary; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.List; +import java.util.Map; +import java.util.concurrent.atomic.AtomicBoolean; +import javax.servlet.http.HttpServlet; +import javax.ws.rs.core.Application; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response.Status; +import org.eclipse.osee.jaxrs.OseeWebApplicationException; +import org.eclipse.osee.jaxrs.server.internal.JaxRsUtils; +import org.eclipse.osee.jaxrs.server.internal.JaxRsVisitable; +import org.eclipse.osee.jaxrs.server.internal.applications.AbstractJaxRsApplicationContainer; +import org.eclipse.osee.jaxrs.server.internal.applications.AbstractJaxRsContainer; +import org.eclipse.osee.jaxrs.server.internal.applications.JaxRsApplicationRegistry.JaxRsContainer; +import org.eclipse.osee.jaxrs.server.internal.applications.JaxRsApplicationRegistry.JaxRsContainerProvider; +import org.eclipse.osee.jaxrs.server.internal.applications.JaxRsContainerProviderImpl; +import org.eclipse.osee.jaxrs.server.internal.applications.JaxRsFactory; +import org.eclipse.osee.jaxrs.server.internal.exceptions.GenericExceptionMapper; +import org.eclipse.osee.jaxrs.server.internal.filters.SecureResourceFilterFactory; +import org.eclipse.osee.jaxrs.server.internal.filters.SecurityContextFilter; +import org.eclipse.osee.jaxrs.server.internal.resources.ServicesResource; +import org.eclipse.osee.logger.Log; +import org.osgi.service.http.HttpService; +import com.sun.jersey.api.container.filter.UriConnegFilter; +import com.sun.jersey.api.core.DefaultResourceConfig; +import com.sun.jersey.api.core.ResourceConfig; +import com.sun.jersey.spi.container.ResourceFilterFactory; +import com.sun.jersey.spi.container.servlet.ServletContainer; + +/** + * @author Roberto E. Escobar + */ +public final class JerseyJaxRsFactory implements JaxRsFactory { + + private final Log logger; + private final HttpService httpService; + private final SecurityContextFilter securityContextFilter; + + private List<Object> singletons; + private List<Object> requestFilters; + + public JerseyJaxRsFactory(Log logger, HttpService httpService, SecurityContextFilter securityContextFilter) { + super(); + this.logger = logger; + this.httpService = httpService; + this.securityContextFilter = securityContextFilter; + } + + @Override + public JaxRsContainerProvider newJaxRsContainerProvider(String contextName) { + return new JaxRsContainerProviderImpl(this, contextName); + } + + @Override + public JaxRsContainer newJaxRsContainer(String contextName) { + Dictionary<String, Object> props = new Hashtable<String, Object>(); + JerseyJaxRsContainer container = new JerseyJaxRsContainer(logger, httpService, props); + container.setServletContext(contextName); + logger.trace("Create - [%s]", container); + return container; + } + + private List<Object> getResourceSingletons() { + if (singletons == null) { + List<Object> resources = new ArrayList<Object>(); + resources.add(new GenericExceptionMapper(logger)); + singletons = resources; + } + return singletons; + } + + private List<Object> getRequestFilters() { + if (requestFilters == null) { + List<Object> resources = new ArrayList<Object>(); + Map<String, MediaType> mappings = new HashMap<String, MediaType>(); + mappings.put("xml", MediaType.APPLICATION_XML_TYPE); + mappings.put("json", MediaType.APPLICATION_JSON_TYPE); + UriConnegFilter filter1 = new UriConnegFilter(mappings); + resources.add(filter1); + requestFilters = resources; + } + return requestFilters; + } + + private List<ResourceFilterFactory> getResourceFilterFactories() { + SecureResourceFilterFactory filterFactory = new SecureResourceFilterFactory(logger, securityContextFilter); + return Collections.<ResourceFilterFactory> singletonList(filterFactory); + } + + private JerseyJaxRsApplicationContainer newApplicationContainer(String applicationContext) { + return new JerseyJaxRsApplicationContainer(applicationContext); + } + + private DefaultResourceConfig newResourceConfig() { + DefaultResourceConfig config = new DefaultResourceConfig(); + Map<String, Object> properties = config.getProperties(); + properties.put(ResourceConfig.PROPERTY_CONTAINER_REQUEST_FILTERS, getRequestFilters()); + properties.put(ResourceConfig.PROPERTY_RESOURCE_FILTER_FACTORIES, getResourceFilterFactories()); + for (Object resource : getResourceSingletons()) { + config.getSingletons().add(resource); + } + return config; + } + + private HttpServlet newBaseJaxsRsServlet(JaxRsVisitable visitable) { + DefaultResourceConfig config = newResourceConfig(); + config.getSingletons().add(new ServicesResource(visitable)); + return new ServletContainer(config); + } + + private HttpServlet newApplicationServlet(JaxRsVisitable visitable, Application application) { + DefaultResourceConfig config = newResourceConfig(); + config.add(application); + JerseyWadlGeneratorConfig wadl = new JerseyWadlGeneratorConfig(logger, visitable); + Map<String, Object> properties = config.getProperties(); + if (wadl.hasExtendedWadl()) { + properties.put(ResourceConfig.PROPERTY_WADL_GENERATOR_CONFIG, wadl); + } else { + properties.remove(ResourceConfig.PROPERTY_WADL_GENERATOR_CONFIG); + } + return new ServletContainer(config); + } + + private final class JerseyJaxRsContainer extends AbstractJaxRsContainer<HttpServlet, JerseyJaxRsApplicationContainer> { + + public JerseyJaxRsContainer(Log logger, HttpService httpService, Dictionary<String, Object> props) { + super(logger, httpService, props); + } + + @Override + protected JerseyJaxRsApplicationContainer createApplicationContainer(String applicationContext) { + return newApplicationContainer(applicationContext); + } + + @Override + protected HttpServlet createBaseJaxsRsServlet(JaxRsVisitable visitable) { + return newBaseJaxsRsServlet(visitable); + } + + @Override + protected void startContainer(JerseyJaxRsApplicationContainer container) { + String baseContext = getServletContext(); + Dictionary<String, Object> properties = getServletProperties(); + HttpService httpService = getHttpService(); + container.startContainer(httpService, baseContext, properties); + } + + @Override + protected void stopContainer(JerseyJaxRsApplicationContainer container) { + String baseContext = getServletContext(); + HttpService httpService = getHttpService(); + container.stopContainer(httpService, baseContext); + } + + }; + + private final class JerseyJaxRsApplicationContainer extends AbstractJaxRsApplicationContainer { + + private final AtomicBoolean isRegistered = new AtomicBoolean(false); + + public JerseyJaxRsApplicationContainer(String applicationContext) { + super(applicationContext); + } + + public void startContainer(HttpService httpService, String baseContext, Dictionary<String, Object> props) { + if (!isRegistered.getAndSet(true)) { + String contextName = getAbsoluteContext(baseContext); + Application application = getApplication(); + HttpServlet servlet = newApplicationServlet(this, application); + try { + httpService.registerServlet(contextName, servlet, props, null); + } catch (Exception ex) { + throw new OseeWebApplicationException(ex, Status.INTERNAL_SERVER_ERROR, + "Error registering servlet [%s] ", contextName); + } + } + } + + public void stopContainer(HttpService httpService, String baseContext) { + if (isRegistered.getAndSet(false)) { + String contextName = getAbsoluteContext(baseContext); + httpService.unregister(contextName); + } + } + + private String getAbsoluteContext(String baseContext) { + String appPath = JaxRsUtils.normalize(getApplicationContext()); + String path = String.format("%s%s", baseContext, appPath); + path = path.replaceAll("//", "/"); + return path; + } + } + +} diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/BundleWadlGeneratorConfig.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/ext/JerseyWadlGeneratorConfig.java index 3911c64af50..8a9b431c946 100644 --- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/BundleWadlGeneratorConfig.java +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/ext/JerseyWadlGeneratorConfig.java @@ -8,14 +8,18 @@ * Contributors: * Boeing - initial API and implementation *******************************************************************************/ -package org.eclipse.osee.jaxrs.server.internal; +package org.eclipse.osee.jaxrs.server.internal.ext; import java.io.IOException; import java.io.InputStream; import java.net.URL; +import java.util.ArrayList; import java.util.Collections; import java.util.List; +import javax.ws.rs.core.Application; import org.eclipse.osee.framework.jdk.core.util.Lib; +import org.eclipse.osee.jaxrs.server.internal.JaxRsVisitable; +import org.eclipse.osee.jaxrs.server.internal.JaxRsVisitor; import org.eclipse.osee.logger.Log; import org.osgi.framework.Bundle; import com.google.common.io.InputSupplier; @@ -28,19 +32,31 @@ import com.sun.jersey.server.wadl.generators.resourcedoc.WadlGeneratorResourceDo /** * @author Roberto E. Escobar */ -public class BundleWadlGeneratorConfig extends WadlGeneratorConfig { +public class JerseyWadlGeneratorConfig extends WadlGeneratorConfig { private final Log logger; - private final ObjectProvider<Iterable<Bundle>> provider; + private final JaxRsVisitable visitable; - public BundleWadlGeneratorConfig(Log logger, ObjectProvider<Iterable<Bundle>> provider) { + public JerseyWadlGeneratorConfig(Log logger, JaxRsVisitable visitable) { this.logger = logger; - this.provider = provider; + this.visitable = visitable; + } + + private Iterable<Bundle> getBundles() { + final List<Bundle> bundles = new ArrayList<Bundle>(); + visitable.accept(new JaxRsVisitor() { + + @Override + public void onApplication(String applicationContext, String componentName, Bundle bundle, Application application) { + bundles.add(bundle); + } + }); + return bundles; } public boolean hasExtendedWadl() { boolean result = false; - Iterable<Bundle> bundles = provider.get(); + Iterable<Bundle> bundles = getBundles(); for (Bundle bundle : bundles) { result = hasExtendedWadl(bundle); if (result) { @@ -92,7 +108,7 @@ public class BundleWadlGeneratorConfig extends WadlGeneratorConfig { private InputStream getAsInputStream(String path, String xmlRoot) throws Exception { RestResourceConcatenator concat = new RestResourceConcatenator(); concat.initialize(xmlRoot); - Iterable<Bundle> bundles = provider.get(); + Iterable<Bundle> bundles = getBundles(); for (Bundle bundle : bundles) { if (hasExtendedWadl(bundle)) { URL url = bundle.getResource(path); diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/RestResourceConcatenator.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/ext/RestResourceConcatenator.java index 0e96e54e0f4..98e779a01cd 100644 --- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/RestResourceConcatenator.java +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/ext/RestResourceConcatenator.java @@ -8,7 +8,7 @@ * Contributors: * Boeing - initial API and implementation *******************************************************************************/ -package org.eclipse.osee.jaxrs.server.internal; +package org.eclipse.osee.jaxrs.server.internal.ext; import java.io.IOException; import java.io.InputStream; diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/filters/SecurityContextFilter.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/filters/SecurityContextFilter.java index a50be71487f..d63babbd6b9 100644 --- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/filters/SecurityContextFilter.java +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/filters/SecurityContextFilter.java @@ -12,7 +12,6 @@ package org.eclipse.osee.jaxrs.server.internal.filters; import javax.ws.rs.core.SecurityContext; import javax.ws.rs.ext.Provider; -import org.eclipse.osee.jaxrs.server.internal.SecurityContextProvider; import com.sun.jersey.spi.container.ContainerRequest; import com.sun.jersey.spi.container.ContainerRequestFilter; import com.sun.jersey.spi.container.ContainerResponseFilter; diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/SecurityContextProvider.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/filters/SecurityContextProvider.java index 927e9c04a5f..e6a6e60d03c 100644 --- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/SecurityContextProvider.java +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/filters/SecurityContextProvider.java @@ -8,7 +8,7 @@ * Contributors: * Boeing - initial API and implementation *******************************************************************************/ -package org.eclipse.osee.jaxrs.server.internal; +package org.eclipse.osee.jaxrs.server.internal.filters; import javax.ws.rs.core.SecurityContext; import com.sun.jersey.api.core.HttpRequestContext; diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/filters/SecurityContextProviderImpl.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/filters/SecurityContextProviderImpl.java index 7d2d677527b..c4703a6192a 100644 --- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/filters/SecurityContextProviderImpl.java +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/filters/SecurityContextProviderImpl.java @@ -22,7 +22,6 @@ import org.eclipse.osee.authorization.admin.AuthorizationRequest; import org.eclipse.osee.authorization.admin.AuthorizationRequestBuilder; import org.eclipse.osee.framework.jdk.core.util.Strings; import org.eclipse.osee.jaxrs.OseeWebApplicationException; -import org.eclipse.osee.jaxrs.server.internal.SecurityContextProvider; import org.eclipse.osee.logger.Log; import com.sun.jersey.api.core.HttpRequestContext; diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/resources/ApplicationResource.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/resources/ApplicationResource.java new file mode 100644 index 00000000000..2cefbedf407 --- /dev/null +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/resources/ApplicationResource.java @@ -0,0 +1,91 @@ +/******************************************************************************* + * Copyright (c) 2014 Boeing. + * 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: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.jaxrs.server.internal.resources; + +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Dictionary; +import java.util.List; +import javax.annotation.security.PermitAll; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Application; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.UriBuilder; +import javax.ws.rs.core.UriInfo; +import org.eclipse.osee.jaxrs.ApplicationInfo; +import org.eclipse.osee.jaxrs.server.internal.JaxRsVisitable; +import org.eclipse.osee.jaxrs.server.internal.JaxRsVisitor; +import org.osgi.framework.Bundle; +import org.osgi.framework.Constants; + +/** + * @author Roberto E. Escobar + */ +@Path("application-details") +public class ApplicationResource { + + private final JaxRsVisitable visitable; + + public ApplicationResource(JaxRsVisitable visitable) { + super(); + this.visitable = visitable; + } + + @PermitAll + @GET + @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) + public List<ApplicationInfo> getApplicationsInfo(final @Context UriInfo uriInfo) { + final List<ApplicationInfo> toReturn = new ArrayList<ApplicationInfo>(); + + visitable.accept(new JaxRsVisitor() { + @Override + public void onApplication(String applicationContext, String componentName, Bundle bundle, Application application) { + Dictionary<String, String> headers = bundle.getHeaders(); + + String bundleName = headers.get(Constants.BUNDLE_SYMBOLICNAME); + String bundleVersion = headers.get(Constants.BUNDLE_VERSION); + + ApplicationInfo info = new ApplicationInfo(); + info.setBundleName(bundleName); + info.setVersion(bundleVersion); + info.setApplicationName(componentName); + + String absolutePath = getServletPath(); + + URI build = UriBuilder.fromPath(absolutePath).path(applicationContext).path("application.wadl").build(); + String path = build.toASCIIString(); + info.setUri(path); + toReturn.add(info); + } + + private String getServletPath() { + String absolutePath = uriInfo.getAbsolutePath().toASCIIString(); + absolutePath = absolutePath.replaceAll("/jaxrs-admin/application-details", ""); + return absolutePath; + } + + }); + Collections.sort(toReturn, new Comparator<ApplicationInfo>() { + + @Override + public int compare(ApplicationInfo o1, ApplicationInfo o2) { + return o1.getApplicationName().compareTo(o2.getApplicationName()); + } + + }); + return toReturn; + } +} diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/resources/ApplicationsResource.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/resources/ApplicationsResource.java deleted file mode 100644 index d104cb40992..00000000000 --- a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/resources/ApplicationsResource.java +++ /dev/null @@ -1,78 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2014 Boeing. - * 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: - * Boeing - initial API and implementation - *******************************************************************************/ -package org.eclipse.osee.jaxrs.server.internal.resources; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Dictionary; -import java.util.List; -import javax.ws.rs.GET; -import javax.ws.rs.Path; -import javax.ws.rs.Produces; -import javax.ws.rs.core.Application; -import javax.ws.rs.core.MediaType; -import org.eclipse.osee.jaxrs.ApplicationInfo; -import org.eclipse.osee.jaxrs.server.internal.ObjectProvider; -import org.eclipse.osee.jaxrs.server.internal.RestServiceUtils; -import org.osgi.framework.Bundle; -import org.osgi.framework.BundleContext; -import org.osgi.framework.Constants; -import org.osgi.framework.ServiceReference; - -/** - * @author Roberto E. Escobar - */ -@Path("application-details") -public class ApplicationsResource { - - private final ObjectProvider<Iterable<Bundle>> provider; - - public ApplicationsResource(ObjectProvider<Iterable<Bundle>> provider) { - super(); - this.provider = provider; - } - - @GET - @Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML}) - public List<ApplicationInfo> getApplicationsInfo() { - List<ApplicationInfo> toReturn = new ArrayList<ApplicationInfo>(); - Iterable<Bundle> bundles = provider.get(); - for (Bundle bundle : bundles) { - Dictionary<String, String> headers = bundle.getHeaders(); - - String bundleName = headers.get(Constants.BUNDLE_SYMBOLICNAME); - String bundleVersion = headers.get(Constants.BUNDLE_VERSION); - - BundleContext bundleContext = bundle.getBundleContext(); - - ServiceReference<?>[] references = bundle.getRegisteredServices(); - for (ServiceReference<?> reference : references) { - String[] object = (String[]) reference.getProperty("objectClass"); - String clazzType = Arrays.deepToString(object); - if (clazzType.contains(Application.class.getSimpleName())) { - String componentName = RestServiceUtils.getComponentName(reference); - - Application application = (Application) bundleContext.getService(reference); - String applicationContext = RestServiceUtils.getApplicationPath(componentName, application); - - ApplicationInfo info = new ApplicationInfo(); - info.setBundleName(bundleName); - info.setVersion(bundleVersion); - info.setApplicationName(componentName); - info.setUri(applicationContext); - toReturn.add(info); - } - - } - } - return toReturn; - } -} diff --git a/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/resources/ServicesResource.java b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/resources/ServicesResource.java new file mode 100644 index 00000000000..2342c48520d --- /dev/null +++ b/plugins/org.eclipse.osee.jaxrs.server/src/org/eclipse/osee/jaxrs/server/internal/resources/ServicesResource.java @@ -0,0 +1,96 @@ +/******************************************************************************* + * Copyright (c) 2014 Boeing. + * 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: + * Boeing - initial API and implementation + *******************************************************************************/ +package org.eclipse.osee.jaxrs.server.internal.resources; + +import javax.annotation.security.PermitAll; +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Application; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.UriBuilder; +import javax.ws.rs.core.UriInfo; +import org.eclipse.osee.jaxrs.server.internal.JaxRsVisitable; +import org.eclipse.osee.jaxrs.server.internal.JaxRsVisitor; +import org.osgi.framework.Bundle; + +/** + * @author Roberto E. Escobar + */ +@Path("services") +public class ServicesResource { + + private static final String CSS = "<style>" + "@CHARSET \"ISO-8859-1\"; " + // + ".heading { font-size: large; } " + // + ".field { font-weight: bold; } " + // + ".value { font-weight: normal; } " + // + ".porttypename { font-weight: bold; } " + // + "table { border: solid; border-collapse: collapse; border-width: 2px; } " + // + "td { border: solid; border-width: 1px; vertical-align: text-top; padding: 5px; } " + // + "</style>"; + + private final JaxRsVisitable visitable; + + public ServicesResource(JaxRsVisitable visitable) { + super(); + this.visitable = visitable; + } + + @PermitAll + @GET + @Produces(MediaType.TEXT_HTML) + public String getServices(final @Context UriInfo uriInfo) { + final StringBuilder builder = new StringBuilder(); + builder.append("<html>"); + builder.append("<head>"); + builder.append(CSS); + builder.append("<meta http-equiv=content-type content=\"text/html; charset=UTF-8\">"); + builder.append("<title>JAX-RS - Service list</title>"); + builder.append("</head>"); + builder.append("<br/><span class=\"heading\">Available RESTful services:</span><br/>"); + builder.append("<table cellpadding=\"1\" cellspacing=\"1\" border=\"1\" width=\"100%\">"); + + visitable.accept(new JaxRsVisitor() { + + @Override + public void onApplication(String applicationContext, String componentName, Bundle bundle, Application application) { + String absolutePath = getServletPath(); + UriBuilder uriBuilder = UriBuilder.fromPath(absolutePath).path(applicationContext); + String baseApplicationPath = uriBuilder.build().toASCIIString(); + String wadlPath = uriBuilder.path("application.wadl").build().toASCIIString(); + + builder.append("<tr><td>"); + builder.append("<span class=\"field\">Endpoint address:</span>"); + builder.append("<span class=\"value\">"); + builder.append(baseApplicationPath); + builder.append("</span>"); + builder.append("<br />"); + builder.append("<span class=\"field\">WADL :</span>"); + builder.append("<a href=\""); + builder.append(wadlPath); + builder.append("\">"); + builder.append(wadlPath); + builder.append("</a></td></tr>"); + } + + private String getServletPath() { + String absolutePath = uriInfo.getAbsolutePath().toASCIIString(); + absolutePath = absolutePath.replaceAll("/services", ""); + return absolutePath; + } + }); + builder.append("</table>"); + builder.append("</html>"); + return builder.toString(); + } + +} |