diff options
author | Mirjan Merruko <mirjan@vaadin.com> | 2017-03-24 13:45:21 +0200 |
---|---|---|
committer | Henri Sara <henri.sara@gmail.com> | 2017-04-25 15:01:06 +0300 |
commit | 16a460fa016e28b32f49b17fa763bda15249d501 (patch) | |
tree | b9ed560728f07d8a293cc92a96c88aee94931f5a /liferay-integration | |
parent | e1b923f90623d7dcdbe355225a4049323dabacf7 (diff) | |
download | vaadin-framework-16a460fa016e28b32f49b17fa763bda15249d501.tar.gz vaadin-framework-16a460fa016e28b32f49b17fa763bda15249d501.zip |
Add liferay integration originally developed by Sampsa Sohlman #8834
Diffstat (limited to 'liferay-integration')
8 files changed, 572 insertions, 0 deletions
diff --git a/liferay-integration/bnd.bnd b/liferay-integration/bnd.bnd new file mode 100644 index 0000000000..53295f4db9 --- /dev/null +++ b/liferay-integration/bnd.bnd @@ -0,0 +1,6 @@ +Bundle-SymbolicName: ${project.groupId}.liferay.integration +Bundle-Name: Vaadin Liferay Integration +Bundle-Version: ${osgi.bundle.version} +Import-Package: com.vaadin.*;version='[${osgi.bundle.version},${osgi.bundle.version}]',\ + * +Export-Package: com.vaadin.osgi.liferay*;-noimport:=true diff --git a/liferay-integration/pom.xml b/liferay-integration/pom.xml new file mode 100644 index 0000000000..e6de0d6b29 --- /dev/null +++ b/liferay-integration/pom.xml @@ -0,0 +1,110 @@ +<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> + <modelVersion>4.0.0</modelVersion> + <artifactId>vaadin-liferay-integration</artifactId> + <packaging>jar</packaging> + <url>https://vaadin.com/</url> + <description>Liferay integration</description> + + <parent> + <groupId>com.vaadin</groupId> + <artifactId>vaadin-root</artifactId> + <version>8.0-SNAPSHOT</version> + </parent> + + <properties> + <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> + <maven.compiler.source>1.8</maven.compiler.source> + <maven.compiler.target>1.8</maven.compiler.target> + <liferay.version>7.0.2-ga3</liferay.version> + </properties> + + <dependencies> + + <!-- OSGi Dependencies --> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>osgi.core</artifactId> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>osgi.annotation</artifactId> + </dependency> + <dependency> + <groupId>org.osgi</groupId> + <artifactId>osgi.cmpn</artifactId> + </dependency> + + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>vaadin-shared</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>vaadin-server</artifactId> + <version>${project.version}</version> + </dependency> + <dependency> + <groupId>${project.groupId}</groupId> + <artifactId>vaadin-push</artifactId> + <version>${project.version}</version> + </dependency> + + <!-- Liferay dependencies --> + + <dependency> + <groupId>javax.portlet</groupId> + <artifactId>portlet-api</artifactId> + </dependency> + + <dependency> + <groupId>javax.servlet</groupId> + <artifactId>javax.servlet-api</artifactId> + </dependency> + </dependencies> + + <build> + <plugins> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-compiler-plugin</artifactId> + <version>3.1</version> + </plugin> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-checkstyle-plugin</artifactId> + <executions> + <execution> + <goals> + <goal>checkstyle</goal> + </goals> + <phase>process-sources</phase> + </execution> + </executions> + </plugin> + <plugin> + <groupId>biz.aQute.bnd</groupId> + <artifactId>bnd-maven-plugin</artifactId> + </plugin> + <!-- This is required to copy the bnd generated MANIFEST.MF to the jar. + https://issues.apache.org/jira/browse/MJAR-193 is supposed to address this + issue, but at the time of writing this the configuration is necessary. Check + https://github.com/bndtools/bnd/tree/master/maven/bnd-maven-plugin --> + <plugin> + <groupId>org.apache.maven.plugins</groupId> + <artifactId>maven-jar-plugin</artifactId> + <configuration> + <archive> + <manifestFile>${project.build.outputDirectory}/META-INF/MANIFEST.MF</manifestFile> + <index>false</index> + <manifest> + <addDefaultImplementationEntries>true</addDefaultImplementationEntries> + </manifest> + </archive> + </configuration> + </plugin> + </plugins> + </build> + +</project> diff --git a/liferay-integration/src/main/java/com/vaadin/osgi/liferay/OSGiUIProvider.java b/liferay-integration/src/main/java/com/vaadin/osgi/liferay/OSGiUIProvider.java new file mode 100644 index 0000000000..1d71238ba5 --- /dev/null +++ b/liferay-integration/src/main/java/com/vaadin/osgi/liferay/OSGiUIProvider.java @@ -0,0 +1,57 @@ +/* + * 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.liferay; + +import org.osgi.framework.ServiceObjects; + +import com.vaadin.server.UIClassSelectionEvent; +import com.vaadin.server.UIProvider; +import com.vaadin.ui.UI; + +/** + * Vaadin {@link com.vaadin.server.UIProvider} that provides a single {@link UI} + * class provided through the registration of a {@link UI} as an OSGi service. + * + * @author Sampsa Sohlman + * + * @since 8.1 + */ +@SuppressWarnings("serial") +public class OSGiUIProvider extends UIProvider { + private Class<UI> uiClass; + + @SuppressWarnings("unchecked") + public OSGiUIProvider(ServiceObjects<UI> serviceObjects) { + super(); + UI ui = serviceObjects.getService(); + uiClass = (Class<UI>) ui.getClass(); + serviceObjects.ungetService(ui); + } + + @Override + public Class<? extends UI> getUIClass(UIClassSelectionEvent event) { + return uiClass; + } + + public String getDefaultPortletName() { + return uiClass.getName(); + } + + public String getDefaultDisplayName() { + return uiClass.getSimpleName(); + } + +} diff --git a/liferay-integration/src/main/java/com/vaadin/osgi/liferay/OSGiVaadinPortletService.java b/liferay-integration/src/main/java/com/vaadin/osgi/liferay/OSGiVaadinPortletService.java new file mode 100644 index 0000000000..1742e9eb41 --- /dev/null +++ b/liferay-integration/src/main/java/com/vaadin/osgi/liferay/OSGiVaadinPortletService.java @@ -0,0 +1,57 @@ +/* + * 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.liferay; + +import com.vaadin.server.DeploymentConfiguration; +import com.vaadin.server.ServiceException; +import com.vaadin.server.VaadinPortlet; +import com.vaadin.server.VaadinPortletService; +import com.vaadin.server.VaadinPortletSession; +import com.vaadin.server.VaadinRequest; +import com.vaadin.server.VaadinSession; +import com.vaadin.ui.UI; + +/** + * {@link VaadinPortletService} class that uses the {@link OSGiUIProvider} to + * configure the {@link UI} class for a {@link VaadinPortlet}. + * + * @author Sampsa Sohlman + * + * @since 8.1 + */ +@SuppressWarnings("serial") +public class OSGiVaadinPortletService extends VaadinPortletService { + private OSGiUIProvider osgiUIProvider; + + public OSGiVaadinPortletService(VaadinPortlet portlet, + DeploymentConfiguration deploymentConfiguration, + OSGiUIProvider osgiUIProvider) throws ServiceException { + + super(portlet, deploymentConfiguration); + this.osgiUIProvider = osgiUIProvider; + } + + @Override + protected VaadinSession createVaadinSession(VaadinRequest request) + throws ServiceException { + + VaadinSession vaadinSession = new VaadinPortletSession(this); + vaadinSession.addUIProvider(osgiUIProvider); + + return vaadinSession; + } + +} diff --git a/liferay-integration/src/main/java/com/vaadin/osgi/liferay/PortletUIServiceTrackerCustomizer.java b/liferay-integration/src/main/java/com/vaadin/osgi/liferay/PortletUIServiceTrackerCustomizer.java new file mode 100644 index 0000000000..9a42b34588 --- /dev/null +++ b/liferay-integration/src/main/java/com/vaadin/osgi/liferay/PortletUIServiceTrackerCustomizer.java @@ -0,0 +1,183 @@ +/* + * 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.liferay; + +import java.util.Dictionary; +import java.util.HashMap; +import java.util.Hashtable; +import java.util.Map; + +import javax.portlet.Portlet; + +import org.osgi.framework.Bundle; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceObjects; +import org.osgi.framework.ServiceReference; +import org.osgi.framework.ServiceRegistration; +import org.osgi.util.tracker.ServiceTrackerCustomizer; + +import com.vaadin.osgi.resources.VaadinResourceService; +import com.vaadin.ui.UI; + +/** + * Tracks {@link UI UIs} registered as OSGi services. + * + * <p> + * If the {@link UI} is annotated with + * {@link VaadinLiferayPortletConfiguration}, a {@link Portlet} is created for + * it. + * + * @author Sampsa Sohlman + * + * @since 8.1 + */ +class PortletUIServiceTrackerCustomizer + implements ServiceTrackerCustomizer<UI, ServiceObjects<UI>> { + + private static final String RESOURCE_PATH_PREFIX = "/o/%s"; + private static final String DISPLAY_CATEGORY = "com.liferay.portlet.display-category"; + private static final String VAADIN_CATEGORY = "category.vaadin"; + + private static final String PORTLET_NAME = "javax.portlet.name"; + private static final String DISPLAY_NAME = "javax.portlet.display-name"; + private static final String PORTLET_SECURITY_ROLE = "javax.portlet.security-role-ref"; + private static final String VAADIN_RESOURCE_PATH = "javax.portlet.init-param.vaadin.resources.path"; + + private Map<ServiceReference<UI>, ServiceRegistration<Portlet>> portletRegistrations = new HashMap<ServiceReference<UI>, ServiceRegistration<Portlet>>(); + private VaadinResourceService service; + + PortletUIServiceTrackerCustomizer(VaadinResourceService service) { + this.service = service; + } + + @Override + public ServiceObjects<UI> addingService( + ServiceReference<UI> uiServiceReference) { + + Bundle bundle = uiServiceReference.getBundle(); + BundleContext bundleContext = bundle.getBundleContext(); + UI contributedUI = bundleContext.getService(uiServiceReference); + + try { + Class<? extends UI> uiClass = contributedUI.getClass(); + VaadinLiferayPortletConfiguration portletConfiguration = uiClass + .getAnnotation(VaadinLiferayPortletConfiguration.class); + if (portletConfiguration != null) { + return registerPortlet(uiServiceReference, + portletConfiguration); + } else { + // No portlet configuration, ignore the UI + return null; + } + } finally { + bundleContext.ungetService(uiServiceReference); + } + } + + private ServiceObjects<UI> registerPortlet(ServiceReference<UI> reference, + VaadinLiferayPortletConfiguration configuration) { + + Bundle bundle = reference.getBundle(); + BundleContext bundleContext = bundle.getBundleContext(); + + ServiceObjects<UI> serviceObjects = bundleContext + .getServiceObjects(reference); + + OSGiUIProvider uiProvider = new OSGiUIProvider(serviceObjects); + + Dictionary<String, Object> properties = createPortletProperties( + uiProvider, reference, configuration); + + VaadinOSGiPortlet portlet = new VaadinOSGiPortlet(uiProvider); + + ServiceRegistration<Portlet> serviceRegistration = bundleContext + .registerService(Portlet.class, portlet, properties); + + portletRegistrations.put(reference, serviceRegistration); + + return serviceObjects; + } + + private Dictionary<String, Object> createPortletProperties( + OSGiUIProvider uiProvider, ServiceReference<UI> reference, + VaadinLiferayPortletConfiguration configuration) { + + Hashtable<String, Object> properties = new Hashtable<String, Object>(); + String category = configuration.category(); + if (category.trim().isEmpty()) { + category = VAADIN_CATEGORY; + } + copyProperty(reference, properties, DISPLAY_CATEGORY, category); + + String portletName = configuration.name(); + if (portletName.trim().isEmpty()) { + portletName = uiProvider.getDefaultPortletName(); + } + + String displayName = configuration.displayName(); + if (displayName.trim().isEmpty()) { + displayName = uiProvider.getDefaultDisplayName(); + } + + copyProperty(reference, properties, PORTLET_NAME, portletName); + copyProperty(reference, properties, DISPLAY_NAME, displayName); + copyProperty(reference, properties, PORTLET_SECURITY_ROLE, + configuration.securityRole()); + + String resourcesPath = String.format(RESOURCE_PATH_PREFIX, + service.getResourcePathPrefix()); + copyProperty(reference, properties, VAADIN_RESOURCE_PATH, + resourcesPath); + + return properties; + } + + private void copyProperty(ServiceReference<UI> serviceReference, + Dictionary<String, Object> properties, String key, + Object defaultValue) { + + Object value = serviceReference.getProperty(key); + if (value != null) { + properties.put(key, value); + } else if (value == null && defaultValue != null) { + properties.put(key, defaultValue); + } + } + + @Override + public void modifiedService(ServiceReference<UI> serviceReference, + ServiceObjects<UI> ui) { + } + + @Override + public void removedService(ServiceReference<UI> reference, + ServiceObjects<UI> ui) { + + ServiceRegistration<Portlet> portletRegistration = portletRegistrations + .get(reference); + portletRegistrations.remove(reference); + portletRegistration.unregister(); + } + + void cleanPortletRegistrations() { + for (ServiceRegistration<Portlet> registration : portletRegistrations + .values()) { + registration.unregister(); + } + portletRegistrations.clear(); + portletRegistrations = null; + } +} diff --git a/liferay-integration/src/main/java/com/vaadin/osgi/liferay/VaadinLiferayPortletConfiguration.java b/liferay-integration/src/main/java/com/vaadin/osgi/liferay/VaadinLiferayPortletConfiguration.java new file mode 100644 index 0000000000..65f983e24c --- /dev/null +++ b/liferay-integration/src/main/java/com/vaadin/osgi/liferay/VaadinLiferayPortletConfiguration.java @@ -0,0 +1,46 @@ +/* + * 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.liferay; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import javax.portlet.Portlet; + +/** + * This annotation is used to inform the + * {@link PortletUIServiceTrackerCustomizer} that this UI should be wrapped in a + * {@link Portlet} and provides the necessary configuration for that. + * + * @author Vaadin Ltd. + * + * @since 8.1 + */ +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.TYPE) +@Inherited +public @interface VaadinLiferayPortletConfiguration { + String category() default "category.vaadin"; + + String name() default ""; + + String displayName() default ""; + + String[] securityRole() default { "power-user", "user" }; +} diff --git a/liferay-integration/src/main/java/com/vaadin/osgi/liferay/VaadinOSGiPortlet.java b/liferay-integration/src/main/java/com/vaadin/osgi/liferay/VaadinOSGiPortlet.java new file mode 100644 index 0000000000..80dd346f23 --- /dev/null +++ b/liferay-integration/src/main/java/com/vaadin/osgi/liferay/VaadinOSGiPortlet.java @@ -0,0 +1,48 @@ +/* + * 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.liferay; + +import com.vaadin.server.DeploymentConfiguration; +import com.vaadin.server.ServiceException; +import com.vaadin.server.VaadinPortlet; +import com.vaadin.server.VaadinPortletService; +import com.vaadin.ui.UI; + +/** + * {@link VaadinPortlet} that uses an {@link OSGiUIProvider} to configure its + * {@link UI}. + * + * @author Sampsa Sohlman + * + * @since 8.1 + */ +@SuppressWarnings("serial") +public class VaadinOSGiPortlet extends VaadinPortlet { + private OSGiUIProvider uiProvider; + + public VaadinOSGiPortlet(OSGiUIProvider uiProvider) { + this.uiProvider = uiProvider; + } + + @Override + protected VaadinPortletService createPortletService( + DeploymentConfiguration configuration) throws ServiceException { + OSGiVaadinPortletService osgiVaadinPortletService = new OSGiVaadinPortletService( + this, configuration, uiProvider); + osgiVaadinPortletService.init(); + return osgiVaadinPortletService; + } +} diff --git a/liferay-integration/src/main/java/com/vaadin/osgi/liferay/VaadinPortletProvider.java b/liferay-integration/src/main/java/com/vaadin/osgi/liferay/VaadinPortletProvider.java new file mode 100644 index 0000000000..0c2374afeb --- /dev/null +++ b/liferay-integration/src/main/java/com/vaadin/osgi/liferay/VaadinPortletProvider.java @@ -0,0 +1,65 @@ +/* + * 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.liferay; + +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceObjects; +import org.osgi.service.component.ComponentContext; +import org.osgi.service.component.annotations.Activate; +import org.osgi.service.component.annotations.Component; +import org.osgi.service.component.annotations.Deactivate; +import org.osgi.util.tracker.ServiceTracker; + +import com.vaadin.osgi.resources.OSGiVaadinResources; +import com.vaadin.osgi.resources.VaadinResourceService; +import com.vaadin.ui.UI; + +/** + * Initializes a service tracker with {@link PortletUIServiceTrackerCustomizer} + * to track {@link UI} service registrations. + * + * @author Sampsa Sohlman + * + * @since 8.1 + */ +@Component(immediate = true) +public class VaadinPortletProvider { + + private ServiceTracker<UI, ServiceObjects<UI>> serviceTracker; + private PortletUIServiceTrackerCustomizer portletUIServiceTrackerCustomizer; + + @Activate + void activate(ComponentContext componentContext) throws Exception { + BundleContext bundleContext = componentContext.getBundleContext(); + VaadinResourceService service = OSGiVaadinResources.getService(); + + portletUIServiceTrackerCustomizer = new PortletUIServiceTrackerCustomizer( + service); + serviceTracker = new ServiceTracker<UI, ServiceObjects<UI>>( + bundleContext, UI.class, portletUIServiceTrackerCustomizer); + serviceTracker.open(); + } + + @Deactivate + void deactivate() { + if (serviceTracker != null) { + serviceTracker.close(); + portletUIServiceTrackerCustomizer.cleanPortletRegistrations(); + portletUIServiceTrackerCustomizer = null; + } + + } +} |