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    
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                            layoutTemplateModel.setName(
352                                    GetterUtil.getString(
353                                            layoutTemplateElement.attributeValue("name"),
354                                            layoutTemplateModel.getName()));
355                            layoutTemplateModel.setTemplatePath(
356                                    GetterUtil.getString(
357                                            layoutTemplateElement.elementText("template-path"),
358                                            layoutTemplateModel.getTemplatePath()));
359                            layoutTemplateModel.setWapTemplatePath(
360                                    GetterUtil.getString(
361                                            layoutTemplateElement.elementText("wap-template-path"),
362                                            layoutTemplateModel.getWapTemplatePath()));
363                            layoutTemplateModel.setThumbnailPath(
364                                    GetterUtil.getString(
365                                            layoutTemplateElement.elementText("thumbnail-path"),
366                                            layoutTemplateModel.getThumbnailPath()));
367    
368                            String content = null;
369    
370                            try {
371                                    content = HttpUtil.URLtoString(
372                                            servletContext.getResource(
373                                                    layoutTemplateModel.getTemplatePath()));
374                            }
375                            catch (Exception e) {
376                                    _log.error(
377                                            "Unable to get content at template path " +
378                                                    layoutTemplateModel.getTemplatePath() + ": " +
379                                                            e.getMessage());
380                            }
381    
382                            if (Validator.isNull(content)) {
383                                    _log.error(
384                                            "No content found at template path " +
385                                                    layoutTemplateModel.getTemplatePath());
386                            }
387                            else {
388                                    StringBundler sb = new StringBundler(3);
389    
390                                    sb.append(themeId);
391    
392                                    if (standard) {
393                                            sb.append(LayoutTemplateConstants.STANDARD_SEPARATOR);
394                                    }
395                                    else {
396                                            sb.append(LayoutTemplateConstants.CUSTOM_SEPARATOR);
397                                    }
398    
399                                    sb.append(layoutTemplateId);
400    
401                                    String velocityTemplateId = sb.toString();
402    
403                                    layoutTemplateModel.setContent(content);
404                                    layoutTemplateModel.setColumns(
405                                            _getColumns(velocityTemplateId, content));
406                            }
407    
408                            if (Validator.isNull(layoutTemplateModel.getWapTemplatePath())) {
409                                    _log.error(
410                                            "The element wap-template-path is not defined for " +
411                                                    layoutTemplateId);
412                            }
413                            else {
414                                    String wapContent = null;
415    
416                                    try {
417                                            wapContent = HttpUtil.URLtoString(
418                                                    servletContext.getResource(
419                                                            layoutTemplateModel.getWapTemplatePath()));
420                                    }
421                                    catch (Exception e) {
422                                            _log.error(
423                                                    "Unable to get content at WAP template path " +
424                                                            layoutTemplateModel.getWapTemplatePath() + ": " +
425                                                                    e.getMessage());
426                                    }
427    
428                                    if (Validator.isNull(wapContent)) {
429                                            _log.error(
430                                                    "No content found at WAP template path " +
431                                                            layoutTemplateModel.getWapTemplatePath());
432                                    }
433                                    else {
434                                            layoutTemplateModel.setWapContent(wapContent);
435                                    }
436                            }
437    
438                            Element rolesElement = layoutTemplateElement.element("roles");
439    
440                            if (rolesElement != null) {
441                                    List<Element> roleNameElements = rolesElement.elements(
442                                            "role-name");
443    
444                                    for (Element roleNameElement : roleNameElements) {
445                                            pluginSetting.addRole(roleNameElement.getText());
446                                    }
447                            }
448    
449                            layoutTemplateModel.setDefaultPluginSetting(pluginSetting);
450    
451                            if (layoutTemplates != null) {
452                                    layoutTemplates.add(layoutTemplateModel);
453                            }
454                    }
455            }
456    
457            @Override
458            public void uninstallLayoutTemplate(
459                    String layoutTemplateId, boolean standard) {
460    
461                    String templateId = null;
462    
463                    try {
464                            if (standard) {
465                                    templateId =
466                                            "null" + LayoutTemplateConstants.STANDARD_SEPARATOR +
467                                                    layoutTemplateId;
468    
469                                    TemplateResourceLoaderUtil.clearCache(
470                                            TemplateConstants.LANG_TYPE_VM, templateId);
471    
472                                    _warStandard.remove(layoutTemplateId);
473                            }
474                            else {
475                                    templateId =
476                                            "null" + LayoutTemplateConstants.CUSTOM_SEPARATOR +
477                                                    layoutTemplateId;
478    
479                                    TemplateResourceLoaderUtil.clearCache(
480                                            TemplateConstants.LANG_TYPE_VM, templateId);
481    
482                                    _warCustom.remove(layoutTemplateId);
483                            }
484                    }
485                    catch (Exception e) {
486                            _log.error(
487                                    "Unable to uninstall layout template " + layoutTemplateId, e);
488                    }
489            }
490    
491            @Override
492            public void uninstallLayoutTemplates(String themeId) {
493                    Map<String, LayoutTemplate> _themesStandard = _getThemesStandard(
494                            themeId);
495    
496                    for (Map.Entry<String, LayoutTemplate> entry :
497                                    _themesStandard.entrySet()) {
498    
499                            LayoutTemplate layoutTemplate = entry.getValue();
500    
501                            String templateId =
502                                    themeId + LayoutTemplateConstants.STANDARD_SEPARATOR +
503                                            layoutTemplate.getLayoutTemplateId();
504    
505                            try {
506                                    TemplateResourceLoaderUtil.clearCache(
507                                            TemplateConstants.LANG_TYPE_VM, templateId);
508                            }
509                            catch (Exception e) {
510                                    _log.error(
511                                            "Unable to uninstall layout template " +
512                                                    layoutTemplate.getLayoutTemplateId(),
513                                            e);
514                            }
515                    }
516    
517                    _themesStandard.clear();
518    
519                    Map<String, LayoutTemplate> _themesCustom = _getThemesCustom(themeId);
520    
521                    for (Map.Entry<String, LayoutTemplate> entry :
522                                    _themesCustom.entrySet()) {
523    
524                            LayoutTemplate layoutTemplate = entry.getValue();
525    
526                            String templateId =
527                                    themeId + LayoutTemplateConstants.CUSTOM_SEPARATOR +
528                                            layoutTemplate.getLayoutTemplateId();
529    
530                            try {
531                                    TemplateResourceLoaderUtil.clearCache(
532                                            TemplateConstants.LANG_TYPE_VM, templateId);
533                            }
534                            catch (Exception e) {
535                                    _log.error(
536                                            "Unable to uninstall layout template " +
537                                                    layoutTemplate.getLayoutTemplateId(),
538                                            e);
539                            }
540                    }
541    
542                    _themesCustom.clear();
543            }
544    
545            private List<String> _getColumns(
546                    String velocityTemplateId, String velocityTemplateContent) {
547    
548                    try {
549                            InitColumnProcessor processor = new InitColumnProcessor();
550    
551                            Template template = TemplateManagerUtil.getTemplate(
552                                    TemplateConstants.LANG_TYPE_VM,
553                                    new StringTemplateResource(
554                                            velocityTemplateId, velocityTemplateContent),
555                                    false);
556    
557                            template.put("processor", processor);
558    
559                            template.processTemplate(new DummyWriter());
560    
561                            return ListUtil.sort(processor.getColumns());
562                    }
563                    catch (Exception e) {
564                            _log.error(e);
565    
566                            return new ArrayList<String>();
567                    }
568            }
569    
570            private Map<String, LayoutTemplate> _getThemesCustom(String themeId) {
571                    String key = themeId.concat(LayoutTemplateConstants.CUSTOM_SEPARATOR);
572    
573                    Map<String, LayoutTemplate> layoutTemplates = _themes.get(key);
574    
575                    if (layoutTemplates == null) {
576                            layoutTemplates = new LinkedHashMap<String, LayoutTemplate>();
577    
578                            _themes.put(key, layoutTemplates);
579                    }
580    
581                    return layoutTemplates;
582            }
583    
584            private Map<String, LayoutTemplate> _getThemesStandard(String themeId) {
585                    String key = themeId + LayoutTemplateConstants.STANDARD_SEPARATOR;
586    
587                    Map<String, LayoutTemplate> layoutTemplates = _themes.get(key);
588    
589                    if (layoutTemplates == null) {
590                            layoutTemplates = new LinkedHashMap<String, LayoutTemplate>();
591    
592                            _themes.put(key, layoutTemplates);
593                    }
594    
595                    return layoutTemplates;
596            }
597    
598            private Set<LayoutTemplate> _readLayoutTemplates(
599                            String servletContextName, ServletContext servletContext,
600                            String xml, PluginPackage pluginPackage)
601                    throws Exception {
602    
603                    Set<LayoutTemplate> layoutTemplates = new HashSet<LayoutTemplate>();
604    
605                    if (xml == null) {
606                            return layoutTemplates;
607                    }
608    
609                    Document document = SAXReaderUtil.read(xml, true);
610    
611                    Element rootElement = document.getRootElement();
612    
613                    Element standardElement = rootElement.element("standard");
614    
615                    if (standardElement != null) {
616                            readLayoutTemplate(
617                                    servletContextName, servletContext, layoutTemplates,
618                                    standardElement, true, null, pluginPackage);
619                    }
620    
621                    Element customElement = rootElement.element("custom");
622    
623                    if (customElement != null) {
624                            readLayoutTemplate(
625                                    servletContextName, servletContext, layoutTemplates,
626                                    customElement, false, null, pluginPackage);
627                    }
628    
629                    return layoutTemplates;
630            }
631    
632            private static Log _log = LogFactoryUtil.getLog(
633                    LayoutTemplateLocalServiceImpl.class);
634    
635            private static Map<String, LayoutTemplate> _portalCustom =
636                    new LinkedHashMap<String, LayoutTemplate>();
637            private static Map<String, LayoutTemplate> _portalStandard =
638                    new LinkedHashMap<String, LayoutTemplate>();
639            private static Map<String, Map<String, LayoutTemplate>> _themes =
640                    new LinkedHashMap<String, Map<String, LayoutTemplate>>();
641            private static Map<String, LayoutTemplate> _warCustom =
642                    new LinkedHashMap<String, LayoutTemplate>();
643            private static Map<String, LayoutTemplate> _warStandard =
644                    new LinkedHashMap<String, LayoutTemplate>();
645    
646    }