001: /**
002: * Copyright (c) 2000-2008 Liferay, Inc. All rights reserved.
003: *
004: * Permission is hereby granted, free of charge, to any person obtaining a copy
005: * of this software and associated documentation files (the "Software"), to deal
006: * in the Software without restriction, including without limitation the rights
007: * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
008: * copies of the Software, and to permit persons to whom the Software is
009: * furnished to do so, subject to the following conditions:
010: *
011: * The above copyright notice and this permission notice shall be included in
012: * all copies or substantial portions of the Software.
013: *
014: * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
015: * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
016: * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
017: * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
018: * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
019: * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
020: * SOFTWARE.
021: */package com.liferay.portal.theme;
022:
023: import com.liferay.portal.kernel.util.GetterUtil;
024: import com.liferay.portal.kernel.util.Validator;
025: import com.liferay.portal.service.impl.ThemeLocalUtil;
026: import com.liferay.portal.util.PortalUtil;
027: import com.liferay.portal.util.PropsValues;
028: import com.liferay.util.CollectionFactory;
029: import com.liferay.util.FileUtil;
030:
031: import java.io.File;
032:
033: import java.util.Map;
034:
035: import javax.servlet.ServletContext;
036:
037: import org.apache.commons.logging.Log;
038: import org.apache.commons.logging.LogFactory;
039:
040: import org.dom4j.Document;
041: import org.dom4j.Element;
042:
043: /**
044: * <a href="ThemeLoader.java.html"><b><i>View Source</i></b></a>
045: *
046: * @author Brian Wing Shun Chan
047: *
048: */
049: public class ThemeLoader {
050:
051: public String getServletContextName() {
052: return _servletContextName;
053: }
054:
055: public String getThemesPath() {
056: return _themesPath;
057: }
058:
059: public File getFileStorage() {
060: return _fileStorage;
061: }
062:
063: public synchronized void loadThemes() {
064: if (_log.isInfoEnabled()) {
065: _log.info("Loading themes in " + _fileStorage);
066: }
067:
068: File[] files = _fileStorage.listFiles();
069:
070: if (files == null) {
071: if (_log.isWarnEnabled()) {
072: _log.warn("There are no directories to process for "
073: + _fileStorage);
074: }
075:
076: return;
077: }
078:
079: for (int i = 0; i < files.length; i++) {
080: if (_log.isDebugEnabled()) {
081: _log.debug("Process directory " + files[i]);
082: }
083:
084: File liferayLookAndFeelXML = new File(files[i]
085: + "/liferay-look-and-feel.xml");
086:
087: if (liferayLookAndFeelXML.exists()) {
088: String lastModifiedKey = liferayLookAndFeelXML
089: .toString();
090:
091: Long prevLastModified = (Long) _lastModifiedMap
092: .get(lastModifiedKey);
093:
094: long lastModified = liferayLookAndFeelXML
095: .lastModified();
096:
097: if ((prevLastModified == null)
098: || (prevLastModified.longValue() < lastModified)) {
099:
100: registerTheme(liferayLookAndFeelXML);
101:
102: _lastModifiedMap.put(lastModifiedKey, new Long(
103: lastModified));
104: } else {
105: if (_log.isDebugEnabled()) {
106: _log
107: .debug("Do not refresh "
108: + liferayLookAndFeelXML
109: + " because it is has not been modified");
110: }
111: }
112: } else {
113: if (_log.isWarnEnabled()) {
114: _log
115: .warn(liferayLookAndFeelXML
116: + " does not exist");
117: }
118: }
119: }
120: }
121:
122: protected ThemeLoader(String servletContextName,
123: ServletContext ctx, String[] xmls) {
124:
125: _servletContextName = servletContextName;
126: _ctx = ctx;
127:
128: try {
129: Document doc = PortalUtil
130: .readDocumentFromXML(xmls[0], true);
131:
132: Element root = doc.getRootElement();
133:
134: _themesPath = GetterUtil.getString(root
135: .elementText("themes-path"), "/themes");
136:
137: String fileStorageValue = PropsValues.THEME_LOADER_STORAGE_PATH;
138:
139: fileStorageValue = GetterUtil.getString(root
140: .elementText("file-storage"), fileStorageValue);
141:
142: if (Validator.isNotNull(fileStorageValue)) {
143: _fileStorage = new File(fileStorageValue);
144: _loadFromServletContext = false;
145: } else {
146: _fileStorage = new File(ctx.getRealPath(_themesPath));
147: _loadFromServletContext = true;
148: }
149:
150: if (!_fileStorage.exists()) {
151: if (_log.isWarnEnabled()) {
152: _log.warn("File storage " + _fileStorage
153: + " does not exist");
154: }
155:
156: if (!_fileStorage.mkdirs()) {
157: _log
158: .error("Unable to create theme loader file storage at "
159: + _fileStorage);
160: }
161: }
162: } catch (Exception e) {
163: _log.error(e, e);
164: }
165:
166: loadThemes();
167: }
168:
169: protected void destroy() {
170: }
171:
172: protected void registerTheme(File liferayLookAndFeelXML) {
173: if (_log.isDebugEnabled()) {
174: _log.debug("Registering " + liferayLookAndFeelXML);
175: }
176:
177: try {
178: String content = FileUtil.read(liferayLookAndFeelXML);
179:
180: ThemeLocalUtil.init(_servletContextName, _ctx, _themesPath,
181: _loadFromServletContext, new String[] { content },
182: null);
183: } catch (Exception e) {
184: _log.error("Error registering theme "
185: + liferayLookAndFeelXML.toString(), e);
186: }
187: }
188:
189: private static Log _log = LogFactory.getLog(ThemeLoader.class);
190:
191: private String _servletContextName;
192: private ServletContext _ctx;
193: private String _themesPath;
194: private File _fileStorage;
195: private boolean _loadFromServletContext = true;
196: private Map _lastModifiedMap = CollectionFactory.getHashMap();
197:
198: }
|