1   /**
2    * Copyright (c) 2000-2009 Liferay, Inc. All rights reserved.
3    *
4    *
5    *
6    *
7    * The contents of this file are subject to the terms of the Liferay Enterprise
8    * Subscription License ("License"). You may not use this file except in
9    * compliance with the License. You can obtain a copy of the License by
10   * contacting Liferay, Inc. See the License for the specific language governing
11   * permissions and limitations under the License, including but not limited to
12   * distribution rights 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.theme;
24  
25  import com.liferay.portal.kernel.log.Log;
26  import com.liferay.portal.kernel.log.LogFactoryUtil;
27  import com.liferay.portal.kernel.util.FileUtil;
28  import com.liferay.portal.kernel.util.GetterUtil;
29  import com.liferay.portal.kernel.util.Validator;
30  import com.liferay.portal.kernel.xml.Document;
31  import com.liferay.portal.kernel.xml.Element;
32  import com.liferay.portal.kernel.xml.SAXReaderUtil;
33  import com.liferay.portal.service.ThemeLocalServiceUtil;
34  import com.liferay.portal.util.PropsValues;
35  
36  import java.io.File;
37  
38  import java.util.HashMap;
39  import java.util.Map;
40  
41  import javax.servlet.ServletContext;
42  
43  /**
44   * <a href="ThemeLoader.java.html"><b><i>View Source</i></b></a>
45   *
46   * @author Brian Wing Shun Chan
47   */
48  public class ThemeLoader {
49  
50      public String getServletContextName() {
51          return _servletContextName;
52      }
53  
54      public String getThemesPath() {
55          return _themesPath;
56      }
57  
58      public File getFileStorage() {
59          return _fileStorage;
60      }
61  
62      public synchronized void loadThemes() {
63          if (_log.isInfoEnabled()) {
64              _log.info("Loading themes in " + _fileStorage);
65          }
66  
67          File[] files = _fileStorage.listFiles();
68  
69          if (files == null) {
70              if (_log.isWarnEnabled()) {
71                  _log.warn(
72                      "There are no directories to process for  " + _fileStorage);
73              }
74  
75              return;
76          }
77  
78          for (int i = 0; i < files.length; i++) {
79              if (_log.isDebugEnabled()) {
80                  _log.debug("Process directory " + files[i]);
81              }
82  
83              File liferayLookAndFeelXML = new File(
84                  files[i] + "/liferay-look-and-feel.xml");
85  
86              if (liferayLookAndFeelXML.exists()) {
87                  String lastModifiedKey = liferayLookAndFeelXML.toString();
88  
89                  Long prevLastModified = _lastModifiedMap.get(lastModifiedKey);
90  
91                  long lastModified = liferayLookAndFeelXML.lastModified();
92  
93                  if ((prevLastModified == null) ||
94                      (prevLastModified.longValue() < lastModified)) {
95  
96                      registerTheme(liferayLookAndFeelXML);
97  
98                      _lastModifiedMap.put(lastModifiedKey, lastModified);
99                  }
100                 else {
101                     if (_log.isDebugEnabled()) {
102                         _log.debug(
103                             "Do not refresh " + liferayLookAndFeelXML +
104                                 " because it is has not been modified");
105                     }
106                 }
107             }
108             else {
109                 if (_log.isWarnEnabled()) {
110                     _log.warn(liferayLookAndFeelXML + " does not exist");
111                 }
112             }
113         }
114     }
115 
116     protected ThemeLoader(
117         String servletContextName, ServletContext servletContext,
118         String[] xmls) {
119 
120         _servletContextName = servletContextName;
121         _servletContext = servletContext;
122 
123         try {
124             Document doc = SAXReaderUtil.read(xmls[0], true);
125 
126             Element root = doc.getRootElement();
127 
128             _themesPath = GetterUtil.getString(
129                 root.elementText("themes-path"), "/themes");
130 
131             String fileStorageValue = PropsValues.THEME_LOADER_STORAGE_PATH;
132 
133             fileStorageValue = GetterUtil.getString(
134                 root.elementText("file-storage"), fileStorageValue);
135 
136             if (Validator.isNotNull(fileStorageValue)) {
137                 _fileStorage = new File(fileStorageValue);
138                 _loadFromServletContext = false;
139             }
140             else {
141                 _fileStorage = new File(
142                     servletContext.getRealPath(_themesPath));
143                 _loadFromServletContext = true;
144             }
145 
146             if (!_fileStorage.exists()) {
147                 if (_log.isWarnEnabled()) {
148                     _log.warn(
149                         "File storage " + _fileStorage + " does not exist");
150                 }
151 
152                 if (!_fileStorage.mkdirs()) {
153                     _log.error(
154                         "Unable to create theme loader file storage at " +
155                             _fileStorage);
156                 }
157             }
158         }
159         catch (Exception e) {
160             _log.error(e, e);
161         }
162 
163         loadThemes();
164     }
165 
166     protected void destroy() {
167     }
168 
169     protected void registerTheme(File liferayLookAndFeelXML) {
170         if (_log.isDebugEnabled()) {
171             _log.debug("Registering " + liferayLookAndFeelXML);
172         }
173 
174         try {
175             String content = FileUtil.read(liferayLookAndFeelXML);
176 
177             ThemeLocalServiceUtil.init(
178                 _servletContextName, _servletContext, _themesPath,
179                 _loadFromServletContext, new String[] {content}, null);
180         }
181         catch (Exception e) {
182             _log.error(
183                 "Error registering theme " + liferayLookAndFeelXML.toString(),
184                 e);
185         }
186     }
187 
188     private static Log _log = LogFactoryUtil.getLog(ThemeLoader.class);
189 
190     private String _servletContextName;
191     private ServletContext _servletContext;
192     private String _themesPath;
193     private File _fileStorage;
194     private boolean _loadFromServletContext = true;
195     private Map<String, Long> _lastModifiedMap = new HashMap<String, Long>();
196 
197 }