001
014
015 package com.liferay.portal.theme;
016
017 import com.liferay.portal.kernel.log.Log;
018 import com.liferay.portal.kernel.log.LogFactoryUtil;
019 import com.liferay.portal.kernel.util.FileUtil;
020 import com.liferay.portal.kernel.util.GetterUtil;
021 import com.liferay.portal.kernel.util.Validator;
022 import com.liferay.portal.kernel.xml.Document;
023 import com.liferay.portal.kernel.xml.Element;
024 import com.liferay.portal.kernel.xml.UnsecureSAXReaderUtil;
025 import com.liferay.portal.service.ThemeLocalServiceUtil;
026 import com.liferay.portal.util.PropsValues;
027
028 import java.io.File;
029
030 import java.util.HashMap;
031 import java.util.Map;
032
033 import javax.servlet.ServletContext;
034
035
038 public class ThemeLoader {
039
040 public File getFileStorage() {
041 return _fileStorage;
042 }
043
044 public String getServletContextName() {
045 return _servletContextName;
046 }
047
048 public String getThemesPath() {
049 return _themesPath;
050 }
051
052 public synchronized void loadThemes() {
053 if (_log.isInfoEnabled()) {
054 _log.info("Loading themes in " + _fileStorage);
055 }
056
057 File[] files = _fileStorage.listFiles();
058
059 if (files == null) {
060 if (_log.isWarnEnabled()) {
061 _log.warn(
062 "There are no directories to process for " + _fileStorage);
063 }
064
065 return;
066 }
067
068 for (int i = 0; i < files.length; i++) {
069 if (_log.isDebugEnabled()) {
070 _log.debug("Process directory " + files[i]);
071 }
072
073 File liferayLookAndFeelXML = new File(
074 files[i] + "/liferay-look-and-feel.xml");
075
076 if (liferayLookAndFeelXML.exists()) {
077 String lastModifiedKey = liferayLookAndFeelXML.toString();
078
079 Long prevLastModified = _lastModifiedMap.get(lastModifiedKey);
080
081 long lastModified = liferayLookAndFeelXML.lastModified();
082
083 if ((prevLastModified == null) ||
084 (prevLastModified.longValue() < lastModified)) {
085
086 registerTheme(liferayLookAndFeelXML);
087
088 _lastModifiedMap.put(lastModifiedKey, lastModified);
089 }
090 else {
091 if (_log.isDebugEnabled()) {
092 _log.debug(
093 "Do not refresh " + liferayLookAndFeelXML +
094 " because it is has not been modified");
095 }
096 }
097 }
098 else {
099 if (_log.isWarnEnabled()) {
100 _log.warn(liferayLookAndFeelXML + " does not exist");
101 }
102 }
103 }
104 }
105
106 protected ThemeLoader(
107 String servletContextName, ServletContext servletContext,
108 String[] xmls) {
109
110 _servletContextName = servletContextName;
111 _servletContext = servletContext;
112
113 boolean loadFromServletContext = true;
114 File fileStorage = null;
115 String themesPath = null;
116
117 try {
118 Document doc = UnsecureSAXReaderUtil.read(xmls[0], true);
119
120 Element root = doc.getRootElement();
121
122 themesPath = GetterUtil.getString(
123 root.elementText("themes-path"), "/themes");
124
125 String fileStorageValue = PropsValues.THEME_LOADER_STORAGE_PATH;
126
127 fileStorageValue = GetterUtil.getString(
128 root.elementText("file-storage"), fileStorageValue);
129
130 if (Validator.isNotNull(fileStorageValue)) {
131 fileStorage = new File(fileStorageValue);
132 loadFromServletContext = false;
133 }
134 else {
135 fileStorage = new File(servletContext.getRealPath(themesPath));
136 loadFromServletContext = true;
137 }
138
139 if (!fileStorage.exists()) {
140 if (_log.isWarnEnabled()) {
141 _log.warn(
142 "File storage " + fileStorage + " does not exist");
143 }
144
145 if (!fileStorage.mkdirs()) {
146 _log.error(
147 "Unable to create theme loader file storage at " +
148 fileStorage);
149 }
150 }
151 }
152 catch (Exception e) {
153 _log.error(e, e);
154 }
155
156 _loadFromServletContext = loadFromServletContext;
157 _fileStorage = fileStorage;
158 _themesPath = themesPath;
159
160 loadThemes();
161 }
162
163 protected void destroy() {
164 }
165
166 protected void registerTheme(File liferayLookAndFeelXML) {
167 if (_log.isDebugEnabled()) {
168 _log.debug("Registering " + liferayLookAndFeelXML);
169 }
170
171 try {
172 String content = FileUtil.read(liferayLookAndFeelXML);
173
174 ThemeLocalServiceUtil.init(
175 _servletContextName, _servletContext, _themesPath,
176 _loadFromServletContext, new String[] {content}, null);
177 }
178 catch (Exception e) {
179 _log.error(
180 "Error registering theme " + liferayLookAndFeelXML.toString(),
181 e);
182 }
183 }
184
185 private static final Log _log = LogFactoryUtil.getLog(ThemeLoader.class);
186
187 private final File _fileStorage;
188 private final Map<String, Long> _lastModifiedMap = new HashMap<>();
189 private final boolean _loadFromServletContext;
190 private final ServletContext _servletContext;
191 private final String _servletContextName;
192 private final String _themesPath;
193
194 }