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