001    /**
002     * Copyright (c) 2000-present 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.kernel.template;
016    
017    import aQute.bnd.annotation.ProviderType;
018    
019    import com.liferay.portal.kernel.language.LanguageUtil;
020    import com.liferay.portal.kernel.log.Log;
021    import com.liferay.portal.kernel.log.LogFactoryUtil;
022    import com.liferay.portal.kernel.util.GetterUtil;
023    import com.liferay.portal.kernel.util.ResourceBundleUtil;
024    import com.liferay.portal.kernel.util.StringUtil;
025    import com.liferay.portal.kernel.xml.Element;
026    import com.liferay.portal.model.Group;
027    import com.liferay.portal.service.GroupLocalServiceUtil;
028    import com.liferay.portal.service.ServiceContext;
029    import com.liferay.portal.service.UserLocalServiceUtil;
030    import com.liferay.portal.util.PortalUtil;
031    import com.liferay.portlet.dynamicdatamapping.DDMTemplate;
032    import com.liferay.portlet.dynamicdatamapping.DDMTemplateManager;
033    import com.liferay.portlet.dynamicdatamapping.DDMTemplateManagerUtil;
034    import com.liferay.registry.Registry;
035    import com.liferay.registry.RegistryUtil;
036    import com.liferay.registry.ServiceReference;
037    import com.liferay.registry.ServiceTracker;
038    import com.liferay.registry.ServiceTrackerCustomizer;
039    
040    import java.util.ArrayList;
041    import java.util.Collections;
042    import java.util.HashMap;
043    import java.util.List;
044    import java.util.Locale;
045    import java.util.Map;
046    import java.util.ResourceBundle;
047    import java.util.concurrent.ConcurrentHashMap;
048    
049    /**
050     * @author Juan Fern??ndez
051     */
052    @ProviderType
053    public class TemplateHandlerRegistryUtil {
054    
055            public static long[] getClassNameIds() {
056                    long[] classNameIds = new long[_instance._templateHandlers.size()];
057    
058                    int i = 0;
059    
060                    for (Map.Entry<String, TemplateHandler> entry :
061                                    _instance._templateHandlers.entrySet()) {
062    
063                            TemplateHandler templateHandler = entry.getValue();
064    
065                            classNameIds[i++] = PortalUtil.getClassNameId(
066                                    templateHandler.getClassName());
067                    }
068    
069                    return classNameIds;
070            }
071    
072            public static TemplateHandler getTemplateHandler(long classNameId) {
073                    String className = PortalUtil.getClassName(classNameId);
074    
075                    return _instance._templateHandlers.get(className);
076            }
077    
078            public static TemplateHandler getTemplateHandler(String className) {
079                    return _instance._templateHandlers.get(className);
080            }
081    
082            public static List<TemplateHandler> getTemplateHandlers() {
083                    List<TemplateHandler> templateHandlers = new ArrayList<>(
084                            _instance._templateHandlers.values());
085    
086                    return Collections.unmodifiableList(templateHandlers);
087            }
088    
089            private TemplateHandlerRegistryUtil() {
090                    Registry registry = RegistryUtil.getRegistry();
091    
092                    _serviceTracker = registry.trackServices(
093                            TemplateHandler.class,
094                            new TemplateHandlerServiceTrackerCustomizer());
095    
096                    _serviceTracker.open();
097            }
098    
099            private static final String _PORTLET_DISPLAY_TEMPLATE_CLASS_NAME =
100                    "com.liferay.portlet.display.template.PortletDisplayTemplate";
101    
102            private static final Log _log = LogFactoryUtil.getLog(
103                    TemplateHandlerRegistryUtil.class);
104    
105            private static final TemplateHandlerRegistryUtil _instance =
106                    new TemplateHandlerRegistryUtil();
107    
108            private final ServiceTracker<TemplateHandler, TemplateHandler>
109                    _serviceTracker;
110            private final Map<String, TemplateHandler> _templateHandlers =
111                    new ConcurrentHashMap<>();
112    
113            private class TemplateHandlerServiceTrackerCustomizer
114                    implements ServiceTrackerCustomizer<TemplateHandler, TemplateHandler> {
115    
116                    @Override
117                    public TemplateHandler addingService(
118                            ServiceReference<TemplateHandler> serviceReference) {
119    
120                            Registry registry = RegistryUtil.getRegistry();
121    
122                            TemplateHandler templateHandler = registry.getService(
123                                    serviceReference);
124    
125                            _templateHandlers.put(
126                                    templateHandler.getClassName(), templateHandler);
127    
128                            try {
129                                    _addTemplate(templateHandler);
130                            }
131                            catch (Exception e) {
132                                    _log.error(
133                                            "Unable to add template for template handler " +
134                                                    templateHandler.getClassName(),
135                                            e);
136                            }
137    
138                            return templateHandler;
139                    }
140    
141                    @Override
142                    public void modifiedService(
143                            ServiceReference<TemplateHandler> serviceReference,
144                            TemplateHandler templateHandler) {
145                    }
146    
147                    @Override
148                    public void removedService(
149                            ServiceReference<TemplateHandler> serviceReference,
150                            TemplateHandler templateHandler) {
151    
152                            Registry registry = RegistryUtil.getRegistry();
153    
154                            registry.ungetService(serviceReference);
155    
156                            _templateHandlers.remove(templateHandler.getClassName());
157                    }
158    
159                    private void _addTemplate(TemplateHandler templateHandler)
160                            throws Exception {
161    
162                            long classNameId = PortalUtil.getClassNameId(
163                                    templateHandler.getClassName());
164    
165                            ServiceContext serviceContext = new ServiceContext();
166    
167                            long companyId = PortalUtil.getDefaultCompanyId();
168    
169                            Group group = GroupLocalServiceUtil.getCompanyGroup(companyId);
170    
171                            serviceContext.setScopeGroupId(group.getGroupId());
172    
173                            long userId = UserLocalServiceUtil.getDefaultUserId(companyId);
174    
175                            serviceContext.setUserId(userId);
176    
177                            List<Element> templateElements =
178                                    templateHandler.getDefaultTemplateElements();
179    
180                            for (Element templateElement : templateElements) {
181                                    String templateKey = templateElement.elementText(
182                                            "template-key");
183    
184                                    DDMTemplate ddmTemplate = DDMTemplateManagerUtil.fetchTemplate(
185                                            group.getGroupId(), classNameId, templateKey);
186    
187                                    if (ddmTemplate != null) {
188                                            continue;
189                                    }
190    
191                                    Class<?> clazz = templateHandler.getClass();
192    
193                                    ClassLoader classLoader = clazz.getClassLoader();
194    
195                                    Map<Locale, String> nameMap = _getLocalizationMap(
196                                            classLoader, group.getGroupId(),
197                                            templateElement.elementText("name"));
198                                    Map<Locale, String> descriptionMap = _getLocalizationMap(
199                                            classLoader, group.getGroupId(),
200                                            templateElement.elementText("description"));
201    
202                                    String type = templateElement.elementText("type");
203    
204                                    if (type == null) {
205                                            type = DDMTemplateManager.TEMPLATE_TYPE_DISPLAY;
206                                    }
207    
208                                    String language = templateElement.elementText("language");
209    
210                                    String scriptFileName = templateElement.elementText(
211                                            "script-file");
212    
213                                    String script = StringUtil.read(classLoader, scriptFileName);
214    
215                                    boolean cacheable = GetterUtil.getBoolean(
216                                            templateElement.elementText("cacheable"));
217    
218                                    DDMTemplateManagerUtil.addTemplate(
219                                            userId, group.getGroupId(), classNameId, 0,
220                                            PortalUtil.getClassNameId(
221                                                    _PORTLET_DISPLAY_TEMPLATE_CLASS_NAME),
222                                            templateKey, nameMap, descriptionMap, type, null, language,
223                                            script, cacheable, false, null, null, serviceContext);
224                            }
225                    }
226    
227                    private Map<Locale, String> _getLocalizationMap(
228                            ClassLoader classLoader, long groupId, String key) {
229    
230                            Map<Locale, String> map = new HashMap<>();
231    
232                            for (Locale locale : LanguageUtil.getAvailableLocales(groupId)) {
233                                    ResourceBundle resourceBundle = ResourceBundleUtil.getBundle(
234                                            "content.Language", locale, classLoader);
235    
236                                    map.put(locale, LanguageUtil.get(resourceBundle, key));
237                            }
238    
239                            return map;
240                    }
241    
242            }
243    
244    }