/** * 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.marketplace.deployer.internal; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.util.GetterUtil; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.lpkg.deployer.LPKGDeployer; import java.io.File; import java.io.InputStream; import java.util.Dictionary; import java.util.Properties; import java.util.zip.ZipEntry; import java.util.zip.ZipFile; import org.apache.felix.fileinstall.ArtifactInstaller; import org.osgi.framework.Bundle; import org.osgi.framework.BundleContext; import org.osgi.framework.BundleException; import org.osgi.framework.Constants; import org.osgi.framework.Version; import org.osgi.service.component.annotations.Activate; import org.osgi.service.component.annotations.Component; import org.osgi.service.component.annotations.Reference; /** * @author Shuyang Zhou */ @Component(immediate = true) public class LPKGArtifactInstaller implements ArtifactInstaller { @Activate public void activate(BundleContext bundleContext) { _bundleContext = bundleContext; } @Override public boolean canHandle(File file) { String name = StringUtil.toLowerCase(file.getName()); return name.endsWith(".lpkg"); } @Override public void install(File file) throws Exception { Properties properties = _readMarketplaceProperties(file); if (GetterUtil.getBoolean( properties.getProperty("restart-required"), true)) { _logRestartRequired(file.getCanonicalPath()); return; } for (Bundle bundle : _lpkgDeployer.deploy(_bundleContext, file)) { Dictionary<String, String> headers = bundle.getHeaders(); String fragmentHost = headers.get(Constants.FRAGMENT_HOST); if (fragmentHost != null) { continue; } try { bundle.start(); } catch (BundleException be) { _log.error("Unable to start " + bundle + " for " + file, be); } } } @Override public void uninstall(File file) throws Exception { Bundle bundle = _bundleContext.getBundle(file.getCanonicalPath()); if (bundle != null) { bundle.uninstall(); } } @Override public void update(File file) throws Exception { Properties properties = _readMarketplaceProperties(file); String canonicalPath = file.getCanonicalPath(); Bundle bundle = _bundleContext.getBundle(canonicalPath); if (bundle != null) { Version currentVersion = bundle.getVersion(); Version newVersion = new Version(properties.getProperty("version")); if (newVersion.compareTo(currentVersion) > 0) { if (GetterUtil.getBoolean( properties.getProperty("restart-required"), true)) { _logRestartRequired(canonicalPath); return; } bundle.update(_lpkgDeployer.toBundle(file)); } } } private void _logRestartRequired(String canonicalPath) { if (_log.isInfoEnabled()) { _log.info( "The portal instance needs to be restarted to complete the " + "installation of " + canonicalPath); } } private Properties _readMarketplaceProperties(File file) { try (ZipFile zipFile = new ZipFile(file)) { ZipEntry zipEntry = zipFile.getEntry( "liferay-marketplace.properties"); if (zipEntry == null) { return null; } Properties properties = new Properties(); try (InputStream inputStream = zipFile.getInputStream(zipEntry)) { properties.load(inputStream); } return properties; } catch (Exception e) { if (_log.isDebugEnabled()) { _log.debug( "Unable to read liferay-marketplace.properties from " + file.getName(), e); } } return null; } private static final Log _log = LogFactoryUtil.getLog( LPKGArtifactInstaller.class); private BundleContext _bundleContext; @Reference private LPKGDeployer _lpkgDeployer; }