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