/**
* 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.messaging;
import com.liferay.exportimport.kernel.lar.ExportImportThreadLocal;
import com.liferay.exportimport.resources.importer.internal.constants.ResourcesImporterDestinationNames;
import com.liferay.exportimport.resources.importer.internal.util.Importer;
import com.liferay.exportimport.resources.importer.internal.util.ImporterException;
import com.liferay.exportimport.resources.importer.internal.util.ImporterFactory;
import com.liferay.exportimport.resources.importer.internal.util.PluginPackageProperties;
import com.liferay.osgi.service.tracker.collections.map.ServiceReferenceMapper;
import com.liferay.osgi.service.tracker.collections.map.ServiceTrackerMap;
import com.liferay.osgi.service.tracker.collections.map.ServiceTrackerMapFactory;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.messaging.Destination;
import com.liferay.portal.kernel.messaging.DestinationConfiguration;
import com.liferay.portal.kernel.messaging.DestinationFactory;
import com.liferay.portal.kernel.messaging.DestinationNames;
import com.liferay.portal.kernel.messaging.HotDeployMessageListener;
import com.liferay.portal.kernel.messaging.Message;
import com.liferay.portal.kernel.messaging.MessageBusUtil;
import com.liferay.portal.kernel.messaging.MessageListener;
import com.liferay.portal.kernel.model.Company;
import com.liferay.portal.kernel.model.Release;
import com.liferay.portal.kernel.security.auth.CompanyThreadLocal;
import com.liferay.portal.kernel.service.CompanyLocalService;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.HashMapDictionary;
import com.liferay.portal.kernel.util.StringBundler;
import com.liferay.portal.kernel.util.Validator;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.ServletContext;
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.service.component.annotations.ReferenceCardinality;
import org.osgi.service.component.annotations.ReferencePolicy;
import org.osgi.service.component.annotations.ReferencePolicyOption;
/**
* @author Ryan Park
* @author Raymond Augé
*/
@Component(
immediate = true,
property = {"destination.name=" + DestinationNames.HOT_DEPLOY},
service = MessageListener.class
)
public class ResourcesImporterHotDeployMessageListener
extends HotDeployMessageListener {
@Activate
protected void activate(final BundleContext bundleContext) {
_bundleContext = bundleContext;
_serviceTrackerMap = ServiceTrackerMapFactory.openSingleValueMap(
bundleContext, ServletContext.class, null,
new ServiceReferenceMapper<String, ServletContext>() {
@Override
public void map(
ServiceReference<ServletContext> serviceReference,
ServiceReferenceMapper.Emitter<String> emitter) {
try {
ServletContext servletContext =
bundleContext.getService(serviceReference);
String servletContextName = GetterUtil.getString(
servletContext.getServletContextName());
emitter.emit(servletContextName);
}
finally {
bundleContext.ungetService(serviceReference);
}
}
});
registerDestination();
}
@Deactivate
protected void deactivate() {
_bundleContext = null;
if (_serviceRegistration != null) {
_serviceRegistration.unregister();
_destination.destroy();
}
_serviceTrackerMap.close();
}
protected void initialize(Message message) throws Exception {
String servletContextName = message.getString("servletContextName");
ServletContext servletContext = _serviceTrackerMap.getService(
servletContextName);
if (servletContext == null) {
return;
}
PluginPackageProperties pluginPackageProperties =
new PluginPackageProperties(servletContext);
String resourcesDir = pluginPackageProperties.getResourcesDir();
if ((servletContext.getResource(ImporterFactory.RESOURCES_DIR) ==
null) &&
(servletContext.getResource(ImporterFactory.TEMPLATES_DIR) ==
null) &&
Validator.isNull(resourcesDir)) {
return;
}
List<Company> companies = _companyLocalService.getCompanies();
try {
ExportImportThreadLocal.setLayoutImportInProcess(true);
ExportImportThreadLocal.setPortletImportInProcess(true);
for (Company company : companies) {
_importResources(
company, servletContext, pluginPackageProperties,
message.getResponseId());
}
}
finally {
ExportImportThreadLocal.setLayoutImportInProcess(false);
ExportImportThreadLocal.setPortletImportInProcess(false);
}
}
@Override
protected void onDeploy(Message message) throws Exception {
initialize(message);
}
protected synchronized void registerDestination() {
if ((_bundleContext != null) && (_serviceRegistration == null) &&
(_destinationFactory != null)) {
DestinationConfiguration destinationConfiguration =
new DestinationConfiguration(
DestinationConfiguration.DESTINATION_TYPE_SERIAL,
ResourcesImporterDestinationNames.RESOURCES_IMPORTER);
_destination = _destinationFactory.createDestination(
destinationConfiguration);
Dictionary<String, Object> dictionary = new HashMapDictionary<>();
dictionary.put("destination.name", _destination.getName());
_serviceRegistration = _bundleContext.registerService(
Destination.class, _destination, dictionary);
}
}
@Reference(unbind = "-")
protected void setCompanyLocalService(
CompanyLocalService companyLocalService) {
_companyLocalService = companyLocalService;
}
@Reference(
target = "(destination.name=" + DestinationNames.HOT_DEPLOY + ")",
unbind = "-"
)
protected void setDestination(Destination destination) {
}
@Reference(
cardinality = ReferenceCardinality.OPTIONAL,
policy = ReferencePolicy.STATIC,
policyOption = ReferencePolicyOption.GREEDY
)
protected void setDestinationFactory(
DestinationFactory destinationFactory) {
_destinationFactory = destinationFactory;
registerDestination();
}
@Reference(unbind = "-")
protected void setImporterFactory(ImporterFactory importerFactory) {
_importerFactory = importerFactory;
}
@Reference(
target = "(&(release.bundle.symbolic.name=com.liferay.exportimport.service)(release.schema.version=1.0.0))",
unbind = "-"
)
protected void setRelease(Release release) {
}
private void _importResources(
Company company, ServletContext servletContext,
PluginPackageProperties pluginPackageProperties,
String messageResponseId)
throws Exception {
long companyId = CompanyThreadLocal.getCompanyId();
try {
CompanyThreadLocal.setCompanyId(company.getCompanyId());
Importer importer = _importerFactory.createImporter(
company.getCompanyId(), servletContext,
pluginPackageProperties);
if (!importer.isDeveloperModeEnabled() && importer.isExisting() &&
!importer.isCompanyGroup()) {
if (_log.isInfoEnabled()) {
_log.info(
"Group or layout set prototype already exists for " +
"company " + company.getWebId());
}
return;
}
long startTime = 0;
if (_log.isInfoEnabled()) {
startTime = System.currentTimeMillis();
}
importer.importResources();
if (_log.isInfoEnabled()) {
StringBundler sb = new StringBundler(7);
sb.append("Importing resources from ");
sb.append(servletContext.getServletContextName());
sb.append(" to group ");
sb.append(importer.getGroupId());
sb.append(" takes ");
long endTime = System.currentTimeMillis() - startTime;
sb.append(endTime);
sb.append(" ms");
_log.info(sb.toString());
}
Message message = new Message();
message.put("companyId", company.getCompanyId());
message.put(
"servletContextName", servletContext.getServletContextName());
message.put("targetClassName", importer.getTargetClassName());
message.put("targetClassPK", importer.getTargetClassPK());
if (Validator.isNotNull(messageResponseId)) {
Map<String, Object> responseMap = new HashMap<>();
responseMap.put("groupId", importer.getTargetClassPK());
message.setPayload(responseMap);
message.setResponseId(messageResponseId);
}
MessageBusUtil.sendMessage("liferay/resources_importer", message);
}
catch (ImporterException ie) {
Message message = new Message();
message.put("companyId", company.getCompanyId());
message.put("error", ie.getMessage());
message.put(
"servletContextName", servletContext.getServletContextName());
message.put(
"targetClassName",
pluginPackageProperties.getTargetClassName());
message.put("targetClassPK", 0);
MessageBusUtil.sendMessage("liferay/resources_importer", message);
}
finally {
CompanyThreadLocal.setCompanyId(companyId);
}
}
private static final Log _log = LogFactoryUtil.getLog(
ResourcesImporterHotDeployMessageListener.class);
private BundleContext _bundleContext;
private CompanyLocalService _companyLocalService;
private Destination _destination;
private DestinationFactory _destinationFactory;
private ImporterFactory _importerFactory;
private ServiceRegistration<Destination> _serviceRegistration;
private ServiceTrackerMap<String, ServletContext> _serviceTrackerMap;
}