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.SAXReaderUtil;
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                    else {
097                            try {
098                                    return layoutTemplate.getUncachedContent();
099                            }
100                            catch (IOException ioe) {
101                                    throw new SystemException(ioe);
102                            }
103                    }
104            }
105    
106            @Override
107            public LayoutTemplate getLayoutTemplate(
108                    String layoutTemplateId, boolean standard, String themeId) {
109    
110                    if (Validator.isNull(layoutTemplateId)) {
111                            return null;
112                    }
113    
114                    LayoutTemplate layoutTemplate = null;
115    
116                    if (themeId != null) {
117                            if (standard) {
118                                    layoutTemplate = _getThemesStandard(themeId).get(
119                                            layoutTemplateId);
120                            }
121                            else {
122                                    layoutTemplate = _getThemesCustom(themeId).get(
123                                            layoutTemplateId);
124                            }
125    
126                            if (layoutTemplate != null) {
127                                    return layoutTemplate;
128                            }
129                    }
130    
131                    if (standard) {
132                            layoutTemplate = _warStandard.get(layoutTemplateId);
133    
134                            if (layoutTemplate == null) {
135                                    layoutTemplate = _portalStandard.get(layoutTemplateId);
136                            }
137                    }
138                    else {
139                            layoutTemplate = _warCustom.get(layoutTemplateId);
140    
141                            if (layoutTemplate == null) {
142                                    layoutTemplate = _portalCustom.get(layoutTemplateId);
143                            }
144                    }
145    
146                    return layoutTemplate;
147            }
148    
149            @Override
150            public List<LayoutTemplate> getLayoutTemplates() {
151                    List<LayoutTemplate> customLayoutTemplates =
152                            new ArrayList<LayoutTemplate>(
153                                    _portalCustom.size() + _warCustom.size());
154    
155                    customLayoutTemplates.addAll(ListUtil.fromMapValues(_portalCustom));
156                    customLayoutTemplates.addAll(ListUtil.fromMapValues(_warCustom));
157    
158                    return customLayoutTemplates;
159            }
160    
161            @Override
162            public List<LayoutTemplate> getLayoutTemplates(String themeId) {
163                    Map<String, LayoutTemplate> _themesCustom = _getThemesCustom(themeId);
164    
165                    List<LayoutTemplate> customLayoutTemplates =
166                            new ArrayList<LayoutTemplate>(
167                                    _portalCustom.size() + _warCustom.size() +
168                                            _themesCustom.size());
169    
170                    for (Map.Entry<String, LayoutTemplate> entry :
171                                    _portalCustom.entrySet()) {
172    
173                            String layoutTemplateId = entry.getKey();
174                            LayoutTemplate layoutTemplate = entry.getValue();
175    
176                            LayoutTemplate themeCustomLayoutTemplate = _themesCustom.get(
177                                    layoutTemplateId);
178    
179                            if (themeCustomLayoutTemplate != null) {
180                                    customLayoutTemplates.add(themeCustomLayoutTemplate);
181                            }
182                            else {
183                                    LayoutTemplate warCustomLayoutTemplate = _warCustom.get(
184                                            layoutTemplateId);
185    
186                                    if (warCustomLayoutTemplate != null) {
187                                            customLayoutTemplates.add(warCustomLayoutTemplate);
188                                    }
189                                    else {
190                                            customLayoutTemplates.add(layoutTemplate);
191                                    }
192                            }
193                    }
194    
195                    for (Map.Entry<String, LayoutTemplate> entry : _warCustom.entrySet()) {
196                            String layoutTemplateId = entry.getKey();
197    
198                            if (!_portalCustom.containsKey(layoutTemplateId) &&
199                                    !_themesCustom.containsKey(layoutTemplateId)) {
200    
201                                    customLayoutTemplates.add(_warCustom.get(layoutTemplateId));
202                            }
203                    }
204    
205                    for (Map.Entry<String, LayoutTemplate> entry :
206                                    _themesCustom.entrySet()) {
207    
208                            String layoutTemplateId = entry.getKey();
209    
210                            if (!_portalCustom.containsKey(layoutTemplateId) &&
211                                    !_warCustom.containsKey(layoutTemplateId)) {
212    
213                                    customLayoutTemplates.add(_themesCustom.get(layoutTemplateId));
214                            }
215                    }
216    
217                    return customLayoutTemplates;
218            }
219    
220            @Override
221            public String getWapContent(
222                            String layoutTemplateId, boolean standard, String themeId)
223                    throws SystemException {
224    
225                    LayoutTemplate layoutTemplate = getLayoutTemplate(
226                            layoutTemplateId, standard, themeId);
227    
228                    if (layoutTemplate == null) {
229                            if (_log.isWarnEnabled()) {
230                                    _log.warn(
231                                            "Layout template " + layoutTemplateId + " does not exist");
232                            }
233    
234                            layoutTemplate = getLayoutTemplate(
235                                    PropsValues.DEFAULT_LAYOUT_TEMPLATE_ID, standard, themeId);
236    
237                            if (layoutTemplate == null) {
238                                    _log.error(
239                                            "Layout template " + layoutTemplateId +
240                                                    " and default layout template " +
241                                                            PropsValues.DEFAULT_LAYOUT_TEMPLATE_ID +
242                                                                    " do not exist");
243    
244                                    return StringPool.BLANK;
245                            }
246                    }
247    
248                    if (PropsValues.LAYOUT_TEMPLATE_CACHE_ENABLED) {
249                            return layoutTemplate.getWapContent();
250                    }
251                    else {
252                            try {
253                                    return layoutTemplate.getUncachedWapContent();
254                            }
255                            catch (IOException ioe) {
256                                    throw new SystemException(ioe);
257                            }
258                    }
259            }
260    
261            @Override
262            public List<LayoutTemplate> init(
263                    ServletContext servletContext, String[] xmls,
264                    PluginPackage pluginPackage) {
265    
266                    return init(null, servletContext, xmls, pluginPackage);
267            }
268    
269            @Override
270            public List<LayoutTemplate> init(
271                    String servletContextName, ServletContext servletContext, String[] xmls,
272                    PluginPackage pluginPackage) {
273    
274                    List<LayoutTemplate> layoutTemplates = new UniqueList<LayoutTemplate>();
275    
276                    try {
277                            for (String xml : xmls) {
278                                    layoutTemplates.addAll(
279                                            _readLayoutTemplates(
280                                                    servletContextName, servletContext, xml,
281                                                    pluginPackage));
282                            }
283                    }
284                    catch (Exception e) {
285                            _log.error(e, e);
286                    }
287    
288                    return layoutTemplates;
289            }
290    
291            @Override
292            public void readLayoutTemplate(
293                    String servletContextName, ServletContext servletContext,
294                    Set<LayoutTemplate> layoutTemplates, Element element, boolean standard,
295                    String themeId, PluginPackage pluginPackage) {
296    
297                    Map<String, LayoutTemplate> installedLayoutTemplates = null;
298    
299                    if (themeId != null) {
300                            if (standard) {
301                                    installedLayoutTemplates = _getThemesStandard(themeId);
302                            }
303                            else {
304                                    installedLayoutTemplates = _getThemesCustom(themeId);
305                            }
306                    }
307                    else if (servletContextName != null) {
308                            if (standard) {
309                                    installedLayoutTemplates = _warStandard;
310                            }
311                            else {
312                                    installedLayoutTemplates = _warCustom;
313                            }
314                    }
315                    else {
316                            if (standard) {
317                                    installedLayoutTemplates = _portalStandard;
318                            }
319                            else {
320                                    installedLayoutTemplates = _portalCustom;
321                            }
322                    }
323    
324                    List<Element> layoutTemplateElements = element.elements(
325                            "layout-template");
326    
327                    for (Element layoutTemplateElement : layoutTemplateElements) {
328                            String layoutTemplateId = layoutTemplateElement.attributeValue(
329                                    "id");
330    
331                            LayoutTemplate layoutTemplateModel = installedLayoutTemplates.get(
332                                    layoutTemplateId);
333    
334                            if (layoutTemplateModel == null) {
335                                    layoutTemplateModel = new LayoutTemplateImpl(layoutTemplateId);
336    
337                                    installedLayoutTemplates.put(
338                                            layoutTemplateId, layoutTemplateModel);
339                            }
340    
341                            PluginSetting pluginSetting =
342                                    pluginSettingLocalService.getDefaultPluginSetting();
343    
344                            layoutTemplateModel.setPluginPackage(pluginPackage);
345                            layoutTemplateModel.setServletContext(servletContext);
346    
347                            if (servletContextName != null) {
348                                    layoutTemplateModel.setServletContextName(servletContextName);
349                            }
350    
351                            layoutTemplateModel.setStandard(standard);
352                            layoutTemplateModel.setThemeId(themeId);
353                            layoutTemplateModel.setName(
354                                    GetterUtil.getString(
355                                            layoutTemplateElement.attributeValue("name"),
356                                            layoutTemplateModel.getName()));
357                            layoutTemplateModel.setTemplatePath(
358                                    GetterUtil.getString(
359                                            layoutTemplateElement.elementText("template-path"),
360                                            layoutTemplateModel.getTemplatePath()));
361                            layoutTemplateModel.setWapTemplatePath(
362                                    GetterUtil.getString(
363                                            layoutTemplateElement.elementText("wap-template-path"),
364                                            layoutTemplateModel.getWapTemplatePath()));
365                            layoutTemplateModel.setThumbnailPath(
366                                    GetterUtil.getString(
367                                            layoutTemplateElement.elementText("thumbnail-path"),
368                                            layoutTemplateModel.getThumbnailPath()));
369    
370                            String content = null;
371    
372                            try {
373                                    content = HttpUtil.URLtoString(
374                                            servletContext.getResource(
375                                                    layoutTemplateModel.getTemplatePath()));
376                            }
377                            catch (Exception e) {
378                                    _log.error(
379                                            "Unable to get content at template path " +
380                                                    layoutTemplateModel.getTemplatePath() + ": " +
381                                                            e.getMessage());
382                            }
383    
384                            if (Validator.isNull(content)) {
385                                    _log.error(
386                                            "No content found at template path " +
387                                                    layoutTemplateModel.getTemplatePath());
388                            }
389                            else {
390                                    StringBundler sb = new StringBundler(3);
391    
392                                    sb.append(themeId);
393    
394                                    if (standard) {
395                                            sb.append(LayoutTemplateConstants.STANDARD_SEPARATOR);
396                                    }
397                                    else {
398                                            sb.append(LayoutTemplateConstants.CUSTOM_SEPARATOR);
399                                    }
400    
401                                    sb.append(layoutTemplateId);
402    
403                                    String velocityTemplateId = sb.toString();
404    
405                                    layoutTemplateModel.setContent(content);
406                                    layoutTemplateModel.setColumns(
407                                            _getColumns(velocityTemplateId, content));
408                            }
409    
410                            if (Validator.isNull(layoutTemplateModel.getWapTemplatePath())) {
411                                    _log.error(
412                                            "The element wap-template-path is not defined for " +
413                                                    layoutTemplateId);
414                            }
415                            else {
416                                    String wapContent = null;
417    
418                                    try {
419                                            wapContent = HttpUtil.URLtoString(
420                                                    servletContext.getResource(
421                                                            layoutTemplateModel.getWapTemplatePath()));
422                                    }
423                                    catch (Exception e) {
424                                            _log.error(
425                                                    "Unable to get content at WAP template path " +
426                                                            layoutTemplateModel.getWapTemplatePath() + ": " +
427                                                                    e.getMessage());
428                                    }
429    
430                                    if (Validator.isNull(wapContent)) {
431                                            _log.error(
432                                                    "No content found at WAP template path " +
433                                                            layoutTemplateModel.getWapTemplatePath());
434                                    }
435                                    else {
436                                            layoutTemplateModel.setWapContent(wapContent);
437                                    }
438                            }
439    
440                            Element rolesElement = layoutTemplateElement.element("roles");
441    
442                            if (rolesElement != null) {
443                                    List<Element> roleNameElements = rolesElement.elements(
444                                            "role-name");
445    
446                                    for (Element roleNameElement : roleNameElements) {
447                                            pluginSetting.addRole(roleNameElement.getText());
448                                    }
449                            }
450    
451                            layoutTemplateModel.setDefaultPluginSetting(pluginSetting);
452    
453                            if (layoutTemplates != null) {
454                                    layoutTemplates.add(layoutTemplateModel);
455                            }
456                    }
457            }
458    
459            @Override
460            public void uninstallLayoutTemplate(
461                    String layoutTemplateId, boolean standard) {
462    
463                    String templateId = null;
464    
465                    try {
466                            if (standard) {
467                                    templateId =
468                                            "null" + LayoutTemplateConstants.STANDARD_SEPARATOR +
469                                                    layoutTemplateId;
470    
471                                    TemplateResourceLoaderUtil.clearCache(
472                                            TemplateConstants.LANG_TYPE_VM, templateId);
473    
474                                    _warStandard.remove(layoutTemplateId);
475                            }
476                            else {
477                                    templateId =
478                                            "null" + LayoutTemplateConstants.CUSTOM_SEPARATOR +
479                                                    layoutTemplateId;
480    
481                                    TemplateResourceLoaderUtil.clearCache(
482                                            TemplateConstants.LANG_TYPE_VM, templateId);
483    
484                                    _warCustom.remove(layoutTemplateId);
485                            }
486                    }
487                    catch (Exception e) {
488                            _log.error(
489                                    "Unable to uninstall layout template " + layoutTemplateId, e);
490                    }
491            }
492    
493            @Override
494            public void uninstallLayoutTemplates(String themeId) {
495                    Map<String, LayoutTemplate> _themesStandard = _getThemesStandard(
496                            themeId);
497    
498                    for (Map.Entry<String, LayoutTemplate> entry :
499                                    _themesStandard.entrySet()) {
500    
501                            LayoutTemplate layoutTemplate = entry.getValue();
502    
503                            String templateId =
504                                    themeId + LayoutTemplateConstants.STANDARD_SEPARATOR +
505                                            layoutTemplate.getLayoutTemplateId();
506    
507                            try {
508                                    TemplateResourceLoaderUtil.clearCache(
509                                            TemplateConstants.LANG_TYPE_VM, templateId);
510                            }
511                            catch (Exception e) {
512                                    _log.error(
513                                            "Unable to uninstall layout template " +
514                                                    layoutTemplate.getLayoutTemplateId(),
515                                            e);
516                            }
517                    }
518    
519                    _themesStandard.clear();
520    
521                    Map<String, LayoutTemplate> _themesCustom = _getThemesCustom(themeId);
522    
523                    for (Map.Entry<String, LayoutTemplate> entry :
524                                    _themesCustom.entrySet()) {
525    
526                            LayoutTemplate layoutTemplate = entry.getValue();
527    
528                            String templateId =
529                                    themeId + LayoutTemplateConstants.CUSTOM_SEPARATOR +
530                                            layoutTemplate.getLayoutTemplateId();
531    
532                            try {
533                                    TemplateResourceLoaderUtil.clearCache(
534                                            TemplateConstants.LANG_TYPE_VM, templateId);
535                            }
536                            catch (Exception e) {
537                                    _log.error(
538                                            "Unable to uninstall layout template " +
539                                                    layoutTemplate.getLayoutTemplateId(),
540                                            e);
541                            }
542                    }
543    
544                    _themesCustom.clear();
545            }
546    
547            private List<String> _getColumns(
548                    String velocityTemplateId, String velocityTemplateContent) {
549    
550                    try {
551                            InitColumnProcessor processor = new InitColumnProcessor();
552    
553                            Template template = TemplateManagerUtil.getTemplate(
554                                    TemplateConstants.LANG_TYPE_VM,
555                                    new StringTemplateResource(
556                                            velocityTemplateId, velocityTemplateContent),
557                                    false);
558    
559                            template.put("processor", processor);
560    
561                            template.processTemplate(new DummyWriter());
562    
563                            return ListUtil.sort(processor.getColumns());
564                    }
565                    catch (Exception e) {
566                            _log.error(e);
567    
568                            return new ArrayList<String>();
569                    }
570            }
571    
572            private Map<String, LayoutTemplate> _getThemesCustom(String themeId) {
573                    String key = themeId.concat(LayoutTemplateConstants.CUSTOM_SEPARATOR);
574    
575                    Map<String, LayoutTemplate> layoutTemplates = _themes.get(key);
576    
577                    if (layoutTemplates == null) {
578                            layoutTemplates = new LinkedHashMap<String, LayoutTemplate>();
579    
580                            _themes.put(key, layoutTemplates);
581                    }
582    
583                    return layoutTemplates;
584            }
585    
586            private Map<String, LayoutTemplate> _getThemesStandard(String themeId) {
587                    String key = themeId + LayoutTemplateConstants.STANDARD_SEPARATOR;
588    
589                    Map<String, LayoutTemplate> layoutTemplates = _themes.get(key);
590    
591                    if (layoutTemplates == null) {
592                            layoutTemplates = new LinkedHashMap<String, LayoutTemplate>();
593    
594                            _themes.put(key, layoutTemplates);
595                    }
596    
597                    return layoutTemplates;
598            }
599    
600            private Set<LayoutTemplate> _readLayoutTemplates(
601                            String servletContextName, ServletContext servletContext,
602                            String xml, PluginPackage pluginPackage)
603                    throws Exception {
604    
605                    Set<LayoutTemplate> layoutTemplates = new HashSet<LayoutTemplate>();
606    
607                    if (xml == null) {
608                            return layoutTemplates;
609                    }
610    
611                    Document document = SAXReaderUtil.read(xml, true);
612    
613                    Element rootElement = document.getRootElement();
614    
615                    Element standardElement = rootElement.element("standard");
616    
617                    if (standardElement != null) {
618                            readLayoutTemplate(
619                                    servletContextName, servletContext, layoutTemplates,
620                                    standardElement, true, null, pluginPackage);
621                    }
622    
623                    Element customElement = rootElement.element("custom");
624    
625                    if (customElement != null) {
626                            readLayoutTemplate(
627                                    servletContextName, servletContext, layoutTemplates,
628                                    customElement, false, null, pluginPackage);
629                    }
630    
631                    return layoutTemplates;
632            }
633    
634            private static Log _log = LogFactoryUtil.getLog(
635                    LayoutTemplateLocalServiceImpl.class);
636    
637            private static Map<String, LayoutTemplate> _portalCustom =
638                    new LinkedHashMap<String, LayoutTemplate>();
639            private static Map<String, LayoutTemplate> _portalStandard =
640                    new LinkedHashMap<String, LayoutTemplate>();
641            private static Map<String, Map<String, LayoutTemplate>> _themes =
642                    new LinkedHashMap<String, Map<String, LayoutTemplate>>();
643            private static Map<String, LayoutTemplate> _warCustom =
644                    new LinkedHashMap<String, LayoutTemplate>();
645            private static Map<String, LayoutTemplate> _warStandard =
646                    new LinkedHashMap<String, LayoutTemplate>();
647    
648    }