1   /**
2    * Copyright (c) 2000-2009 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   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
12   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
13   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
14   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
15   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
17   * SOFTWARE.
18   */
19  
20  package com.liferay.portal.kernel.deploy.auto;
21  
22  import com.liferay.portal.kernel.log.Log;
23  import com.liferay.portal.kernel.log.LogFactoryUtil;
24  import com.liferay.portal.kernel.util.IntegerWrapper;
25  
26  import java.io.File;
27  
28  import java.util.HashMap;
29  import java.util.HashSet;
30  import java.util.List;
31  import java.util.Map;
32  import java.util.Set;
33  
34  /**
35   * <a href="AutoDeployDir.java.html"><b><i>View Source</i></b></a>
36   *
37   * @author Ivica Cardic
38   * @author Brian Wing Shun Chan
39   *
40   */
41  public class AutoDeployDir {
42  
43      public AutoDeployDir(
44          String name, File deployDir, File destDir, long interval,
45          int blacklistThreshold, List<AutoDeployListener> listeners) {
46  
47          _name = name;
48          _deployDir = deployDir;
49          _destDir = destDir;
50          _interval = interval;
51          _blacklistThreshold = blacklistThreshold;
52          _listeners = listeners;
53          _inProcessFiles = new HashMap<String, IntegerWrapper>();
54          _blacklistFiles = new HashSet<String>();
55      }
56  
57      public String getName() {
58          return _name;
59      }
60  
61      public File getDeployDir() {
62          return _deployDir;
63      }
64  
65      public File getDestDir() {
66          return _destDir;
67      }
68  
69      public long getInterval() {
70          return _interval;
71      }
72  
73      public int getBlacklistThreshold() {
74          return _blacklistThreshold;
75      }
76  
77      public List<AutoDeployListener> getListeners() {
78          return _listeners;
79      }
80  
81      public void start() {
82          if (!_deployDir.exists()) {
83              if (_log.isInfoEnabled()) {
84                  _log.info("Creating missing directory " + _deployDir);
85              }
86  
87              boolean created = _deployDir.mkdirs();
88  
89              if (!created) {
90                  _log.error("Directory " + _deployDir + " could not be created");
91              }
92          }
93  
94          if (_interval > 0) {
95              try {
96                  Thread currentThread = Thread.currentThread();
97  
98                  _scanner = new AutoDeployScanner(
99                      currentThread.getThreadGroup(),
100                     AutoDeployScanner.class.getName(), this);
101 
102                 _scanner.start();
103 
104                 if (_log.isInfoEnabled()) {
105                     _log.info("Auto deploy scanner started for " + _deployDir);
106                 }
107             }
108             catch (Exception e) {
109                 _log.error(e, e);
110 
111                 stop();
112 
113                 return;
114             }
115         }
116         else {
117             if (_log.isInfoEnabled()) {
118                 _log.info("Auto deploy scanning is disabled for " + _deployDir);
119             }
120         }
121     }
122 
123     public void stop() {
124         if (_scanner != null) {
125             _scanner.pause();
126         }
127     }
128 
129     protected void scanDirectory() {
130         File[] files = _deployDir.listFiles();
131 
132         for (int i = 0; i < files.length; i++) {
133             File file = files[i];
134 
135             String fileName = file.getName().toLowerCase();
136 
137             if ((file.isFile()) &&
138                 (fileName.endsWith(".war") || fileName.endsWith(".zip") ||
139                  fileName.endsWith(".xml"))) {
140 
141                 processFile(file);
142             }
143         }
144     }
145 
146     protected void processFile(File file) {
147         String fileName = file.getName();
148 
149         if (!file.canRead()) {
150             _log.error("Unable to read " + fileName);
151 
152             return;
153         }
154 
155         if (!file.canWrite()) {
156             _log.error("Unable to write " + fileName);
157 
158             return;
159         }
160 
161         if (_blacklistFiles.contains(fileName)) {
162             if (_log.isDebugEnabled()) {
163                 _log.debug(
164                     "Skip processing of " + fileName + " because it is " +
165                         "blacklisted. You must restart the server to remove " +
166                             "the file from the blacklist.");
167             }
168 
169             return;
170         }
171 
172         IntegerWrapper attempt = _inProcessFiles.get(fileName);
173 
174         if (attempt == null) {
175             attempt = new IntegerWrapper(1);
176 
177             _inProcessFiles.put(fileName, attempt);
178 
179             if (_log.isInfoEnabled()) {
180                 _log.info("Processing " + fileName);
181             }
182         }
183         else {
184             if (_log.isInfoEnabled()) {
185                 _log.info(
186                     "Processing " + fileName + ". This is attempt " +
187                         attempt.getValue() + ".");
188             }
189         }
190 
191         try {
192             for (AutoDeployListener listener : _listeners) {
193                 listener.deploy(file);
194             }
195 
196             if (file.delete()) {
197                 _inProcessFiles.remove(fileName);
198             }
199             else {
200                 _log.error("Auto deploy failed to remove " + fileName);
201 
202                 if (_log.isInfoEnabled()) {
203                     _log.info("Add " + fileName + " to the blacklist");
204                 }
205 
206                 _blacklistFiles.add(fileName);
207             }
208         }
209         catch (Exception e) {
210             _log.error(e, e);
211 
212             attempt.increment();
213 
214             if (attempt.getValue() >= _blacklistThreshold) {
215                 if (_log.isInfoEnabled()) {
216                     _log.info("Add " + fileName + " to the blacklist");
217                 }
218 
219                 _blacklistFiles.add(fileName);
220             }
221         }
222     }
223 
224     private static Log _log = LogFactoryUtil.getLog(AutoDeployDir.class);
225 
226     private String _name;
227     private File _deployDir;
228     private File _destDir;
229     private long _interval;
230     private int _blacklistThreshold;
231     private List<AutoDeployListener> _listeners;
232     private Map<String, IntegerWrapper> _inProcessFiles;
233     private Set<String> _blacklistFiles;
234     private AutoDeployScanner _scanner;
235 
236 }