/**
* 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.kernel.deploy.auto;
import com.liferay.portal.kernel.deploy.auto.context.AutoDeploymentContext;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.util.ArrayUtil;
import com.liferay.portal.kernel.util.FileUtil;
import com.liferay.portal.kernel.util.PropsKeys;
import com.liferay.portal.kernel.util.PropsUtil;
import com.liferay.portal.kernel.util.StringUtil;
import com.liferay.registry.Registry;
import com.liferay.registry.RegistryUtil;
import com.liferay.registry.ServiceTracker;
import java.io.File;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.CopyOnWriteArrayList;
/**
* @author Ivica Cardic
* @author Brian Wing Shun Chan
*/
public class AutoDeployDir {
public static final String DEFAULT_NAME = "defaultAutoDeployDir";
public static void deploy(
AutoDeploymentContext autoDeploymentContext,
List<AutoDeployListener> autoDeployListeners)
throws AutoDeployException {
AutoDeployListener autoDeployListener = _serviceTracker.getService();
if (autoDeployListener != null) {
if (autoDeployListener.isDeployable(autoDeploymentContext)) {
autoDeployListener.deploy(autoDeploymentContext);
File file = autoDeploymentContext.getFile();
file.delete();
return;
}
}
String[] dirNames = PropsUtil.getArray(
PropsKeys.MODULE_FRAMEWORK_AUTO_DEPLOY_DIRS);
if (ArrayUtil.isEmpty(dirNames)) {
throw new AutoDeployException(
"The portal property \"" +
PropsKeys.MODULE_FRAMEWORK_AUTO_DEPLOY_DIRS +
"\" is not set");
}
String dirName = dirNames[0];
File file = autoDeploymentContext.getFile();
String fileName = file.getName();
if (StringUtil.endsWith(fileName, ".cfg")) {
for (String curDirName : dirNames) {
if (curDirName.endsWith("/configs")) {
dirName = curDirName;
break;
}
}
}
else if (StringUtil.endsWith(fileName, ".lpkg")) {
for (String curDirName : dirNames) {
if (curDirName.endsWith("/marketplace")) {
dirName = curDirName;
break;
}
}
}
else if (StringUtil.endsWith(fileName, ".war")) {
for (String curDirName : dirNames) {
if (curDirName.endsWith("/war")) {
dirName = curDirName;
break;
}
}
}
else {
for (String curDirName : dirNames) {
if (curDirName.endsWith("/modules")) {
dirName = curDirName;
break;
}
}
}
FileUtil.move(file, new File(dirName, fileName));
}
public AutoDeployDir(
String name, File deployDir, File destDir, long interval,
List<AutoDeployListener> autoDeployListeners) {
_name = name;
_deployDir = deployDir;
_destDir = destDir;
_interval = interval;
_autoDeployListeners = new CopyOnWriteArrayList<>(autoDeployListeners);
_blacklistFileTimestamps = new HashMap<>();
}
public File getDeployDir() {
return _deployDir;
}
public File getDestDir() {
return _destDir;
}
public long getInterval() {
return _interval;
}
public List<AutoDeployListener> getListeners() {
return _autoDeployListeners;
}
public String getName() {
return _name;
}
public void registerListener(AutoDeployListener listener) {
_autoDeployListeners.add(listener);
}
public void start() {
if (!_deployDir.exists()) {
if (_log.isInfoEnabled()) {
_log.info("Creating missing directory " + _deployDir);
}
boolean created = _deployDir.mkdirs();
if (!created) {
_log.error("Directory " + _deployDir + " could not be created");
}
}
if ((_interval > 0) &&
((_autoDeployScanner == null) || !_autoDeployScanner.isAlive())) {
try {
scanDirectory();
Thread currentThread = Thread.currentThread();
_autoDeployScanner = new AutoDeployScanner(
currentThread.getThreadGroup(),
AutoDeployScanner.class.getName(), this);
_autoDeployScanner.start();
if (_log.isInfoEnabled()) {
_log.info("Auto deploy scanner started for " + _deployDir);
}
}
catch (Exception e) {
_log.error(e, e);
stop();
return;
}
}
else {
if (_log.isInfoEnabled()) {
_log.info("Auto deploy scanning is disabled for " + _deployDir);
}
}
}
public void stop() {
if (_autoDeployScanner != null) {
_autoDeployScanner.pause();
}
_serviceTracker.close();
}
public void unregisterListener(AutoDeployListener autoDeployListener) {
_autoDeployListeners.remove(autoDeployListener);
}
protected AutoDeploymentContext buildAutoDeploymentContext(File file) {
AutoDeploymentContext autoDeploymentContext =
new AutoDeploymentContext();
autoDeploymentContext.setFile(file);
return autoDeploymentContext;
}
protected void processFile(File file) {
String fileName = file.getName();
if (!file.canRead()) {
_log.error("Unable to read " + fileName);
return;
}
if (!file.canWrite()) {
_log.error("Unable to write " + fileName);
return;
}
if (_blacklistFileTimestamps.containsKey(fileName) &&
(_blacklistFileTimestamps.get(fileName) == file.lastModified())) {
if (_log.isDebugEnabled()) {
_log.debug(
"Skip processing of " + fileName + " because it is " +
"blacklisted");
}
return;
}
if (_log.isInfoEnabled()) {
_log.info("Processing " + fileName);
}
try {
AutoDeploymentContext autoDeploymentContext =
buildAutoDeploymentContext(file);
deploy(autoDeploymentContext, _autoDeployListeners);
return;
}
catch (Exception e) {
_log.error(e, e);
}
if (_log.isInfoEnabled()) {
_log.info("Add " + fileName + " to the blacklist");
}
_blacklistFileTimestamps.put(fileName, file.lastModified());
}
protected void scanDirectory() {
File[] files = _deployDir.listFiles();
if (files == null) {
return;
}
Set<String> blacklistedFileNames = _blacklistFileTimestamps.keySet();
Iterator<String> iterator = blacklistedFileNames.iterator();
while (iterator.hasNext()) {
String blacklistedFileName = iterator.next();
boolean blacklistedFileExists = false;
for (File file : files) {
if (StringUtil.equalsIgnoreCase(
blacklistedFileName, file.getName())) {
blacklistedFileExists = true;
}
}
if (!blacklistedFileExists) {
if (_log.isDebugEnabled()) {
_log.debug(
"Remove blacklisted file " + blacklistedFileName +
" because it was deleted");
}
iterator.remove();
}
}
for (File file : files) {
String fileName = file.getName();
fileName = StringUtil.toLowerCase(fileName);
if (file.isFile() &&
(fileName.endsWith(".jar") || fileName.endsWith(".lpkg") ||
fileName.endsWith(".war") || fileName.endsWith(".xml") ||
fileName.endsWith(".zip"))) {
processFile(file);
}
}
}
private static final Log _log = LogFactoryUtil.getLog(AutoDeployDir.class);
private static AutoDeployScanner _autoDeployScanner;
private static final ServiceTracker<AutoDeployListener, AutoDeployListener>
_serviceTracker;
static {
Registry registry = RegistryUtil.getRegistry();
_serviceTracker = registry.trackServices(AutoDeployListener.class);
_serviceTracker.open();
}
private final List<AutoDeployListener> _autoDeployListeners;
private final Map<String, Long> _blacklistFileTimestamps;
private final File _deployDir;
private final File _destDir;
private final long _interval;
private final String _name;
}