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