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