1
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
49 public class ThemeLoader {
50
51 public String getServletContextName() {
52 return _servletContextName;
53 }
54
55 public String getThemesPath() {
56 return _themesPath;
57 }
58
59 public File getFileStorage() {
60 return _fileStorage;
61 }
62
63 public synchronized void loadThemes() {
64 if (_log.isInfoEnabled()) {
65 _log.info("Loading themes in " + _fileStorage);
66 }
67
68 File[] files = _fileStorage.listFiles();
69
70 if (files == null) {
71 if (_log.isWarnEnabled()) {
72 _log.warn(
73 "There are no directories to process for " + _fileStorage);
74 }
75
76 return;
77 }
78
79 for (int i = 0; i < files.length; i++) {
80 if (_log.isDebugEnabled()) {
81 _log.debug("Process directory " + files[i]);
82 }
83
84 File liferayLookAndFeelXML = new File(
85 files[i] + "/liferay-look-and-feel.xml");
86
87 if (liferayLookAndFeelXML.exists()) {
88 String lastModifiedKey = liferayLookAndFeelXML.toString();
89
90 Long prevLastModified = _lastModifiedMap.get(lastModifiedKey);
91
92 long lastModified = liferayLookAndFeelXML.lastModified();
93
94 if ((prevLastModified == null) ||
95 (prevLastModified.longValue() < lastModified)) {
96
97 registerTheme(liferayLookAndFeelXML);
98
99 _lastModifiedMap.put(lastModifiedKey, lastModified);
100 }
101 else {
102 if (_log.isDebugEnabled()) {
103 _log.debug(
104 "Do not refresh " + liferayLookAndFeelXML +
105 " because it is has not been modified");
106 }
107 }
108 }
109 else {
110 if (_log.isWarnEnabled()) {
111 _log.warn(liferayLookAndFeelXML + " does not exist");
112 }
113 }
114 }
115 }
116
117 protected ThemeLoader(
118 String servletContextName, ServletContext servletContext,
119 String[] xmls) {
120
121 _servletContextName = servletContextName;
122 _servletContext = servletContext;
123
124 try {
125 Document doc = SAXReaderUtil.read(xmls[0], true);
126
127 Element root = doc.getRootElement();
128
129 _themesPath = GetterUtil.getString(
130 root.elementText("themes-path"), "/themes");
131
132 String fileStorageValue = PropsValues.THEME_LOADER_STORAGE_PATH;
133
134 fileStorageValue = GetterUtil.getString(
135 root.elementText("file-storage"), fileStorageValue);
136
137 if (Validator.isNotNull(fileStorageValue)) {
138 _fileStorage = new File(fileStorageValue);
139 _loadFromServletContext = false;
140 }
141 else {
142 _fileStorage = new File(
143 servletContext.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 ThemeLocalServiceUtil.init(
179 _servletContextName, _servletContext, _themesPath,
180 _loadFromServletContext, 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 = LogFactoryUtil.getLog(ThemeLoader.class);
190
191 private String _servletContextName;
192 private ServletContext _servletContext;
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 }