1   /**
2    * Copyright (c) 2000-2010 Liferay, Inc. All rights reserved.
3    *
4    * The contents of this file are subject to the terms of the Liferay Enterprise
5    * Subscription License ("License"). You may not use this file except in
6    * compliance with the License. You can obtain a copy of the License by
7    * contacting Liferay, Inc. See the License for the specific language governing
8    * permissions and limitations under the License, including but not limited to
9    * distribution rights of the Software.
10   *
11   *
12   *
13   */
14  
15  package com.liferay.portal.kernel.deploy.auto;
16  
17  import com.liferay.portal.kernel.log.Log;
18  import com.liferay.portal.kernel.log.LogFactoryUtil;
19  import com.liferay.portal.kernel.util.IntegerWrapper;
20  
21  import java.io.File;
22  
23  import java.util.HashMap;
24  import java.util.HashSet;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.Set;
28  import java.util.concurrent.CopyOnWriteArrayList;
29  
30  /**
31   * <a href="AutoDeployDir.java.html"><b><i>View Source</i></b></a>
32   *
33   * @author Ivica Cardic
34   * @author Brian Wing Shun Chan
35   */
36  public class AutoDeployDir {
37  
38      public static final String DEFAULT_NAME = "defaultAutoDeployDir";
39  
40      public AutoDeployDir(
41          String name, File deployDir, File destDir, long interval,
42          int blacklistThreshold, List<AutoDeployListener> autoDeployListeners) {
43  
44          _name = name;
45          _deployDir = deployDir;
46          _destDir = destDir;
47          _interval = interval;
48          _blacklistThreshold = blacklistThreshold;
49          _autoDeployListeners = new CopyOnWriteArrayList<AutoDeployListener>(
50              autoDeployListeners);
51          _inProcessFiles = new HashMap<String, IntegerWrapper>();
52          _blacklistFiles = new HashSet<String>();
53      }
54  
55      public int getBlacklistThreshold() {
56          return _blacklistThreshold;
57      }
58  
59      public File getDeployDir() {
60          return _deployDir;
61      }
62  
63      public File getDestDir() {
64          return _destDir;
65      }
66  
67      public long getInterval() {
68          return _interval;
69      }
70  
71      public List<AutoDeployListener> getListeners() {
72          return _autoDeployListeners;
73      }
74  
75      public String getName() {
76          return _name;
77      }
78  
79      public void registerListener(AutoDeployListener listener) {
80          _autoDeployListeners.add(listener);
81      }
82  
83      public void start() {
84          if (!_deployDir.exists()) {
85              if (_log.isInfoEnabled()) {
86                  _log.info("Creating missing directory " + _deployDir);
87              }
88  
89              boolean created = _deployDir.mkdirs();
90  
91              if (!created) {
92                  _log.error("Directory " + _deployDir + " could not be created");
93              }
94          }
95  
96          if (_interval > 0) {
97              try {
98                  Thread currentThread = Thread.currentThread();
99  
100                 _autoDeployScanner = new AutoDeployScanner(
101                     currentThread.getThreadGroup(),
102                     AutoDeployScanner.class.getName(), this);
103 
104                 _autoDeployScanner.start();
105 
106                 if (_log.isInfoEnabled()) {
107                     _log.info("Auto deploy scanner started for " + _deployDir);
108                 }
109             }
110             catch (Exception e) {
111                 _log.error(e, e);
112 
113                 stop();
114 
115                 return;
116             }
117         }
118         else {
119             if (_log.isInfoEnabled()) {
120                 _log.info("Auto deploy scanning is disabled for " + _deployDir);
121             }
122         }
123     }
124 
125     public void stop() {
126         if (_autoDeployScanner != null) {
127             _autoDeployScanner.pause();
128         }
129     }
130 
131     public void unregisterListener(AutoDeployListener autoDeployListener) {
132         _autoDeployListeners.remove(autoDeployListener);
133     }
134 
135     protected void processFile(File file) {
136         String fileName = file.getName();
137 
138         if (!file.canRead()) {
139             _log.error("Unable to read " + fileName);
140 
141             return;
142         }
143 
144         if (!file.canWrite()) {
145             _log.error("Unable to write " + fileName);
146 
147             return;
148         }
149 
150         if (_blacklistFiles.contains(fileName)) {
151             if (_log.isDebugEnabled()) {
152                 _log.debug(
153                     "Skip processing of " + fileName + " because it is " +
154                         "blacklisted. You must restart the server to remove " +
155                             "the file from the blacklist.");
156             }
157 
158             return;
159         }
160 
161         IntegerWrapper attempt = _inProcessFiles.get(fileName);
162 
163         if (attempt == null) {
164             attempt = new IntegerWrapper(1);
165 
166             _inProcessFiles.put(fileName, attempt);
167 
168             if (_log.isInfoEnabled()) {
169                 _log.info("Processing " + fileName);
170             }
171         }
172         else {
173             if (_log.isInfoEnabled()) {
174                 _log.info(
175                     "Processing " + fileName + ". This is attempt " +
176                         attempt.getValue() + ".");
177             }
178         }
179 
180         try {
181             for (AutoDeployListener autoDeployListener : _autoDeployListeners) {
182                 autoDeployListener.deploy(file);
183             }
184 
185             if (file.delete()) {
186                 _inProcessFiles.remove(fileName);
187             }
188             else {
189                 _log.error("Auto deploy failed to remove " + fileName);
190 
191                 if (_log.isInfoEnabled()) {
192                     _log.info("Add " + fileName + " to the blacklist");
193                 }
194 
195                 _blacklistFiles.add(fileName);
196             }
197         }
198         catch (Exception e) {
199             _log.error(e, e);
200 
201             attempt.increment();
202 
203             if (attempt.getValue() >= _blacklistThreshold) {
204                 if (_log.isInfoEnabled()) {
205                     _log.info("Add " + fileName + " to the blacklist");
206                 }
207 
208                 _blacklistFiles.add(fileName);
209             }
210         }
211     }
212 
213     protected void scanDirectory() {
214         File[] files = _deployDir.listFiles();
215 
216         for (File file : files) {
217             String fileName = file.getName().toLowerCase();
218 
219             if ((file.isFile()) &&
220                 (fileName.endsWith(".war") || fileName.endsWith(".zip") ||
221                  fileName.endsWith(".xml"))) {
222 
223                 processFile(file);
224             }
225         }
226     }
227 
228     private static Log _log = LogFactoryUtil.getLog(AutoDeployDir.class);
229 
230     private List<AutoDeployListener> _autoDeployListeners;
231     private AutoDeployScanner _autoDeployScanner;
232     private Set<String> _blacklistFiles;
233     private int _blacklistThreshold;
234     private File _deployDir;
235     private File _destDir;
236     private Map<String, IntegerWrapper> _inProcessFiles;
237     private long _interval;
238     private String _name;
239 
240 }