1
22
23 package com.liferay.portal.theme;
24
25 import com.liferay.portal.kernel.util.GetterUtil;
26 import com.liferay.portal.kernel.util.Validator;
27 import com.liferay.portal.service.impl.ThemeLocalUtil;
28 import com.liferay.portal.util.DocumentUtil;
29 import com.liferay.portal.util.PropsValues;
30 import com.liferay.util.FileUtil;
31
32 import java.io.File;
33
34 import java.util.HashMap;
35 import java.util.Map;
36
37 import javax.servlet.ServletContext;
38
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41
42 import org.dom4j.Document;
43 import org.dom4j.Element;
44
45
51 public class ThemeLoader {
52
53 public String getServletContextName() {
54 return _servletContextName;
55 }
56
57 public String getThemesPath() {
58 return _themesPath;
59 }
60
61 public File getFileStorage() {
62 return _fileStorage;
63 }
64
65 public synchronized void loadThemes() {
66 if (_log.isInfoEnabled()) {
67 _log.info("Loading themes in " + _fileStorage);
68 }
69
70 File[] files = _fileStorage.listFiles();
71
72 if (files == null) {
73 if (_log.isWarnEnabled()) {
74 _log.warn(
75 "There are no directories to process for " + _fileStorage);
76 }
77
78 return;
79 }
80
81 for (int i = 0; i < files.length; i++) {
82 if (_log.isDebugEnabled()) {
83 _log.debug("Process directory " + files[i]);
84 }
85
86 File liferayLookAndFeelXML = new File(
87 files[i] + "/liferay-look-and-feel.xml");
88
89 if (liferayLookAndFeelXML.exists()) {
90 String lastModifiedKey = liferayLookAndFeelXML.toString();
91
92 Long prevLastModified = _lastModifiedMap.get(lastModifiedKey);
93
94 long lastModified = liferayLookAndFeelXML.lastModified();
95
96 if ((prevLastModified == null) ||
97 (prevLastModified.longValue() < lastModified)) {
98
99 registerTheme(liferayLookAndFeelXML);
100
101 _lastModifiedMap.put(lastModifiedKey, lastModified);
102 }
103 else {
104 if (_log.isDebugEnabled()) {
105 _log.debug(
106 "Do not refresh " + liferayLookAndFeelXML +
107 " because it is has not been modified");
108 }
109 }
110 }
111 else {
112 if (_log.isWarnEnabled()) {
113 _log.warn(liferayLookAndFeelXML + " does not exist");
114 }
115 }
116 }
117 }
118
119 protected ThemeLoader(
120 String servletContextName, ServletContext ctx, String[] xmls) {
121
122 _servletContextName = servletContextName;
123 _ctx = ctx;
124
125 try {
126 Document doc = DocumentUtil.readDocumentFromXML(xmls[0], true);
127
128 Element root = doc.getRootElement();
129
130 _themesPath = GetterUtil.getString(
131 root.elementText("themes-path"), "/themes");
132
133 String fileStorageValue = PropsValues.THEME_LOADER_STORAGE_PATH;
134
135 fileStorageValue = GetterUtil.getString(
136 root.elementText("file-storage"), fileStorageValue);
137
138 if (Validator.isNotNull(fileStorageValue)) {
139 _fileStorage = new File(fileStorageValue);
140 _loadFromServletContext = false;
141 }
142 else {
143 _fileStorage = new File(ctx.getRealPath(_themesPath));
144 _loadFromServletContext = true;
145 }
146
147 if (!_fileStorage.exists()) {
148 if (_log.isWarnEnabled()) {
149 _log.warn(
150 "File storage " + _fileStorage + " does not exist");
151 }
152
153 if (!_fileStorage.mkdirs()) {
154 _log.error(
155 "Unable to create theme loader file storage at " +
156 _fileStorage);
157 }
158 }
159 }
160 catch (Exception e) {
161 _log.error(e, e);
162 }
163
164 loadThemes();
165 }
166
167 protected void destroy() {
168 }
169
170 protected void registerTheme(File liferayLookAndFeelXML) {
171 if (_log.isDebugEnabled()) {
172 _log.debug("Registering " + liferayLookAndFeelXML);
173 }
174
175 try {
176 String content = FileUtil.read(liferayLookAndFeelXML);
177
178 ThemeLocalUtil.init(
179 _servletContextName, _ctx, _themesPath, _loadFromServletContext,
180 new String[] {content}, null);
181 }
182 catch (Exception e) {
183 _log.error(
184 "Error registering theme " + liferayLookAndFeelXML.toString(),
185 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<String, Long> _lastModifiedMap = new HashMap<String, Long>();
197
198 }