@@ -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 |
@@ -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> |
@@ -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(); | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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" }; | |||
} |
@@ -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; | |||
} | |||
} |
@@ -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; | |||
} | |||
} | |||
} |
@@ -618,6 +618,7 @@ | |||
<module>themes</module> | |||
<module>uitest</module> | |||
<module>liferay</module> | |||
<module>liferay-integration</module> | |||
<module>all</module> | |||
<module>compatibility-server</module> | |||
<module>compatibility-server-gae</module> | |||
@@ -668,6 +669,7 @@ | |||
<module>compatibility-client-compiled</module> | |||
<module>compatibility-shared</module> | |||
<module>compatibility-themes</module> | |||
<module>liferay-integration</module> | |||
<!-- Nexus staging bug needs the last module to be deployed. --> | |||
<module>testbench-api</module> | |||
<!-- BOM is built and released separately --> | |||
@@ -733,6 +735,7 @@ | |||
<module>compatibility-client-compiled</module> | |||
<module>compatibility-shared</module> | |||
<module>compatibility-themes</module> | |||
<module>liferay-integration</module> | |||
<!-- Nexus staging bug needs the last module to be deployed. --> | |||
<module>testbench-api</module> | |||
<!-- BOM is built and released separately --> | |||
@@ -798,6 +801,7 @@ | |||
<module>compatibility-client-compiled</module> | |||
<module>compatibility-shared</module> | |||
<module>compatibility-themes</module> | |||
<module>liferay-integration</module> | |||
<module>testbench-api</module> | |||
<module>bom</module> | |||
</modules> | |||
@@ -857,6 +861,7 @@ | |||
<module>client-compiler</module> | |||
<module>shared</module> | |||
<module>compatibility-shared</module> | |||
<module>liferay-integration</module> | |||
</modules> | |||
<repositories> | |||
<repository> |
@@ -73,6 +73,7 @@ def getApiDiffHtml(): | |||
"compatibility-server", | |||
"compatibility-server-gae", | |||
"compatibility-shared", | |||
"liferay-integration", | |||
"server", "shared" | |||
] | |||
link_list = list(map(lambda module: "<a href='http://{}/repository/download/{}/{}:id/apidiff/{}/japicmp.html'>{}</a>".format(args.teamcityUrl, args.buildTypeId, args.buildId, module, module), modules)) | |||
@@ -122,7 +123,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-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-testbench-api', 'vaadin-bom' ], args.version) | |||
content = "<html><head></head><body><table>" | |||
traffic_light = "<svg width=\"20px\" height=\"20px\" style=\"padding-right:5px\"><circle cx=\"10\" cy=\"10\" r=\"10\" fill=\"{color}\"/></svg>" |