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.StringUtil;
024    import com.liferay.portal.kernel.xml.Element;
025    import com.liferay.portal.model.Group;
026    import com.liferay.portal.service.GroupLocalServiceUtil;
027    import com.liferay.portal.service.ServiceContext;
028    import com.liferay.portal.service.UserLocalServiceUtil;
029    import com.liferay.portal.util.PortalUtil;
030    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplate;
031    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants;
032    import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
033    import com.liferay.portlet.portletdisplaytemplate.util.PortletDisplayTemplate;
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 Log _log = LogFactoryUtil.getLog(
100                    TemplateHandlerRegistryUtil.class);
101    
102            private static final TemplateHandlerRegistryUtil _instance =
103                    new TemplateHandlerRegistryUtil();
104    
105            private final ServiceTracker<TemplateHandler, TemplateHandler>
106                    _serviceTracker;
107            private final Map<String, TemplateHandler> _templateHandlers =
108                    new ConcurrentHashMap<>();
109    
110            private class TemplateHandlerServiceTrackerCustomizer
111                    implements ServiceTrackerCustomizer<TemplateHandler, TemplateHandler> {
112    
113                    @Override
114                    public TemplateHandler addingService(
115                            ServiceReference<TemplateHandler> serviceReference) {
116    
117                            Registry registry = RegistryUtil.getRegistry();
118    
119                            TemplateHandler templateHandler = registry.getService(
120                                    serviceReference);
121    
122                            _templateHandlers.put(
123                                    templateHandler.getClassName(), templateHandler);
124    
125                            try {
126                                    _addTemplate(templateHandler);
127                            }
128                            catch (Exception e) {
129                                    _log.error(
130                                            "Unable to add template for template handler " +
131                                                    templateHandler.getClassName(),
132                                            e);
133                            }
134    
135                            return templateHandler;
136                    }
137    
138                    @Override
139                    public void modifiedService(
140                            ServiceReference<TemplateHandler> serviceReference,
141                            TemplateHandler templateHandler) {
142                    }
143    
144                    @Override
145                    public void removedService(
146                            ServiceReference<TemplateHandler> serviceReference,
147                            TemplateHandler templateHandler) {
148    
149                            Registry registry = RegistryUtil.getRegistry();
150    
151                            registry.ungetService(serviceReference);
152    
153                            _templateHandlers.remove(templateHandler.getClassName());
154                    }
155    
156                    private void _addTemplate(TemplateHandler templateHandler)
157                            throws Exception {
158    
159                            long classNameId = PortalUtil.getClassNameId(
160                                    templateHandler.getClassName());
161    
162                            ServiceContext serviceContext = new ServiceContext();
163    
164                            long companyId = PortalUtil.getDefaultCompanyId();
165    
166                            Group group = GroupLocalServiceUtil.getCompanyGroup(companyId);
167    
168                            serviceContext.setScopeGroupId(group.getGroupId());
169    
170                            long userId = UserLocalServiceUtil.getDefaultUserId(companyId);
171    
172                            serviceContext.setUserId(userId);
173    
174                            List<Element> templateElements =
175                                    templateHandler.getDefaultTemplateElements();
176    
177                            for (Element templateElement : templateElements) {
178                                    String templateKey = templateElement.elementText(
179                                            "template-key");
180    
181                                    DDMTemplate ddmTemplate =
182                                            DDMTemplateLocalServiceUtil.fetchTemplate(
183                                                    group.getGroupId(), classNameId, templateKey);
184    
185                                    if (ddmTemplate != null) {
186                                            continue;
187                                    }
188    
189                                    Class<?> clazz = templateHandler.getClass();
190    
191                                    ClassLoader classLoader = clazz.getClassLoader();
192    
193                                    Map<Locale, String> nameMap = _getLocalizationMap(
194                                            classLoader, group.getGroupId(),
195                                            templateElement.elementText("name"));
196                                    Map<Locale, String> descriptionMap = _getLocalizationMap(
197                                            classLoader, group.getGroupId(),
198                                            templateElement.elementText("description"));
199                                    String language = templateElement.elementText("language");
200                                    String scriptFileName = templateElement.elementText(
201                                            "script-file");
202    
203                                    String script = StringUtil.read(classLoader, scriptFileName);
204    
205                                    boolean cacheable = GetterUtil.getBoolean(
206                                            templateElement.elementText("cacheable"));
207    
208                                    DDMTemplateLocalServiceUtil.addTemplate(
209                                            userId, group.getGroupId(), classNameId, 0,
210                                            PortalUtil.getClassNameId(PortletDisplayTemplate.class),
211                                            templateKey, nameMap, descriptionMap,
212                                            DDMTemplateConstants.TEMPLATE_TYPE_DISPLAY, null, language,
213                                            script, cacheable, false, null, null, serviceContext);
214                            }
215                    }
216    
217                    private Map<Locale, String> _getLocalizationMap(
218                            ClassLoader classLoader, long groupId, String key) {
219    
220                            Map<Locale, String> map = new HashMap<>();
221    
222                            for (Locale locale : LanguageUtil.getAvailableLocales(groupId)) {
223                                    ResourceBundle resourceBundle = ResourceBundle.getBundle(
224                                            "content.Language", locale, classLoader);
225    
226                                    map.put(locale, LanguageUtil.get(resourceBundle, key));
227                            }
228    
229                            return map;
230                    }
231    
232            }
233    
234    }