From: Mirjan Merruko Date: Tue, 4 Apr 2017 14:05:27 +0000 (+0300) Subject: Add scr component to help registering VaadinServlet configurations X-Git-Tag: 8.1.0.alpha7~59 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=de7a16aee8544ea20be2f5ac9c9ed3d85b35a8a4;p=vaadin-framework.git Add scr component to help registering VaadinServlet configurations This component will detect VaadinServlet configurations, add the static resource configuration property and then register a servlet using the HttpWhiteboard specification. This works with pax-jetty but not pax-http-tomcat. Partly covers #7173 --- diff --git a/osgi-integration/bnd.bnd b/osgi-integration/bnd.bnd new file mode 100644 index 0000000000..1244665199 --- /dev/null +++ b/osgi-integration/bnd.bnd @@ -0,0 +1,7 @@ +Bundle-SymbolicName: ${project.groupId}.osgi.integration +Bundle-Name: Vaadin OSGi Integration +Bundle-Version: ${osgi.bundle.version} +Import-Package: com.vaadin.*;version='[${osgi.bundle.version},${osgi.bundle.version}]',\ + * + +Export-Package: com.vaadin.osgi.servlet \ No newline at end of file diff --git a/osgi-integration/pom.xml b/osgi-integration/pom.xml new file mode 100644 index 0000000000..ef91b89b6a --- /dev/null +++ b/osgi-integration/pom.xml @@ -0,0 +1,97 @@ + + 4.0.0 + vaadin-osgi-integration + jar + https://vaadin.com/ + OSGi Integration + + + com.vaadin + vaadin-root + 8.0-SNAPSHOT + + + + UTF-8 + 1.8 + 1.8 + + + + + + + org.osgi + osgi.core + + + org.osgi + osgi.annotation + + + org.osgi + osgi.cmpn + + + + ${project.groupId} + vaadin-shared + ${project.version} + + + ${project.groupId} + vaadin-server + ${project.version} + + + + javax.servlet + javax.servlet-api + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.1 + + + org.apache.maven.plugins + maven-checkstyle-plugin + + + + checkstyle + + process-sources + + + + + biz.aQute.bnd + bnd-maven-plugin + + + + org.apache.maven.plugins + maven-jar-plugin + + + ${project.build.outputDirectory}/META-INF/MANIFEST.MF + false + + true + + + + + + + + diff --git a/osgi-integration/src/main/java/com/vaadin/osgi/servlet/VaadinServletRegistration.java b/osgi-integration/src/main/java/com/vaadin/osgi/servlet/VaadinServletRegistration.java new file mode 100644 index 0000000000..8a0592fb58 --- /dev/null +++ b/osgi-integration/src/main/java/com/vaadin/osgi/servlet/VaadinServletRegistration.java @@ -0,0 +1,136 @@ +/* + * Copyright 2000-2016 Vaadin Ltd. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ +package com.vaadin.osgi.servlet; + +import java.util.Hashtable; + +import javax.servlet.Servlet; +import javax.servlet.annotation.WebServlet; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Reference; +import org.osgi.service.component.annotations.ReferenceCardinality; +import org.osgi.service.component.annotations.ReferencePolicy; +import org.osgi.service.http.whiteboard.HttpWhiteboardConstants; +import org.osgi.service.log.LogService; + +import com.vaadin.osgi.resources.OSGiVaadinResources; +import com.vaadin.osgi.resources.OSGiVaadinResources.ResourceBundleInactiveException; +import com.vaadin.osgi.resources.VaadinResourceService; +import com.vaadin.server.Constants; +import com.vaadin.server.VaadinServlet; + +/** + * This component tracks {@link VaadinServlet} registrations, configures them + * with the appropriate path to the Vaadin static resources and registers a + * {@link Servlet} using the HttpWhiteboard specification. + * + * @author Vaadin Ltd. + * + * @since 8.1 + */ +@Component(immediate = true) +public class VaadinServletRegistration { + private static final String MISSING_ANNOTATION_MESSAGE_FORMAT = "The property '%s' must be set in a '%s' without the '%s' annotation!"; + private static final String URL_PATTERNS_NOT_SET_MESSAGE_FORMAT = "The property '%s' must be set when the 'urlPatterns' attribute is not set!"; + + private static final String SERVLET_PATTERN = HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_PATTERN; + + private static final String VAADIN_RESOURCES_PARAM = HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_INIT_PARAM_PREFIX + + Constants.PARAMETER_VAADIN_RESOURCES; + + private LogService logService; + + @Reference(cardinality = ReferenceCardinality.MULTIPLE, service = VaadinServlet.class, policy = ReferencePolicy.DYNAMIC) + void bindVaadinServlet(ServiceReference reference) + throws ResourceBundleInactiveException { + log(LogService.LOG_WARNING, "VaadinServlet Registration"); + BundleContext bundleContext = reference.getBundle().getBundleContext(); + Hashtable properties = getProperties(reference); + + VaadinServlet servlet = bundleContext.getService(reference); + + WebServlet annotation = servlet.getClass() + .getAnnotation(WebServlet.class); + + if (!validateSettings(annotation, properties)) + return; + + properties.put(VAADIN_RESOURCES_PARAM, getResourcePath()); + if (annotation != null) { + properties.put( + HttpWhiteboardConstants.HTTP_WHITEBOARD_SERVLET_ASYNC_SUPPORTED, + Boolean.toString(annotation.asyncSupported())); + } + + bundleContext.registerService(Servlet.class, servlet, properties); + bundleContext.ungetService(reference); + } + + private boolean validateSettings(WebServlet annotation, + Hashtable properties) { + if (!properties.containsKey(SERVLET_PATTERN)) { + if (annotation == null) { + log(LogService.LOG_ERROR, + String.format(MISSING_ANNOTATION_MESSAGE_FORMAT, + SERVLET_PATTERN, + VaadinServlet.class.getSimpleName(), + WebServlet.class.getName())); + return false; + } else if (annotation.urlPatterns().length == 0) { + log(LogService.LOG_ERROR, String.format( + URL_PATTERNS_NOT_SET_MESSAGE_FORMAT, SERVLET_PATTERN)); + return false; + } + } + return true; + } + + private String getResourcePath() throws ResourceBundleInactiveException { + VaadinResourceService service = OSGiVaadinResources.getService(); + return String.format("/%s", service.getResourcePathPrefix()); + } + + private void log(int level, String message) { + if (logService != null) { + logService.log(level, message); + } + } + + void unbindVaadinServlet(VaadinServlet servlet) { + + } + + @Reference(cardinality = ReferenceCardinality.OPTIONAL) + void setLogService(LogService logService) { + this.logService = logService; + } + + void unsetLogService(LogService logService) { + this.logService = null; + } + + private Hashtable getProperties( + ServiceReference reference) { + Hashtable properties = new Hashtable<>(); + for (String key : reference.getPropertyKeys()) { + properties.put(key, reference.getProperty(key)); + } + return properties; + } +} diff --git a/pom.xml b/pom.xml index 12aee97965..0a9931b6ba 100644 --- a/pom.xml +++ b/pom.xml @@ -619,6 +619,7 @@ uitest liferay liferay-integration + osgi-integration all compatibility-server compatibility-server-gae @@ -670,6 +671,7 @@ compatibility-shared compatibility-themes liferay-integration + osgi-integration testbench-api @@ -736,6 +738,7 @@ compatibility-shared compatibility-themes liferay-integration + osgi-integration testbench-api @@ -802,6 +805,7 @@ compatibility-shared compatibility-themes liferay-integration + osgi-integration testbench-api bom @@ -862,6 +866,7 @@ shared compatibility-shared liferay-integration + osgi-integration diff --git a/scripts/GenerateBuildTestAndStagingReport.py b/scripts/GenerateBuildTestAndStagingReport.py index fd75f30217..f87b72ce3f 100644 --- a/scripts/GenerateBuildTestAndStagingReport.py +++ b/scripts/GenerateBuildTestAndStagingReport.py @@ -74,6 +74,7 @@ def getApiDiffHtml(): "compatibility-server-gae", "compatibility-shared", "liferay-integration", + "osgi-integration", "server", "shared" ] link_list = list(map(lambda module: "{}".format(args.teamcityUrl, args.buildTypeId, args.buildId, module, module), modules)) @@ -123,7 +124,7 @@ def completeArtifactNames(artifactIds, version): return list(map(lambda x: completeArtifactName(x, version), artifactIds)) -allowedArtifacts = completeArtifactNames([ 'vaadin-maven-plugin', 'vaadin-archetypes', 'vaadin-archetype-application', 'vaadin-archetype-application-multimodule', 'vaadin-archetype-application-example', 'vaadin-archetype-widget', 'vaadin-archetype-liferay-portlet', 'vaadin-root', 'vaadin-shared', 'vaadin-server', 'vaadin-client', 'vaadin-client-compiler', 'vaadin-client-compiled', 'vaadin-push', 'vaadin-themes', 'vaadin-compatibility-shared', 'vaadin-compatibility-server', "vaadin-compatibility-server-gae", 'vaadin-compatibility-client', 'vaadin-compatibility-client-compiled', 'vaadin-compatibility-themes', 'vaadin-liferay-integration', 'vaadin-testbench-api', 'vaadin-bom' ], args.version) +allowedArtifacts = completeArtifactNames([ 'vaadin-maven-plugin', 'vaadin-archetypes', 'vaadin-archetype-application', 'vaadin-archetype-application-multimodule', 'vaadin-archetype-application-example', 'vaadin-archetype-widget', 'vaadin-archetype-liferay-portlet', 'vaadin-root', 'vaadin-shared', 'vaadin-server', 'vaadin-client', 'vaadin-client-compiler', 'vaadin-client-compiled', 'vaadin-push', 'vaadin-themes', 'vaadin-compatibility-shared', 'vaadin-compatibility-server', "vaadin-compatibility-server-gae", 'vaadin-compatibility-client', 'vaadin-compatibility-client-compiled', 'vaadin-compatibility-themes', 'vaadin-liferay-integration', "vaadin-osgi-integration", 'vaadin-testbench-api', 'vaadin-bom' ], args.version) content = "" traffic_light = ""