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.StringBundler;
021 import com.liferay.portal.kernel.util.StringPool;
022 import com.liferay.portal.kernel.util.StringUtil;
023
024 import java.io.File;
025
026 import java.util.ArrayList;
027 import java.util.HashMap;
028 import java.util.Iterator;
029 import java.util.List;
030 import java.util.Map;
031 import java.util.Set;
032 import java.util.concurrent.CopyOnWriteArrayList;
033
034
038 public class AutoDeployDir {
039
040 public static final String DEFAULT_NAME = "defaultAutoDeployDir";
041
042
045 public static void deploy(
046 AutoDeploymentContext autoDeploymentContext,
047 List<AutoDeployListener> autoDeployListeners)
048 throws AutoDeployException {
049
050 List<AutoDeployListener> deployableAutoDeployListeners =
051 new ArrayList<>();
052
053 for (AutoDeployListener autoDeployListener : autoDeployListeners) {
054 if (autoDeployListener.isDeployable(autoDeploymentContext)) {
055 deployableAutoDeployListeners.add(autoDeployListener);
056 }
057 }
058
059 if (deployableAutoDeployListeners.size() > 1) {
060 StringBundler sb = new StringBundler(
061 3 + (deployableAutoDeployListeners.size() * 2) - 1);
062
063 sb.append("More than one auto deploy listener is available for ");
064 sb.append(autoDeploymentContext.getFile());
065 sb.append(": ");
066
067 for (int i = 0; i < deployableAutoDeployListeners.size(); i++) {
068 AutoDeployListener deployableAutoDeployListener =
069 deployableAutoDeployListeners.get(i);
070
071 Class<?> clazz = deployableAutoDeployListener.getClass();
072
073 if (i != 0) {
074 sb.append(StringPool.COMMA_AND_SPACE);
075 }
076
077 sb.append(clazz.getName());
078 }
079
080 throw new AutoDeployException(sb.toString());
081 }
082
083 for (AutoDeployListener deployableAutoDeployListener :
084 deployableAutoDeployListeners) {
085
086 deployableAutoDeployListener.deploy(autoDeploymentContext);
087 }
088 }
089
090 public AutoDeployDir(
091 String name, File deployDir, File destDir, long interval,
092 List<AutoDeployListener> autoDeployListeners) {
093
094 _name = name;
095 _deployDir = deployDir;
096 _destDir = destDir;
097 _interval = interval;
098 _autoDeployListeners = new CopyOnWriteArrayList<>(autoDeployListeners);
099 _blacklistFileTimestamps = new HashMap<>();
100 }
101
102 public File getDeployDir() {
103 return _deployDir;
104 }
105
106 public File getDestDir() {
107 return _destDir;
108 }
109
110 public long getInterval() {
111 return _interval;
112 }
113
114 public List<AutoDeployListener> getListeners() {
115 return _autoDeployListeners;
116 }
117
118 public String getName() {
119 return _name;
120 }
121
122 public void registerListener(AutoDeployListener listener) {
123 _autoDeployListeners.add(listener);
124 }
125
126 public void start() {
127 if (!_deployDir.exists()) {
128 if (_log.isInfoEnabled()) {
129 _log.info("Creating missing directory " + _deployDir);
130 }
131
132 boolean created = _deployDir.mkdirs();
133
134 if (!created) {
135 _log.error("Directory " + _deployDir + " could not be created");
136 }
137 }
138
139 if ((_interval > 0) &&
140 ((_autoDeployScanner == null) || !_autoDeployScanner.isAlive())) {
141
142 try {
143 Thread currentThread = Thread.currentThread();
144
145 _autoDeployScanner = new AutoDeployScanner(
146 currentThread.getThreadGroup(),
147 AutoDeployScanner.class.getName(), this);
148
149 _autoDeployScanner.start();
150
151 if (_log.isInfoEnabled()) {
152 _log.info("Auto deploy scanner started for " + _deployDir);
153 }
154 }
155 catch (Exception e) {
156 _log.error(e, e);
157
158 stop();
159
160 return;
161 }
162 }
163 else {
164 if (_log.isInfoEnabled()) {
165 _log.info("Auto deploy scanning is disabled for " + _deployDir);
166 }
167 }
168 }
169
170 public void stop() {
171 if (_autoDeployScanner != null) {
172 _autoDeployScanner.pause();
173 }
174 }
175
176 public void unregisterListener(AutoDeployListener autoDeployListener) {
177 _autoDeployListeners.remove(autoDeployListener);
178 }
179
180 protected AutoDeploymentContext buildAutoDeploymentContext(File file) {
181 AutoDeploymentContext autoDeploymentContext =
182 new AutoDeploymentContext();
183
184 autoDeploymentContext.setFile(file);
185
186 return autoDeploymentContext;
187 }
188
189 protected void processFile(File file) {
190 String fileName = file.getName();
191
192 if (!file.canRead()) {
193 _log.error("Unable to read " + fileName);
194
195 return;
196 }
197
198 if (!file.canWrite()) {
199 _log.error("Unable to write " + fileName);
200
201 return;
202 }
203
204 if (_blacklistFileTimestamps.containsKey(fileName) &&
205 (_blacklistFileTimestamps.get(fileName) == file.lastModified())) {
206
207 if (_log.isDebugEnabled()) {
208 _log.debug(
209 "Skip processing of " + fileName + " because it is " +
210 "blacklisted");
211 }
212
213 return;
214 }
215
216 if (_log.isInfoEnabled()) {
217 _log.info("Processing " + fileName);
218 }
219
220 try {
221 AutoDeploymentContext autoDeploymentContext =
222 buildAutoDeploymentContext(file);
223
224 deploy(autoDeploymentContext, _autoDeployListeners);
225
226 if (file.delete()) {
227 return;
228 }
229
230 _log.error("Auto deploy failed to remove " + fileName);
231 }
232 catch (Exception e) {
233 _log.error(e, e);
234 }
235
236 if (_log.isInfoEnabled()) {
237 _log.info("Add " + fileName + " to the blacklist");
238 }
239
240 _blacklistFileTimestamps.put(fileName, file.lastModified());
241 }
242
243 protected void scanDirectory() {
244 File[] files = _deployDir.listFiles();
245
246 if (files == null) {
247 return;
248 }
249
250 Set<String> blacklistedFileNames = _blacklistFileTimestamps.keySet();
251
252 Iterator<String> iterator = blacklistedFileNames.iterator();
253
254 while (iterator.hasNext()) {
255 String blacklistedFileName = iterator.next();
256
257 boolean blacklistedFileExists = false;
258
259 for (File file : files) {
260 if (StringUtil.equalsIgnoreCase(
261 blacklistedFileName, file.getName())) {
262
263 blacklistedFileExists = true;
264 }
265 }
266
267 if (!blacklistedFileExists) {
268 if (_log.isDebugEnabled()) {
269 _log.debug(
270 "Remove blacklisted file " + blacklistedFileName +
271 " because it was deleted");
272 }
273
274 iterator.remove();
275 }
276 }
277
278 for (File file : files) {
279 String fileName = file.getName();
280
281 fileName = StringUtil.toLowerCase(fileName);
282
283 if (file.isFile() &&
284 (fileName.endsWith(".jar") || fileName.endsWith(".lpkg") ||
285 fileName.endsWith(".war") || fileName.endsWith(".xml") ||
286 fileName.endsWith(".zip"))) {
287
288 processFile(file);
289 }
290 }
291 }
292
293 private static final Log _log = LogFactoryUtil.getLog(AutoDeployDir.class);
294
295 private static AutoDeployScanner _autoDeployScanner;
296
297 private final List<AutoDeployListener> _autoDeployListeners;
298 private final Map<String, Long> _blacklistFileTimestamps;
299 private final File _deployDir;
300 private final File _destDir;
301 private final long _interval;
302 private final String _name;
303
304 }