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<String>();
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();
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<AutoDeployListener>(
085 autoDeployListeners);
086 _blacklistFileTimestamps = new HashMap<String, Long>();
087 }
088
089 public File getDeployDir() {
090 return _deployDir;
091 }
092
093 public File getDestDir() {
094 return _destDir;
095 }
096
097 public long getInterval() {
098 return _interval;
099 }
100
101 public List<AutoDeployListener> getListeners() {
102 return _autoDeployListeners;
103 }
104
105 public String getName() {
106 return _name;
107 }
108
109 public void registerListener(AutoDeployListener listener) {
110 _autoDeployListeners.add(listener);
111 }
112
113 public void start() {
114 if (!_deployDir.exists()) {
115 if (_log.isInfoEnabled()) {
116 _log.info("Creating missing directory " + _deployDir);
117 }
118
119 boolean created = _deployDir.mkdirs();
120
121 if (!created) {
122 _log.error("Directory " + _deployDir + " could not be created");
123 }
124 }
125
126 if (_interval > 0) {
127 try {
128 Thread currentThread = Thread.currentThread();
129
130 _autoDeployScanner = new AutoDeployScanner(
131 currentThread.getThreadGroup(),
132 AutoDeployScanner.class.getName(), this);
133
134 _autoDeployScanner.start();
135
136 if (_log.isInfoEnabled()) {
137 _log.info("Auto deploy scanner started for " + _deployDir);
138 }
139 }
140 catch (Exception e) {
141 _log.error(e, e);
142
143 stop();
144
145 return;
146 }
147 }
148 else {
149 if (_log.isInfoEnabled()) {
150 _log.info("Auto deploy scanning is disabled for " + _deployDir);
151 }
152 }
153 }
154
155 public void stop() {
156 if (_autoDeployScanner != null) {
157 _autoDeployScanner.pause();
158 }
159 }
160
161 public void unregisterListener(AutoDeployListener autoDeployListener) {
162 _autoDeployListeners.remove(autoDeployListener);
163 }
164
165 protected AutoDeploymentContext buildAutoDeploymentContext(File file) {
166 AutoDeploymentContext autoDeploymentContext =
167 new AutoDeploymentContext();
168
169 autoDeploymentContext.setFile(file);
170
171 return autoDeploymentContext;
172 }
173
174 protected void processFile(File file) {
175 String fileName = file.getName();
176
177 if (!file.canRead()) {
178 _log.error("Unable to read " + fileName);
179
180 return;
181 }
182
183 if (!file.canWrite()) {
184 _log.error("Unable to write " + fileName);
185
186 return;
187 }
188
189 if (_blacklistFileTimestamps.containsKey(fileName) &&
190 (_blacklistFileTimestamps.get(fileName) == file.lastModified())) {
191
192 if (_log.isDebugEnabled()) {
193 _log.debug(
194 "Skip processing of " + fileName + " because it is " +
195 "blacklisted");
196 }
197
198 return;
199 }
200
201 if (_log.isInfoEnabled()) {
202 _log.info("Processing " + fileName);
203 }
204
205 try {
206 AutoDeploymentContext autoDeploymentContext =
207 buildAutoDeploymentContext(file);
208
209 deploy(autoDeploymentContext, _autoDeployListeners);
210
211 if (file.delete()) {
212 return;
213 }
214
215 _log.error("Auto deploy failed to remove " + fileName);
216 }
217 catch (Exception e) {
218 _log.error(e, e);
219 }
220
221 if (_log.isInfoEnabled()) {
222 _log.info("Add " + fileName + " to the blacklist");
223 }
224
225 _blacklistFileTimestamps.put(fileName, file.lastModified());
226 }
227
228 protected void scanDirectory() {
229 File[] files = _deployDir.listFiles();
230
231 if (files == null) {
232 return;
233 }
234
235 Set<String> blacklistedFileNames = _blacklistFileTimestamps.keySet();
236
237 Iterator<String> iterator = blacklistedFileNames.iterator();
238
239 while (iterator.hasNext()) {
240 String blacklistedFileName = iterator.next();
241
242 boolean blacklistedFileExists = false;
243
244 for (File file : files) {
245 if (StringUtil.equalsIgnoreCase(
246 blacklistedFileName, file.getName())) {
247
248 blacklistedFileExists = true;
249 }
250 }
251
252 if (!blacklistedFileExists) {
253 if (_log.isDebugEnabled()) {
254 _log.debug(
255 "Remove blacklisted file " + blacklistedFileName +
256 " because it was deleted");
257 }
258
259 iterator.remove();
260 }
261 }
262
263 for (File file : files) {
264 String fileName = file.getName();
265
266 fileName = StringUtil.toLowerCase(fileName);
267
268 if (file.isFile() &&
269 (fileName.endsWith(".jar") || fileName.endsWith(".lpkg") ||
270 fileName.endsWith(".war") || fileName.endsWith(".xml") ||
271 fileName.endsWith(".zip"))) {
272
273 processFile(file);
274 }
275 }
276 }
277
278 private static Log _log = LogFactoryUtil.getLog(AutoDeployDir.class);
279
280 private List<AutoDeployListener> _autoDeployListeners;
281 private AutoDeployScanner _autoDeployScanner;
282 private Map<String, Long> _blacklistFileTimestamps;
283 private File _deployDir;
284 private File _destDir;
285 private long _interval;
286 private String _name;
287
288 }