1
22
23 package com.liferay.portal.service.impl;
24
25 import com.liferay.portal.SystemException;
26 import com.liferay.portal.kernel.plugin.PluginPackage;
27 import com.liferay.portal.kernel.util.GetterUtil;
28 import com.liferay.portal.kernel.util.HttpUtil;
29 import com.liferay.portal.kernel.util.ObjectValuePair;
30 import com.liferay.portal.kernel.util.StringPool;
31 import com.liferay.portal.kernel.util.Validator;
32 import com.liferay.portal.model.LayoutTemplate;
33 import com.liferay.portal.model.PluginSetting;
34 import com.liferay.portal.model.impl.LayoutTemplateImpl;
35 import com.liferay.portal.service.PluginSettingLocalServiceUtil;
36 import com.liferay.portal.util.DocumentUtil;
37 import com.liferay.portal.util.PropsUtil;
38 import com.liferay.portal.util.PropsValues;
39 import com.liferay.portlet.layoutconfiguration.util.velocity.InitColumnProcessor;
40 import com.liferay.util.ListUtil;
41
42 import java.io.IOException;
43 import java.io.PrintWriter;
44 import java.io.StringWriter;
45
46 import java.util.ArrayList;
47 import java.util.Collections;
48 import java.util.HashSet;
49 import java.util.Iterator;
50 import java.util.LinkedHashMap;
51 import java.util.List;
52 import java.util.Map;
53 import java.util.Set;
54
55 import javax.servlet.ServletContext;
56
57 import org.apache.commons.logging.Log;
58 import org.apache.commons.logging.LogFactory;
59 import org.apache.velocity.VelocityContext;
60 import org.apache.velocity.app.Velocity;
61
62 import org.dom4j.Document;
63 import org.dom4j.DocumentException;
64 import org.dom4j.Element;
65
66
73 public class LayoutTemplateLocalUtil {
74
75 public static String getContent(
76 String layoutTemplateId, boolean standard, String themeId)
77 throws SystemException {
78
79 LayoutTemplate layoutTemplate = getLayoutTemplate(
80 layoutTemplateId, standard, themeId);
81
82 if (layoutTemplate == null) {
83 if (_log.isWarnEnabled()) {
84 _log.warn(
85 "Layout template " + layoutTemplateId + " does not exist");
86 }
87
88 layoutTemplate = getLayoutTemplate(
89 PropsValues.DEFAULT_USER_LAYOUT_TEMPLATE_ID, standard, themeId);
90
91 if (layoutTemplate == null) {
92 _log.error(
93 "Layout template " + layoutTemplateId +
94 " and default user layout template " +
95 PropsValues.DEFAULT_USER_LAYOUT_TEMPLATE_ID +
96 " does not exist");
97
98 return StringPool.BLANK;
99 }
100 }
101
102 if (PropsValues.LAYOUT_TEMPLATE_CACHE_ENABLED) {
103 return layoutTemplate.getContent();
104 }
105 else {
106 try {
107 return layoutTemplate.getUncachedContent();
108 }
109 catch (IOException ioe) {
110 throw new SystemException(ioe);
111 }
112 }
113 }
114
115 public static LayoutTemplate getLayoutTemplate(
116 String layoutTemplateId, boolean standard, String themeId) {
117
118 if (Validator.isNull(layoutTemplateId)) {
119 return null;
120 }
121
122 LayoutTemplate layoutTemplate = null;
123
124 if (themeId != null) {
125 if (standard) {
126 layoutTemplate = _getThemesStandard(themeId).get(
127 layoutTemplateId);
128 }
129 else {
130 layoutTemplate = _getThemesCustom(themeId).get(
131 layoutTemplateId);
132 }
133
134 if (layoutTemplate != null) {
135 return layoutTemplate;
136 }
137 }
138
139 if (standard) {
140 layoutTemplate = _warStandard.get(layoutTemplateId);
141
142 if (layoutTemplate == null) {
143 layoutTemplate = _portalStandard.get(layoutTemplateId);
144 }
145 }
146 else {
147 layoutTemplate = _warCustom.get(layoutTemplateId);
148
149 if (layoutTemplate == null) {
150 layoutTemplate = _portalCustom.get(layoutTemplateId);
151 }
152 }
153
154 return layoutTemplate;
155 }
156
157 public static List<LayoutTemplate> getLayoutTemplates() {
158 List<LayoutTemplate> customLayoutTemplates =
159 new ArrayList<LayoutTemplate>(
160 _portalCustom.size() + _warCustom.size());
161
162 customLayoutTemplates.addAll(
163 ListUtil.fromCollection(_portalCustom.values()));
164
165 customLayoutTemplates.addAll(
166 ListUtil.fromCollection(_warCustom.values()));
167
168 return customLayoutTemplates;
169 }
170
171 public static List<LayoutTemplate> getLayoutTemplates(String themeId) {
172 Map<String, LayoutTemplate> _themesCustom = _getThemesCustom(themeId);
173
174 List<LayoutTemplate> customLayoutTemplates =
175 new ArrayList<LayoutTemplate>(
176 _portalCustom.size() + _warCustom.size() +
177 _themesCustom.size());
178
179 Iterator<Map.Entry<String, LayoutTemplate>> itr =
180 _portalCustom.entrySet().iterator();
181
182 while (itr.hasNext()) {
183 Map.Entry<String, LayoutTemplate> entry = itr.next();
184
185 String layoutTemplateId = entry.getKey();
186 LayoutTemplate layoutTemplate = entry.getValue();
187
188 if (_themesCustom.containsKey(layoutTemplateId)) {
189 customLayoutTemplates.add(_themesCustom.get(layoutTemplateId));
190 }
191 else if (_warCustom.containsKey(layoutTemplateId)) {
192 customLayoutTemplates.add(_warCustom.get(layoutTemplateId));
193 }
194 else {
195 customLayoutTemplates.add(layoutTemplate);
196 }
197 }
198
199 itr = _warCustom.entrySet().iterator();
200
201 while (itr.hasNext()) {
202 Map.Entry<String, LayoutTemplate> entry = itr.next();
203
204 String layoutTemplateId = entry.getKey();
205
206 if (!_portalCustom.containsKey(layoutTemplateId) &&
207 !_themesCustom.containsKey(layoutTemplateId)) {
208
209 customLayoutTemplates.add(_warCustom.get(layoutTemplateId));
210 }
211 }
212
213 itr = _themesCustom.entrySet().iterator();
214
215 while (itr.hasNext()) {
216 Map.Entry<String, LayoutTemplate> entry = itr.next();
217
218 String layoutTemplateId = entry.getKey();
219
220 if (!_portalCustom.containsKey(layoutTemplateId) &&
221 !_warCustom.containsKey(layoutTemplateId)) {
222
223 customLayoutTemplates.add(_themesCustom.get(layoutTemplateId));
224 }
225 }
226
227 return customLayoutTemplates;
228 }
229
230 public static String getWapContent(
231 String layoutTemplateId, boolean standard, String themeId)
232 throws SystemException {
233
234 LayoutTemplate layoutTemplate = getLayoutTemplate(
235 layoutTemplateId, standard, themeId);
236
237 if (layoutTemplate == null) {
238 if (_log.isWarnEnabled()) {
239 _log.warn(
240 "Layout template " + layoutTemplateId + " does not exist");
241 }
242
243 layoutTemplate = getLayoutTemplate(
244 PropsValues.DEFAULT_USER_LAYOUT_TEMPLATE_ID, standard, themeId);
245
246 if (layoutTemplate == null) {
247 _log.error(
248 "Layout template " + layoutTemplateId +
249 " and default user layout template " +
250 PropsValues.DEFAULT_USER_LAYOUT_TEMPLATE_ID +
251 " does not exist");
252
253 return StringPool.BLANK;
254 }
255 }
256
257 if (GetterUtil.getBoolean(PropsUtil.get(
258 PropsUtil.LAYOUT_TEMPLATE_CACHE_ENABLED))) {
259
260 return layoutTemplate.getWapContent();
261 }
262 else {
263 try {
264 return layoutTemplate.getUncachedWapContent();
265 }
266 catch (IOException ioe) {
267 throw new SystemException(ioe);
268 }
269 }
270 }
271
272 public static List<ObjectValuePair<String, Boolean>> init(
273 ServletContext ctx, String[] xmls, PluginPackage pluginPackage) {
274
275 return init(null, ctx, xmls, pluginPackage);
276 }
277
278 public static List<ObjectValuePair<String, Boolean>> init(
279 String servletContextName, ServletContext ctx, String[] xmls,
280 PluginPackage pluginPackage) {
281
282 List<ObjectValuePair<String, Boolean>> layoutTemplateIds =
283 new ArrayList<ObjectValuePair<String, Boolean>>();
284
285 try {
286 for (int i = 0; i < xmls.length; i++) {
287 Set<ObjectValuePair<String, Boolean>> curLayoutTemplateIds =
288 _readLayoutTemplates(
289 servletContextName, ctx, xmls[i], pluginPackage);
290
291 Iterator<ObjectValuePair<String, Boolean>> itr =
292 curLayoutTemplateIds.iterator();
293
294 while (itr.hasNext()) {
295 ObjectValuePair<String, Boolean> ovp = itr.next();
296
297 if (!layoutTemplateIds.contains(ovp)) {
298 layoutTemplateIds.add(ovp);
299 }
300 }
301 }
302 }
303 catch (Exception e) {
304 e.printStackTrace();
305 }
306
307 return layoutTemplateIds;
308 }
309
310 public static void readLayoutTemplate(
311 String servletContextName, ServletContext ctx,
312 Set<ObjectValuePair<String, Boolean>> layoutTemplateIds, Element el,
313 boolean standard, String themeId, PluginPackage pluginPackage)
314 throws IOException {
315
316 Map<String, LayoutTemplate> layoutTemplates = null;
317
318 if (themeId != null) {
319 if (standard) {
320 layoutTemplates = _getThemesStandard(themeId);
321 }
322 else {
323 layoutTemplates = _getThemesCustom(themeId);
324 }
325 }
326 else if (servletContextName != null) {
327 if (standard) {
328 layoutTemplates = _warStandard;
329 }
330 else {
331 layoutTemplates = _warCustom;
332 }
333 }
334 else {
335 if (standard) {
336 layoutTemplates = _portalStandard;
337 }
338 else {
339 layoutTemplates = _portalCustom;
340 }
341 }
342
343 Iterator<Element> itr = el.elements("layout-template").iterator();
344
345 while (itr.hasNext()) {
346 Element layoutTemplate = itr.next();
347
348 String layoutTemplateId = layoutTemplate.attributeValue("id");
349
350 if (layoutTemplateIds != null) {
351 ObjectValuePair<String, Boolean> ovp =
352 new ObjectValuePair<String, Boolean>(
353 layoutTemplateId, standard);
354
355 layoutTemplateIds.add(ovp);
356 }
357
358 LayoutTemplate layoutTemplateModel = layoutTemplates.get(
359 layoutTemplateId);
360
361 if (layoutTemplateModel == null) {
362 layoutTemplateModel = new LayoutTemplateImpl(layoutTemplateId);
363
364 layoutTemplates.put(layoutTemplateId, layoutTemplateModel);
365 }
366
367 PluginSetting pluginSetting =
368 PluginSettingLocalServiceUtil.getDefaultPluginSetting();
369
370 layoutTemplateModel.setPluginPackage(pluginPackage);
371 layoutTemplateModel.setServletContext(ctx);
372
373 if (servletContextName != null) {
374 layoutTemplateModel.setServletContextName(servletContextName);
375 }
376
377 layoutTemplateModel.setStandard(standard);
378 layoutTemplateModel.setName(GetterUtil.getString(
379 layoutTemplate.attributeValue("name"),
380 layoutTemplateModel.getName()));
381 layoutTemplateModel.setTemplatePath(GetterUtil.getString(
382 layoutTemplate.elementText("template-path"),
383 layoutTemplateModel.getTemplatePath()));
384 layoutTemplateModel.setWapTemplatePath(GetterUtil.getString(
385 layoutTemplate.elementText("wap-template-path"),
386 layoutTemplateModel.getWapTemplatePath()));
387 layoutTemplateModel.setThumbnailPath(GetterUtil.getString(
388 layoutTemplate.elementText("thumbnail-path"),
389 layoutTemplateModel.getThumbnailPath()));
390
391 String content = null;
392
393 try {
394 content = HttpUtil.URLtoString(ctx.getResource(
395 layoutTemplateModel.getTemplatePath()));
396 }
397 catch (Exception e) {
398 _log.error(
399 "Unable to get content at template path " +
400 layoutTemplateModel.getTemplatePath() + ": " +
401 e.getMessage());
402 }
403
404 if (Validator.isNull(content)) {
405 _log.error(
406 "No content found at template path " +
407 layoutTemplateModel.getTemplatePath());
408 }
409 else {
410 layoutTemplateModel.setContent(content);
411 layoutTemplateModel.setColumns(_getColumns(content));
412 }
413
414 if (Validator.isNull(layoutTemplateModel.getWapTemplatePath())) {
415 _log.error(
416 "The element wap-template-path is not defined for " +
417 layoutTemplateId);
418 }
419 else {
420 String wapContent = null;
421
422 try {
423 wapContent = HttpUtil.URLtoString(ctx.getResource(
424 layoutTemplateModel.getWapTemplatePath()));
425 }
426 catch (Exception e) {
427 _log.error(
428 "Unable to get content at WAP template path " +
429 layoutTemplateModel.getWapTemplatePath() + ": " +
430 e.getMessage());
431 }
432
433 if (Validator.isNull(wapContent)) {
434 _log.error(
435 "No content found at WAP template path " +
436 layoutTemplateModel.getWapTemplatePath());
437 }
438 else {
439 layoutTemplateModel.setWapContent(wapContent);
440 }
441 }
442
443 Element rolesEl = layoutTemplate.element("roles");
444
445 if (rolesEl != null) {
446 Iterator<Element> itr2 = rolesEl.elements(
447 "role-name").iterator();
448
449 while (itr2.hasNext()) {
450 Element roleNameEl = itr2.next();
451
452 pluginSetting.addRole(roleNameEl.getText());
453 }
454 }
455
456 layoutTemplateModel.setDefaultPluginSetting(pluginSetting);
457 }
458 }
459
460 public static void uninstallLayoutTemplate(
461 String layoutTemplateId, boolean standard) {
462
463 if (standard) {
464 _warStandard.remove(layoutTemplateId);
465 }
466 else {
467 _warCustom.remove(layoutTemplateId);
468 }
469 }
470
471 public static void uninstallLayoutTemplates(String themeId) {
472 _getThemesStandard(themeId).clear();
473 _getThemesCustom(themeId).clear();
474 }
475
476 private static List<String> _getColumns(String content) {
477 try {
478 InitColumnProcessor processor = new InitColumnProcessor();
479
480 VelocityContext context = new VelocityContext();
481
482 context.put("processor", processor);
483
484 Velocity.evaluate(
485 context, new PrintWriter(new StringWriter()),
486 LayoutTemplateLocalUtil.class.getName(), content);
487
488 List<String> columns = processor.getColumns();
489
490 Collections.sort(columns);
491
492 return columns;
493 }
494 catch (Exception e) {
495 _log.error(e);
496
497 return new ArrayList<String>();
498 }
499 }
500
501 private static Set<ObjectValuePair<String, Boolean>> _readLayoutTemplates(
502 String servletContextName, ServletContext ctx, String xml,
503 PluginPackage pluginPackage)
504 throws DocumentException, IOException {
505
506 Set<ObjectValuePair<String, Boolean>> layoutTemplateIds =
507 new HashSet<ObjectValuePair<String, Boolean>>();
508
509 if (xml == null) {
510 return layoutTemplateIds;
511 }
512
513 Document doc = DocumentUtil.readDocumentFromXML(xml, true);
514
515 Element root = doc.getRootElement();
516
517 Element standardEl = root.element("standard");
518
519 if (standardEl != null) {
520 readLayoutTemplate(
521 servletContextName, ctx, layoutTemplateIds, standardEl, true,
522 null, pluginPackage);
523 }
524
525 Element customEl = root.element("custom");
526
527 if (customEl != null) {
528 readLayoutTemplate(
529 servletContextName, ctx, layoutTemplateIds, customEl, false,
530 null, pluginPackage);
531 }
532
533 return layoutTemplateIds;
534 }
535
536 private static Map<String, LayoutTemplate> _getThemesCustom(
537 String themeId) {
538
539 String key = themeId + _CUSTOM_SEPARATOR;
540
541 Map<String, LayoutTemplate> layoutTemplates = _themes.get(key);
542
543 if (layoutTemplates == null) {
544 layoutTemplates = new LinkedHashMap<String, LayoutTemplate>();
545
546 _themes.put(key, layoutTemplates);
547 }
548
549 return layoutTemplates;
550 }
551
552 private static Map<String, LayoutTemplate> _getThemesStandard(
553 String themeId) {
554
555 String key = themeId + _STANDARD_SEPARATOR;
556
557 Map<String, LayoutTemplate> layoutTemplates = _themes.get(key);
558
559 if (layoutTemplates == null) {
560 layoutTemplates = new LinkedHashMap<String, LayoutTemplate>();
561
562 _themes.put(key, layoutTemplates);
563 }
564
565 return layoutTemplates;
566 }
567
568 private static final String _STANDARD_SEPARATOR = "_STANDARD_";
569
570 private static final String _CUSTOM_SEPARATOR = "_CUSTOM_";
571
572 private static Log _log = LogFactory.getLog(LayoutTemplateLocalUtil.class);
573
574 private static Map<String, LayoutTemplate> _portalStandard =
575 new LinkedHashMap<String, LayoutTemplate>();
576 private static Map<String, LayoutTemplate> _portalCustom =
577 new LinkedHashMap<String, LayoutTemplate>();
578
579 private static Map<String, LayoutTemplate> _warStandard =
580 new LinkedHashMap<String, LayoutTemplate>();
581 private static Map<String, LayoutTemplate> _warCustom =
582 new LinkedHashMap<String, LayoutTemplate>();
583
584 private static Map<String, Map<String, LayoutTemplate>> _themes =
585 new LinkedHashMap<String, Map<String, LayoutTemplate>>();
586
587 }