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