/**
* 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.portal.deploy;
import com.liferay.portal.kernel.deploy.DeployManagerUtil;
import com.liferay.portal.kernel.deploy.auto.AutoDeployDir;
import com.liferay.portal.kernel.deploy.auto.AutoDeployUtil;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.NamedThreadFactory;
import com.liferay.portal.kernel.util.PortalClassLoaderUtil;
import com.liferay.portal.kernel.util.StreamUtil;
import com.liferay.portal.kernel.util.Time;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* <p>
* See https://issues.liferay.com/browse/LPS-39277.
* </p>
*
* @author Brian Wing Shun Chan
* @author Shuyang Zhou
*/
public class RequiredPluginsUtil {
public static synchronized void startCheckingRequiredPlugins() {
if (_scheduledExecutorService != null) {
return;
}
_scheduledExecutorService = Executors.newSingleThreadScheduledExecutor(
new NamedThreadFactory(
RequiredPluginsUtil.class.getName(), Thread.NORM_PRIORITY,
null));
_scheduledExecutorService.scheduleWithFixedDelay(
new Runnable() {
@Override
public void run() {
checkRequiredPlugins();
}
},
Time.MINUTE, Time.MINUTE, TimeUnit.MILLISECONDS);
}
public static synchronized void stopCheckingRequiredPlugins() {
_unschedule(true);
}
protected static synchronized void checkRequiredPlugins() {
List<String[]> levelsRequiredDeploymentContexts =
DeployManagerUtil.getLevelsRequiredDeploymentContexts();
List<String[]> levelsRequiredDeploymentWARFileNames =
DeployManagerUtil.getLevelsRequiredDeploymentWARFileNames();
boolean deployed = false;
for (int i = 0; i < levelsRequiredDeploymentContexts.size(); i++) {
String[] levelRequiredDeploymentContexts =
levelsRequiredDeploymentContexts.get(i);
String[] levelRequiredDeploymentWARFileNames =
levelsRequiredDeploymentWARFileNames.get(i);
for (int j = 0; j < levelRequiredDeploymentContexts.length; j++) {
String levelRequiredDeploymentContext =
levelRequiredDeploymentContexts[j];
if (DeployManagerUtil.isDeployed(
levelRequiredDeploymentContext)) {
continue;
}
deployed = true;
String levelRequiredDeploymentWARFileName =
levelRequiredDeploymentWARFileNames[j];
if (_log.isDebugEnabled()) {
_log.debug(
"Automatically deploying the required plugin " +
levelRequiredDeploymentWARFileName);
}
ClassLoader classLoader =
PortalClassLoaderUtil.getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream(
"com/liferay/portal/deploy/dependencies/plugins" + (i + 1) +
"/" + levelRequiredDeploymentWARFileNames[j]);
AutoDeployDir autoDeployDir = AutoDeployUtil.getDir(
AutoDeployDir.DEFAULT_NAME);
if (autoDeployDir == null) {
// This should never happen except during shutdown
if (_log.isDebugEnabled()) {
_log.debug(
"The autodeploy directory " +
AutoDeployDir.DEFAULT_NAME + " is null");
}
continue;
}
try {
StreamUtil.transfer(
inputStream,
new FileOutputStream(
autoDeployDir.getDeployDir() + "/" +
levelRequiredDeploymentWARFileNames[j]));
}
catch (IOException ioe) {
_log.error("Unable to write file", ioe);
}
}
}
if (!deployed) {
// If all the required plugins were already in place, then we can
// safely unschedule our required plugins check to conserve
// processing power. Removal of plugins would trigger an undeploy
// event which would restart the scheduled required plugins check.
_unschedule(false);
}
}
private static void _unschedule(boolean awaitTermination) {
if (_scheduledExecutorService != null) {
_scheduledExecutorService.shutdownNow();
if (awaitTermination) {
try {
_scheduledExecutorService.awaitTermination(
1, TimeUnit.MINUTES);
}
catch (InterruptedException ie) {
_log.error(ie, ie);
}
}
_scheduledExecutorService = null;
}
}
private static final Log _log = LogFactoryUtil.getLog(
RequiredPluginsUtil.class);
private static ScheduledExecutorService _scheduledExecutorService;
}