/**
* Copyright (c) 2000-present Liferay, Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation; either version 2.1 of the License, or (at your option)
* any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*/
package com.liferay.exportimport.resources.importer.internal.extender;
import com.liferay.exportimport.resources.importer.provider.ResourceImporterBundleProvider;
import com.liferay.osgi.util.ServiceTrackerFactory;
import com.liferay.portal.kernel.cluster.ClusterMasterExecutor;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.messaging.DestinationNames;
import com.liferay.portal.kernel.messaging.Message;
import com.liferay.portal.kernel.messaging.MessageBus;
import com.liferay.portal.kernel.plugin.PluginPackage;
import com.liferay.portal.kernel.util.HashMapDictionary;
import com.liferay.portal.plugin.PluginPackageUtil;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.ServletContext;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleContext;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.ServiceRegistration;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import org.osgi.service.component.annotations.Reference;
import org.osgi.util.tracker.ServiceTracker;
import org.osgi.util.tracker.ServiceTrackerCustomizer;
/**
* @author Michael C. Han
*/
@Component(immediate = true)
public class ResourceImporterExtender {
@Activate
protected void activate(BundleContext bundleContext) {
_bundleContext = bundleContext;
_serviceTracker = ServiceTrackerFactory.create(
bundleContext, ResourceImporterBundleProvider.class,
new ResourceImporterBundleProviderServiceTrackerCustomizer());
_serviceTracker.open();
}
@Deactivate
protected void deactivate() {
for (ServiceRegistration<?> serviceRegistration :
_serviceRegistrations.values()) {
serviceRegistration.unregister();
}
_serviceRegistrations.clear();
_serviceTracker.close();
_serviceTracker = null;
_bundleContext = null;
}
private static final Log _log = LogFactoryUtil.getLog(
ResourceImporterExtender.class);
private BundleContext _bundleContext;
@Reference
private ClusterMasterExecutor _clusterMasterExecutor;
@Reference
private MessageBus _messageBus;
private final Map<String, ServiceRegistration<ServletContext>>
_serviceRegistrations = new ConcurrentHashMap<>();
private ServiceTracker
<ResourceImporterBundleProvider, ResourceImporterBundleProvider>
_serviceTracker;
private class ResourceImporterBundleProviderServiceTrackerCustomizer
implements ServiceTrackerCustomizer
<ResourceImporterBundleProvider, ResourceImporterBundleProvider> {
@Override
public ResourceImporterBundleProvider addingService(
ServiceReference<ResourceImporterBundleProvider> serviceReference) {
if (!_clusterMasterExecutor.isMaster()) {
return null;
}
Bundle bundle = serviceReference.getBundle();
String bundleSymbolicName = bundle.getSymbolicName();
try {
PluginPackage pluginPackage = getPluginPackage(bundle);
PluginPackageUtil.registerInstalledPluginPackage(pluginPackage);
ServletContext servletContext = new BundleServletContextAdapter(
bundle);
ServiceRegistration<ServletContext> serviceRegistration =
_bundleContext.registerService(
ServletContext.class, servletContext,
new HashMapDictionary<String, Object>());
_serviceRegistrations.put(
bundleSymbolicName, serviceRegistration);
Message message = new Message();
message.put("command", "deploy");
message.put("servletContextName", bundleSymbolicName);
_messageBus.sendMessage(DestinationNames.HOT_DEPLOY, message);
}
catch (Exception e) {
if (_log.isWarnEnabled()) {
_log.warn(
"Unable to initialize bundle: " + bundleSymbolicName,
e);
}
}
return null;
}
@Override
public void modifiedService(
ServiceReference<ResourceImporterBundleProvider> serviceReference,
ResourceImporterBundleProvider resourceImporterBundleProvider) {
}
@Override
public void removedService(
ServiceReference<ResourceImporterBundleProvider> serviceReference,
ResourceImporterBundleProvider resourceImporterBundleProvider) {
Bundle bundle = serviceReference.getBundle();
String bundleSymbolicName = bundle.getSymbolicName();
ServiceRegistration<ServletContext> serviceRegistration =
_serviceRegistrations.remove(bundleSymbolicName);
if (serviceRegistration != null) {
serviceRegistration.unregister();
}
try {
PluginPackage pluginPackage = getPluginPackage(bundle);
PluginPackageUtil.unregisterInstalledPluginPackage(
pluginPackage);
}
catch (Exception e) {
if (_log.isWarnEnabled()) {
_log.warn(
"Unable to unregister bundle: " + bundleSymbolicName,
e);
}
}
}
protected PluginPackage getPluginPackage(Bundle bundle)
throws IOException {
URL url = bundle.getResource(
"/WEB-INF/liferay-plugin-package.properties");
InputStream inputStream = url.openStream();
Properties liferayPluginPackageProperties = new Properties();
liferayPluginPackageProperties.load(inputStream);
PluginPackage pluginPackage =
PluginPackageUtil.readPluginPackageProperties(
bundle.getSymbolicName() + "-web",
liferayPluginPackageProperties);
pluginPackage.setContext(bundle.getSymbolicName());
return pluginPackage;
}
}
}