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
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 }