001
014
015 package com.liferay.portal.kernel.deploy.auto;
016
017 import com.liferay.portal.kernel.deploy.auto.context.AutoDeploymentContext;
018 import com.liferay.portal.kernel.log.Log;
019 import com.liferay.portal.kernel.log.LogFactoryUtil;
020 import com.liferay.portal.kernel.util.ArrayUtil;
021 import com.liferay.portal.kernel.util.FileUtil;
022 import com.liferay.portal.kernel.util.PropsKeys;
023 import com.liferay.portal.kernel.util.PropsUtil;
024 import com.liferay.portal.kernel.util.StringUtil;
025 import com.liferay.registry.Registry;
026 import com.liferay.registry.RegistryUtil;
027 import com.liferay.registry.ServiceTracker;
028
029 import java.io.File;
030
031 import java.util.HashMap;
032 import java.util.Iterator;
033 import java.util.List;
034 import java.util.Map;
035 import java.util.Set;
036 import java.util.concurrent.CopyOnWriteArrayList;
037
038
042 public class AutoDeployDir {
043
044 public static final String DEFAULT_NAME = "defaultAutoDeployDir";
045
046 public static void deploy(
047 AutoDeploymentContext autoDeploymentContext,
048 List<AutoDeployListener> autoDeployListeners)
049 throws AutoDeployException {
050
051 AutoDeployListener autoDeployListener = _serviceTracker.getService();
052
053 if (autoDeployListener != null) {
054 if (autoDeployListener.isDeployable(autoDeploymentContext)) {
055 autoDeployListener.deploy(autoDeploymentContext);
056
057 File file = autoDeploymentContext.getFile();
058
059 file.delete();
060
061 return;
062 }
063 }
064
065 String[] dirNames = PropsUtil.getArray(
066 PropsKeys.MODULE_FRAMEWORK_AUTO_DEPLOY_DIRS);
067
068 if (ArrayUtil.isEmpty(dirNames)) {
069 throw new AutoDeployException(
070 "The portal property \"" +
071 PropsKeys.MODULE_FRAMEWORK_AUTO_DEPLOY_DIRS +
072 "\" is not set");
073 }
074
075 String dirName = dirNames[0];
076
077 File file = autoDeploymentContext.getFile();
078
079 String fileName = file.getName();
080
081 if (StringUtil.endsWith(fileName, ".cfg")) {
082 for (String curDirName : dirNames) {
083 if (curDirName.endsWith("/configs")) {
084 dirName = curDirName;
085
086 break;
087 }
088 }
089 }
090 else if (StringUtil.endsWith(fileName, ".lpkg")) {
091 for (String curDirName : dirNames) {
092 if (curDirName.endsWith("/marketplace")) {
093 dirName = curDirName;
094
095 break;
096 }
097 }
098 }
099 else if (StringUtil.endsWith(fileName, ".war")) {
100 for (String curDirName : dirNames) {
101 if (curDirName.endsWith("/war")) {
102 dirName = curDirName;
103
104 break;
105 }
106 }
107 }
108 else {
109 for (String curDirName : dirNames) {
110 if (curDirName.endsWith("/modules")) {
111 dirName = curDirName;
112
113 break;
114 }
115 }
116 }
117
118 FileUtil.move(file, new File(dirName, fileName));
119 }
120
121 public AutoDeployDir(
122 String name, File deployDir, File destDir, long interval,
123 List<AutoDeployListener> autoDeployListeners) {
124
125 _name = name;
126 _deployDir = deployDir;
127 _destDir = destDir;
128 _interval = interval;
129 _autoDeployListeners = new CopyOnWriteArrayList<>(autoDeployListeners);
130 _blacklistFileTimestamps = new HashMap<>();
131 }
132
133 public File getDeployDir() {
134 return _deployDir;
135 }
136
137 public File getDestDir() {
138 return _destDir;
139 }
140
141 public long getInterval() {
142 return _interval;
143 }
144
145 public List<AutoDeployListener> getListeners() {
146 return _autoDeployListeners;
147 }
148
149 public String getName() {
150 return _name;
151 }
152
153 public void registerListener(AutoDeployListener listener) {
154 _autoDeployListeners.add(listener);
155 }
156
157 public void start() {
158 if (!_deployDir.exists()) {
159 if (_log.isInfoEnabled()) {
160 _log.info("Creating missing directory " + _deployDir);
161 }
162
163 boolean created = _deployDir.mkdirs();
164
165 if (!created) {
166 _log.error("Directory " + _deployDir + " could not be created");
167 }
168 }
169
170 if ((_interval > 0) &&
171 ((_autoDeployScanner == null) || !_autoDeployScanner.isAlive())) {
172
173 try {
174 Thread currentThread = Thread.currentThread();
175
176 _autoDeployScanner = new AutoDeployScanner(
177 currentThread.getThreadGroup(),
178 AutoDeployScanner.class.getName(), this);
179
180 _autoDeployScanner.start();
181
182 if (_log.isInfoEnabled()) {
183 _log.info("Auto deploy scanner started for " + _deployDir);
184 }
185 }
186 catch (Exception e) {
187 _log.error(e, e);
188
189 stop();
190
191 return;
192 }
193 }
194 else {
195 if (_log.isInfoEnabled()) {
196 _log.info("Auto deploy scanning is disabled for " + _deployDir);
197 }
198 }
199 }
200
201 public void stop() {
202 if (_autoDeployScanner != null) {
203 _autoDeployScanner.pause();
204 }
205
206 _serviceTracker.close();
207 }
208
209 public void unregisterListener(AutoDeployListener autoDeployListener) {
210 _autoDeployListeners.remove(autoDeployListener);
211 }
212
213 protected AutoDeploymentContext buildAutoDeploymentContext(File file) {
214 AutoDeploymentContext autoDeploymentContext =
215 new AutoDeploymentContext();
216
217 autoDeploymentContext.setFile(file);
218
219 return autoDeploymentContext;
220 }
221
222 protected void processFile(File file) {
223 String fileName = file.getName();
224
225 if (!file.canRead()) {
226 _log.error("Unable to read " + fileName);
227
228 return;
229 }
230
231 if (!file.canWrite()) {
232 _log.error("Unable to write " + fileName);
233
234 return;
235 }
236
237 if (_blacklistFileTimestamps.containsKey(fileName) &&
238 (_blacklistFileTimestamps.get(fileName) == file.lastModified())) {
239
240 if (_log.isDebugEnabled()) {
241 _log.debug(
242 "Skip processing of " + fileName + " because it is " +
243 "blacklisted");
244 }
245
246 return;
247 }
248
249 if (_log.isInfoEnabled()) {
250 _log.info("Processing " + fileName);
251 }
252
253 try {
254 AutoDeploymentContext autoDeploymentContext =
255 buildAutoDeploymentContext(file);
256
257 deploy(autoDeploymentContext, _autoDeployListeners);
258
259 return;
260 }
261 catch (Exception e) {
262 _log.error(e, e);
263 }
264
265 if (_log.isInfoEnabled()) {
266 _log.info("Add " + fileName + " to the blacklist");
267 }
268
269 _blacklistFileTimestamps.put(fileName, file.lastModified());
270 }
271
272 protected void scanDirectory() {
273 File[] files = _deployDir.listFiles();
274
275 if (files == null) {
276 return;
277 }
278
279 Set<String> blacklistedFileNames = _blacklistFileTimestamps.keySet();
280
281 Iterator<String> iterator = blacklistedFileNames.iterator();
282
283 while (iterator.hasNext()) {
284 String blacklistedFileName = iterator.next();
285
286 boolean blacklistedFileExists = false;
287
288 for (File file : files) {
289 if (StringUtil.equalsIgnoreCase(
290 blacklistedFileName, file.getName())) {
291
292 blacklistedFileExists = true;
293 }
294 }
295
296 if (!blacklistedFileExists) {
297 if (_log.isDebugEnabled()) {
298 _log.debug(
299 "Remove blacklisted file " + blacklistedFileName +
300 " because it was deleted");
301 }
302
303 iterator.remove();
304 }
305 }
306
307 for (File file : files) {
308 String fileName = file.getName();
309
310 fileName = StringUtil.toLowerCase(fileName);
311
312 if (file.isFile() &&
313 (fileName.endsWith(".jar") || fileName.endsWith(".lpkg") ||
314 fileName.endsWith(".war") || fileName.endsWith(".xml") ||
315 fileName.endsWith(".zip"))) {
316
317 processFile(file);
318 }
319 }
320 }
321
322 private static final Log _log = LogFactoryUtil.getLog(AutoDeployDir.class);
323
324 private static AutoDeployScanner _autoDeployScanner;
325 private static final ServiceTracker<AutoDeployListener, AutoDeployListener>
326 _serviceTracker;
327
328 static {
329 Registry registry = RegistryUtil.getRegistry();
330
331 _serviceTracker = registry.trackServices(AutoDeployListener.class);
332
333 _serviceTracker.open();
334 }
335
336 private final List<AutoDeployListener> _autoDeployListeners;
337 private final Map<String, Long> _blacklistFileTimestamps;
338 private final File _deployDir;
339 private final File _destDir;
340 private final long _interval;
341 private final String _name;
342
343 }