com.vaadin.osgi.liferay.PortletUIServiceTrackerCustomizer Maven / Gradle / Ivy
Show all versions of vaadin-liferay-integration Show documentation
/*
* Copyright (C) 2000-2024 Vaadin Ltd
*
* This program is available under Vaadin Commercial License and Service Terms.
*
* See for the full
* license.
*/
package com.vaadin.osgi.liferay;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;
import java.util.Optional;
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.service.log.LogService;
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.
*
*
* If the {@link UI} is annotated with
* {@link VaadinLiferayPortletConfiguration}, a {@link Portlet} is created for
* it.
*
* This only applies to Liferay Portal 7+ with OSGi support.
*
* @author Sampsa Sohlman
*
* @since 8.1
*/
class PortletUIServiceTrackerCustomizer
implements ServiceTrackerCustomizer> {
private static final String RESOURCE_PATH_PREFIX = "/o/%s";
private static final String DISPLAY_CATEGORY = PortletProperties.DISPLAY_CATEGORY;
private static final String VAADIN_CATEGORY = "category.vaadin";
private static final String PORTLET_NAME = PortletProperties.PORTLET_NAME;
private static final String DISPLAY_NAME = PortletProperties.DISPLAY_NAME;
private static final String PORTLET_SECURITY_ROLE = PortletProperties.PORTLET_SECURITY_ROLE;
private static final String VAADIN_RESOURCE_PATH = "javax.portlet.init-param.vaadin.resources.path";
private Map, ServiceRegistration> portletRegistrations = new HashMap, ServiceRegistration>();
private VaadinResourceService service;
private Optional logService;
PortletUIServiceTrackerCustomizer(VaadinResourceService service,
LogService logService) {
this.service = service;
this.logService = Optional.ofNullable(logService);
}
@Override
public ServiceObjects addingService(
ServiceReference 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);
boolean isPortletUi = uiServiceReference
.getProperty(PortletProperties.PORTLET_UI_PROPERTY) != null
|| portletConfiguration != null;
if (isPortletUi) {
return registerPortlet(uiServiceReference,
portletConfiguration);
} else {
// No portlet configuration, ignore the UI
return null;
}
} finally {
bundleContext.ungetService(uiServiceReference);
}
}
private ServiceObjects registerPortlet(ServiceReference reference,
VaadinLiferayPortletConfiguration configuration) {
Bundle bundle = reference.getBundle();
BundleContext bundleContext = bundle.getBundleContext();
ServiceObjects serviceObjects = bundleContext
.getServiceObjects(reference);
OsgiUIProvider uiProvider = new OsgiUIProvider(serviceObjects,
logService);
Dictionary properties = null;
if (configuration != null) {
properties = createPortletProperties(uiProvider, reference,
configuration);
} else {
properties = createPortletProperties(reference);
}
OsgiVaadinPortlet portlet = new OsgiVaadinPortlet(uiProvider);
ServiceRegistration serviceRegistration = bundleContext
.registerService(Portlet.class, portlet, properties);
portletRegistrations.put(reference, serviceRegistration);
return serviceObjects;
}
private Dictionary createPortletProperties(
OsgiUIProvider uiProvider, ServiceReference reference,
VaadinLiferayPortletConfiguration configuration) {
Hashtable properties = new Hashtable();
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 serviceReference,
Dictionary 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);
}
}
private Dictionary createPortletProperties(
ServiceReference reference) {
Hashtable properties = new Hashtable<>();
for (String key : reference.getPropertyKeys()) {
properties.put(key, reference.getProperty(key));
}
String resourcesPath = String.format(RESOURCE_PATH_PREFIX,
service.getResourcePathPrefix());
properties.put(VAADIN_RESOURCE_PATH, resourcesPath);
return properties;
}
@Override
public void modifiedService(ServiceReference serviceReference,
ServiceObjects ui) {
/*
* This service has been registered as a portlet at some point,
* otherwise it wouldn't be tracked.
*
* This handles changes for Portlet related properties that are part of
* the UI service to be passed to the Portlet service registration.
*/
Dictionary newProperties = createPortletProperties(
serviceReference);
ServiceRegistration registration = portletRegistrations
.get(serviceReference);
if (registration != null) {
registration.setProperties(newProperties);
}
}
@Override
public void removedService(ServiceReference reference,
ServiceObjects ui) {
ServiceRegistration portletRegistration = portletRegistrations
.get(reference);
portletRegistrations.remove(reference);
portletRegistration.unregister();
}
void cleanPortletRegistrations() {
for (ServiceRegistration registration : portletRegistrations
.values()) {
registration.unregister();
}
portletRegistrations.clear();
portletRegistrations = null;
}
}