001    /**
002     * Copyright (c) 2000-2013 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.service.impl;
016    
017    import com.liferay.portal.kernel.exception.SystemException;
018    import com.liferay.portal.kernel.io.DummyWriter;
019    import com.liferay.portal.kernel.log.Log;
020    import com.liferay.portal.kernel.log.LogFactoryUtil;
021    import com.liferay.portal.kernel.plugin.PluginPackage;
022    import com.liferay.portal.kernel.template.StringTemplateResource;
023    import com.liferay.portal.kernel.template.Template;
024    import com.liferay.portal.kernel.template.TemplateConstants;
025    import com.liferay.portal.kernel.template.TemplateManagerUtil;
026    import com.liferay.portal.kernel.template.TemplateResourceLoaderUtil;
027    import com.liferay.portal.kernel.util.GetterUtil;
028    import com.liferay.portal.kernel.util.HttpUtil;
029    import com.liferay.portal.kernel.util.ListUtil;
030    import com.liferay.portal.kernel.util.StringBundler;
031    import com.liferay.portal.kernel.util.StringPool;
032    import com.liferay.portal.kernel.util.UniqueList;
033    import com.liferay.portal.kernel.util.Validator;
034    import com.liferay.portal.kernel.xml.Document;
035    import com.liferay.portal.kernel.xml.Element;
036    import com.liferay.portal.kernel.xml.UnsecureSAXReaderUtil;
037    import com.liferay.portal.layoutconfiguration.util.velocity.InitColumnProcessor;
038    import com.liferay.portal.model.LayoutTemplate;
039    import com.liferay.portal.model.LayoutTemplateConstants;
040    import com.liferay.portal.model.PluginSetting;
041    import com.liferay.portal.model.impl.LayoutTemplateImpl;
042    import com.liferay.portal.service.base.LayoutTemplateLocalServiceBaseImpl;
043    import com.liferay.portal.util.PropsValues;
044    
045    import java.io.IOException;
046    
047    import java.util.ArrayList;
048    import java.util.HashSet;
049    import java.util.LinkedHashMap;
050    import java.util.List;
051    import java.util.Map;
052    import java.util.Set;
053    
054    import javax.servlet.ServletContext;
055    
056    /**
057     * @author Ivica Cardic
058     * @author Jorge Ferrer
059     * @author Brian Wing Shun Chan
060     * @author Raymond Aug??
061     */
062    public class LayoutTemplateLocalServiceImpl
063            extends LayoutTemplateLocalServiceBaseImpl {
064    
065            @Override
066            public String getContent(
067                            String layoutTemplateId, boolean standard, String themeId)
068                    throws SystemException {
069    
070                    LayoutTemplate layoutTemplate = getLayoutTemplate(
071                            layoutTemplateId, standard, themeId);
072    
073                    if (layoutTemplate == null) {
074                            if (_log.isWarnEnabled()) {
075                                    _log.warn(
076                                            "Layout template " + layoutTemplateId + " does not exist");
077                            }
078    
079                            layoutTemplate = getLayoutTemplate(
080                                    PropsValues.DEFAULT_LAYOUT_TEMPLATE_ID, standard, themeId);
081    
082                            if (layoutTemplate == null) {
083                                    _log.error(
084                                            "Layout template " + layoutTemplateId +
085                                                    " and default layout template " +
086                                                            PropsValues.DEFAULT_LAYOUT_TEMPLATE_ID +
087                                                                    " do not exist");
088    
089                                    return StringPool.BLANK;
090                            }
091                    }
092    
093                    if (PropsValues.LAYOUT_TEMPLATE_CACHE_ENABLED) {
094                            return layoutTemplate.getContent();
095                    }
096    
097                    try {
098                            return layoutTemplate.getUncachedContent();
099                    }
100                    catch (IOException ioe) {
101                            throw new SystemException(ioe);
102                    }
103            }
104    
105            @Override
106            public LayoutTemplate getLayoutTemplate(
107                    String layoutTemplateId, boolean standard, String themeId) {
108    
109                    if (Validator.isNull(layoutTemplateId)) {
110                            return null;
111                    }
112    
113                    LayoutTemplate layoutTemplate = null;
114    
115                    if (themeId != null) {
116                            if (standard) {
117                                    layoutTemplate = _getThemesStandard(themeId).get(
118                                            layoutTemplateId);
119                            }
120                            else {
121                                    layoutTemplate = _getThemesCustom(themeId).get(
122                                            layoutTemplateId);
123                            }
124    
125                            if (layoutTemplate != null) {
126                                    return layoutTemplate;
127                            }
128                    }
129    
130                    if (standard) {
131                            layoutTemplate = _warStandard.get(layoutTemplateId);
132    
133                            if (layoutTemplate == null) {
134                                    layoutTemplate = _portalStandard.get(layoutTemplateId);
135                            }
136                    }
137                    else {
138                            layoutTemplate = _warCustom.get(layoutTemplateId);
139    
140                            if (layoutTemplate == null) {
141                                    layoutTemplate = _portalCustom.get(layoutTemplateId);
142                            }
143                    }
144    
145                    return layoutTemplate;
146            }
147    
148            @Override
149            public List<LayoutTemplate> getLayoutTemplates() {
150                    List<LayoutTemplate> customLayoutTemplates =
151                            new ArrayList<LayoutTemplate>(
152                                    _portalCustom.size() + _warCustom.size());
153    
154                    customLayoutTemplates.addAll(ListUtil.fromMapValues(_portalCustom));
155                    customLayoutTemplates.addAll(ListUtil.fromMapValues(_warCustom));
156    
157                    return customLayoutTemplates;
158            }
159    
160            @Override
161            public List<LayoutTemplate> getLayoutTemplates(String themeId) {
162                    Map<String, LayoutTemplate> _themesCustom = _getThemesCustom(themeId);
163    
164                    List<LayoutTemplate> customLayoutTemplates =
165                            new ArrayList<LayoutTemplate>(
166                                    _portalCustom.size() + _warCustom.size() +
167                                            _themesCustom.size());
168    
169                    for (Map.Entry<String, LayoutTemplate> entry :
170                                    _portalCustom.entrySet()) {
171    
172                            String layoutTemplateId = entry.getKey();
173                            LayoutTemplate layoutTemplate = entry.getValue();
174    
175                            LayoutTemplate themeCustomLayoutTemplate = _themesCustom.get(
176                                    layoutTemplateId);
177    
178                            if (themeCustomLayoutTemplate != null) {
179                                    customLayoutTemplates.add(themeCustomLayoutTemplate);
180                            }
181                            else {
182                                    LayoutTemplate warCustomLayoutTemplate = _warCustom.get(
183                                            layoutTemplateId);
184    
185                                    if (warCustomLayoutTemplate != null) {
186                                            customLayoutTemplates.add(warCustomLayoutTemplate);
187                                    }
188                                    else {
189                                            customLayoutTemplates.add(layoutTemplate);
190                                    }
191                            }
192                    }
193    
194                    for (Map.Entry<String, LayoutTemplate> entry : _warCustom.entrySet()) {
195                            String layoutTemplateId = entry.getKey();
196    
197                            if (!_portalCustom.containsKey(layoutTemplateId) &&
198                                    !_themesCustom.containsKey(layoutTemplateId)) {
199    
200                                    customLayoutTemplates.add(_warCustom.get(layoutTemplateId));
201                            }
202                    }
203    
204                    for (Map.Entry<String, LayoutTemplate> entry :
205                                    _themesCustom.entrySet()) {
206    
207                            String layoutTemplateId = entry.getKey();
208    
209                            if (!_portalCustom.containsKey(layoutTemplateId) &&
210                                    !_warCustom.containsKey(layoutTemplateId)) {
211    
212                                    customLayoutTemplates.add(_themesCustom.get(layoutTemplateId));
213                            }
214                    }
215    
216                    return customLayoutTemplates;
217            }
218    
219            @Override
220            public String getWapContent(
221                            String layoutTemplateId, boolean standard, String themeId)
222                    throws SystemException {
223    
224                    LayoutTemplate layoutTemplate = getLayoutTemplate(
225                            layoutTemplateId, standard, themeId);
226    
227                    if (layoutTemplate == null) {
228                            if (_log.isWarnEnabled()) {
229                                    _log.warn(
230                                            "Layout template " + layoutTemplateId + " does not exist");
231                            }
232    
233                            layoutTemplate = getLayoutTemplate(
234                                    PropsValues.DEFAULT_LAYOUT_TEMPLATE_ID, standard, themeId);
235    
236                            if (layoutTemplate == null) {
237                                    _log.error(
238                                            "Layout template " + layoutTemplateId +
239                                                    " and default layout template " +
240                                                            PropsValues.DEFAULT_LAYOUT_TEMPLATE_ID +
241                                                                    " do not exist");
242    
243                                    return StringPool.BLANK;
244                            }
245                    }
246    
247                    if (PropsValues.LAYOUT_TEMPLATE_CACHE_ENABLED) {
248                            return layoutTemplate.getWapContent();
249                    }
250    
251                    try {
252                            return layoutTemplate.getUncachedWapContent();
253                    }
254                    catch (IOException ioe) {
255                            throw new SystemException(ioe);
256                    }
257            }
258    
259            @Override
260            public List<LayoutTemplate> init(
261                    ServletContext servletContext, String[] xmls,
262                    PluginPackage pluginPackage) {
263    
264                    return init(null, servletContext, xmls, pluginPackage);
265            }
266    
267            @Override
268            public List<LayoutTemplate> init(
269                    String servletContextName, ServletContext servletContext, String[] xmls,
270                    PluginPackage pluginPackage) {
271    
272                    List<LayoutTemplate> layoutTemplates = new UniqueList<LayoutTemplate>();
273    
274                    try {
275                            for (String xml : xmls) {
276                                    layoutTemplates.addAll(
277                                            _readLayoutTemplates(
278                                                    servletContextName, servletContext, xml,
279                                                    pluginPackage));
280                            }
281                    }
282                    catch (Exception e) {
283                            _log.error(e, e);
284                    }
285    
286                    return layoutTemplates;
287            }
288    
289            @Override
290            public void readLayoutTemplate(
291                    String servletContextName, ServletContext servletContext,
292                    Set<LayoutTemplate> layoutTemplates, Element element, boolean standard,
293                    String themeId, PluginPackage pluginPackage) {
294    
295                    Map<String, LayoutTemplate> installedLayoutTemplates = null;
296    
297                    if (themeId != null) {
298                            if (standard) {
299                                    installedLayoutTemplates = _getThemesStandard(themeId);
300                            }
301                            else {
302                                    installedLayoutTemplates = _getThemesCustom(themeId);
303                            }
304                    }
305                    else if (servletContextName != null) {
306                            if (standard) {
307                                    installedLayoutTemplates = _warStandard;
308                            }
309                            else {
310                                    installedLayoutTemplates = _warCustom;
311                            }
312                    }
313                    else {
314                            if (standard) {
315                                    installedLayoutTemplates = _portalStandard;
316                            }
317                            else {
318                                    installedLayoutTemplates = _portalCustom;
319                            }
320                    }
321    
322                    List<Element> layoutTemplateElements = element.elements(
323                            "layout-template");
324    
325                    for (Element layoutTemplateElement : layoutTemplateElements) {
326                            String layoutTemplateId = layoutTemplateElement.attributeValue(
327                                    "id");
328    
329                            LayoutTemplate layoutTemplateModel = installedLayoutTemplates.get(
330                                    layoutTemplateId);
331    
332                            if (layoutTemplateModel == null) {
333                                    layoutTemplateModel = new LayoutTemplateImpl(layoutTemplateId);
334    
335                                    installedLayoutTemplates.put(
336                                            layoutTemplateId, layoutTemplateModel);
337                            }
338    
339                            PluginSetting pluginSetting =
340                                    pluginSettingLocalService.getDefaultPluginSetting();
341    
342                            layoutTemplateModel.setPluginPackage(pluginPackage);
343                            layoutTemplateModel.setServletContext(servletContext);
344    
345                            if (servletContextName != null) {
346                                    layoutTemplateModel.setServletContextName(servletContextName);
347                            }
348    
349                            layoutTemplateModel.setStandard(standard);
350                            layoutTemplateModel.setThemeId(themeId);
351    
352                            String templateName = GetterUtil.getString(
353                                    layoutTemplateElement.attributeValue("name"));
354    
355                            if (Validator.isNotNull(templateName)) {
356                                    layoutTemplateModel.setName(templateName);
357                            }
358    
359                            layoutTemplateModel.setTemplatePath(
360                                    GetterUtil.getString(
361                                            layoutTemplateElement.elementText("template-path"),
362                                            layoutTemplateModel.getTemplatePath()));
363                            layoutTemplateModel.setWapTemplatePath(
364                                    GetterUtil.getString(
365                                            layoutTemplateElement.elementText("wap-template-path"),
366                                            layoutTemplateModel.getWapTemplatePath()));
367                            layoutTemplateModel.setThumbnailPath(
368                                    GetterUtil.getString(
369                                            layoutTemplateElement.elementText("thumbnail-path"),
370                                            layoutTemplateModel.getThumbnailPath()));
371    
372                            String content = null;
373    
374                            try {
375                                    content = HttpUtil.URLtoString(
376                                            servletContext.getResource(
377                                                    layoutTemplateModel.getTemplatePath()));
378                            }
379                            catch (Exception e) {
380                                    _log.error(
381                                            "Unable to get content at template path " +
382                                                    layoutTemplateModel.getTemplatePath() + ": " +
383                                                            e.getMessage());
384                            }
385    
386                            if (Validator.isNull(content)) {
387                                    _log.error(
388                                            "No content found at template path " +
389                                                    layoutTemplateModel.getTemplatePath());
390                            }
391                            else {
392                                    StringBundler sb = new StringBundler(3);
393    
394                                    sb.append(themeId);
395    
396                                    if (standard) {
397                                            sb.append(LayoutTemplateConstants.STANDARD_SEPARATOR);
398                                    }
399                                    else {
400                                            sb.append(LayoutTemplateConstants.CUSTOM_SEPARATOR);
401                                    }
402    
403                                    sb.append(layoutTemplateId);
404    
405                                    String velocityTemplateId = sb.toString();
406    
407                                    layoutTemplateModel.setContent(content);
408                                    layoutTemplateModel.setColumns(
409                                            _getColumns(velocityTemplateId, content));
410                            }
411    
412                            if (Validator.isNull(layoutTemplateModel.getWapTemplatePath())) {
413                                    _log.error(
414                                            "The element wap-template-path is not defined for " +
415                                                    layoutTemplateId);
416                            }
417                            else {
418                                    String wapContent = null;
419    
420                                    try {
421                                            wapContent = HttpUtil.URLtoString(
422                                                    servletContext.getResource(
423                                                            layoutTemplateModel.getWapTemplatePath()));
424                                    }
425                                    catch (Exception e) {
426                                            _log.error(
427                                                    "Unable to get content at WAP template path " +
428                                                            layoutTemplateModel.getWapTemplatePath() + ": " +
429                                                                    e.getMessage());
430                                    }
431    
432                                    if (Validator.isNull(wapContent)) {
433                                            _log.error(
434                                                    "No content found at WAP template path " +
435                                                            layoutTemplateModel.getWapTemplatePath());
436                                    }
437                                    else {
438                                            layoutTemplateModel.setWapContent(wapContent);
439                                    }
440                            }
441    
442                            Element rolesElement = layoutTemplateElement.element("roles");
443    
444                            if (rolesElement != null) {
445                                    List<Element> roleNameElements = rolesElement.elements(
446                                            "role-name");
447    
448                                    for (Element roleNameElement : roleNameElements) {
449                                            pluginSetting.addRole(roleNameElement.getText());
450                                    }
451                            }
452    
453                            layoutTemplateModel.setDefaultPluginSetting(pluginSetting);
454    
455                            if (layoutTemplates != null) {
456                                    layoutTemplates.add(layoutTemplateModel);
457                            }
458                    }
459            }
460    
461            @Override
462            public void uninstallLayoutTemplate(
463                    String layoutTemplateId, boolean standard) {
464    
465                    String templateId = null;
466    
467                    try {
468                            if (standard) {
469                                    templateId =
470                                            "null" + LayoutTemplateConstants.STANDARD_SEPARATOR +
471                                                    layoutTemplateId;
472    
473                                    TemplateResourceLoaderUtil.clearCache(
474                                            TemplateConstants.LANG_TYPE_VM, templateId);
475    
476                                    _warStandard.remove(layoutTemplateId);
477                            }
478                            else {
479                                    templateId =
480                                            "null" + LayoutTemplateConstants.CUSTOM_SEPARATOR +
481                                                    layoutTemplateId;
482    
483                                    TemplateResourceLoaderUtil.clearCache(
484                                            TemplateConstants.LANG_TYPE_VM, templateId);
485    
486                                    _warCustom.remove(layoutTemplateId);
487                            }
488                    }
489                    catch (Exception e) {
490                            _log.error(
491                                    "Unable to uninstall layout template " + layoutTemplateId, e);
492                    }
493            }
494    
495            @Override
496            public void uninstallLayoutTemplates(String themeId) {
497                    Map<String, LayoutTemplate> _themesStandard = _getThemesStandard(
498                            themeId);
499    
500                    for (Map.Entry<String, LayoutTemplate> entry :
501                                    _themesStandard.entrySet()) {
502    
503                            LayoutTemplate layoutTemplate = entry.getValue();
504    
505                            String templateId =
506                                    themeId + LayoutTemplateConstants.STANDARD_SEPARATOR +
507                                            layoutTemplate.getLayoutTemplateId();
508    
509                            try {
510                                    TemplateResourceLoaderUtil.clearCache(
511                                            TemplateConstants.LANG_TYPE_VM, templateId);
512                            }
513                            catch (Exception e) {
514                                    _log.error(
515                                            "Unable to uninstall layout template " +
516                                                    layoutTemplate.getLayoutTemplateId(),
517                                            e);
518                            }
519                    }
520    
521                    _themesStandard.clear();
522    
523                    Map<String, LayoutTemplate> _themesCustom = _getThemesCustom(themeId);
524    
525                    for (Map.Entry<String, LayoutTemplate> entry :
526                                    _themesCustom.entrySet()) {
527    
528                            LayoutTemplate layoutTemplate = entry.getValue();
529    
530                            String templateId =
531                                    themeId + LayoutTemplateConstants.CUSTOM_SEPARATOR +
532                                            layoutTemplate.getLayoutTemplateId();
533    
534                            try {
535                                    TemplateResourceLoaderUtil.clearCache(
536                                            TemplateConstants.LANG_TYPE_VM, templateId);
537                            }
538                            catch (Exception e) {
539                                    _log.error(
540                                            "Unable to uninstall layout template " +
541                                                    layoutTemplate.getLayoutTemplateId(),
542                                            e);
543                            }
544                    }
545    
546                    _themesCustom.clear();
547            }
548    
549            private List<String> _getColumns(
550                    String velocityTemplateId, String velocityTemplateContent) {
551    
552                    try {
553                            InitColumnProcessor processor = new InitColumnProcessor();
554    
555                            Template template = TemplateManagerUtil.getTemplate(
556                                    TemplateConstants.LANG_TYPE_VM,
557                                    new StringTemplateResource(
558                                            velocityTemplateId, velocityTemplateContent),
559                                    false);
560    
561                            template.put("processor", processor);
562    
563                            template.processTemplate(new DummyWriter());
564    
565                            return ListUtil.sort(processor.getColumns());
566                    }
567                    catch (Exception e) {
568                            _log.error(e);
569    
570                            return new ArrayList<String>();
571                    }
572            }
573    
574            private Map<String, LayoutTemplate> _getThemesCustom(String themeId) {
575                    String key = themeId.concat(LayoutTemplateConstants.CUSTOM_SEPARATOR);
576    
577                    Map<String, LayoutTemplate> layoutTemplates = _themes.get(key);
578    
579                    if (layoutTemplates == null) {
580                            layoutTemplates = new LinkedHashMap<String, LayoutTemplate>();
581    
582                            _themes.put(key, layoutTemplates);
583                    }
584    
585                    return layoutTemplates;
586            }
587    
588            private Map<String, LayoutTemplate> _getThemesStandard(String themeId) {
589                    String key = themeId + LayoutTemplateConstants.STANDARD_SEPARATOR;
590    
591                    Map<String, LayoutTemplate> layoutTemplates = _themes.get(key);
592    
593                    if (layoutTemplates == null) {
594                            layoutTemplates = new LinkedHashMap<String, LayoutTemplate>();
595    
596                            _themes.put(key, layoutTemplates);
597                    }
598    
599                    return layoutTemplates;
600            }
601    
602            private Set<LayoutTemplate> _readLayoutTemplates(
603                            String servletContextName, ServletContext servletContext,
604                            String xml, PluginPackage pluginPackage)
605                    throws Exception {
606    
607                    Set<LayoutTemplate> layoutTemplates = new HashSet<LayoutTemplate>();
608    
609                    if (xml == null) {
610                            return layoutTemplates;
611                    }
612    
613                    Document document = UnsecureSAXReaderUtil.read(xml, true);
614    
615                    Element rootElement = document.getRootElement();
616    
617                    Element standardElement = rootElement.element("standard");
618    
619                    if (standardElement != null) {
620                            readLayoutTemplate(
621                                    servletContextName, servletContext, layoutTemplates,
622                                    standardElement, true, null, pluginPackage);
623                    }
624    
625                    Element customElement = rootElement.element("custom");
626    
627                    if (customElement != null) {
628                            readLayoutTemplate(
629                                    servletContextName, servletContext, layoutTemplates,
630                                    customElement, false, null, pluginPackage);
631                    }
632    
633                    return layoutTemplates;
634            }
635    
636            private static Log _log = LogFactoryUtil.getLog(
637                    LayoutTemplateLocalServiceImpl.class);
638    
639            private static Map<String, LayoutTemplate> _portalCustom =
640                    new LinkedHashMap<String, LayoutTemplate>();
641            private static Map<String, LayoutTemplate> _portalStandard =
642                    new LinkedHashMap<String, LayoutTemplate>();
643            private static Map<String, Map<String, LayoutTemplate>> _themes =
644                    new LinkedHashMap<String, Map<String, LayoutTemplate>>();
645            private static Map<String, LayoutTemplate> _warCustom =
646                    new LinkedHashMap<String, LayoutTemplate>();
647            private static Map<String, LayoutTemplate> _warStandard =
648                    new LinkedHashMap<String, LayoutTemplate>();
649    
650    }