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.portlet.dynamicdatamapping.util;
016    
017    import com.liferay.portal.kernel.language.LanguageUtil;
018    import com.liferay.portal.kernel.template.TemplateConstants;
019    import com.liferay.portal.kernel.upgrade.util.UpgradeProcessUtil;
020    import com.liferay.portal.kernel.util.FileUtil;
021    import com.liferay.portal.kernel.util.GetterUtil;
022    import com.liferay.portal.kernel.util.LocaleUtil;
023    import com.liferay.portal.kernel.util.StringPool;
024    import com.liferay.portal.kernel.util.StringUtil;
025    import com.liferay.portal.kernel.workflow.WorkflowConstants;
026    import com.liferay.portal.kernel.xml.Attribute;
027    import com.liferay.portal.kernel.xml.Document;
028    import com.liferay.portal.kernel.xml.Element;
029    import com.liferay.portal.kernel.xml.UnsecureSAXReaderUtil;
030    import com.liferay.portal.service.ServiceContext;
031    import com.liferay.portal.util.PortalUtil;
032    import com.liferay.portlet.documentlibrary.model.DLFileEntryTypeConstants;
033    import com.liferay.portlet.dynamicdatamapping.io.DDMFormXSDDeserializerUtil;
034    import com.liferay.portlet.dynamicdatamapping.model.DDMForm;
035    import com.liferay.portlet.dynamicdatamapping.model.DDMFormLayout;
036    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
037    import com.liferay.portlet.dynamicdatamapping.model.DDMStructureConstants;
038    import com.liferay.portlet.dynamicdatamapping.model.DDMTemplateConstants;
039    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
040    import com.liferay.portlet.dynamicdatamapping.service.DDMTemplateLocalServiceUtil;
041    import com.liferay.portlet.dynamicdatamapping.storage.StorageType;
042    
043    import java.util.HashMap;
044    import java.util.List;
045    import java.util.Locale;
046    import java.util.Map;
047    
048    /**
049     * @author Michael C. Han
050     */
051    public class DefaultDDMStructureUtil {
052    
053            public static void addDDMStructures(
054                            long userId, long groupId, long classNameId,
055                            ClassLoader classLoader, String fileName,
056                            ServiceContext serviceContext)
057                    throws Exception {
058    
059                    Locale locale = PortalUtil.getSiteDefaultLocale(groupId);
060    
061                    List<Element> structureElements = getDDMStructures(
062                            classLoader, fileName, locale);
063    
064                    for (Element structureElement : structureElements) {
065                            boolean dynamicStructure = GetterUtil.getBoolean(
066                                    structureElement.elementText("dynamic-structure"));
067    
068                            if (dynamicStructure) {
069                                    continue;
070                            }
071    
072                            String name = structureElement.elementText("name");
073    
074                            String description = structureElement.elementText("description");
075    
076                            String ddmStructureKey = name;
077    
078                            DDMStructure ddmStructure =
079                                    DDMStructureLocalServiceUtil.fetchStructure(
080                                            groupId, classNameId, ddmStructureKey);
081    
082                            if (ddmStructure != null) {
083                                    continue;
084                            }
085    
086                            Element structureElementRootElement = structureElement.element(
087                                    "root");
088    
089                            String definition = structureElementRootElement.asXML();
090    
091                            Map<Locale, String> nameMap = new HashMap<>();
092                            Map<Locale, String> descriptionMap = new HashMap<>();
093    
094                            for (Locale curLocale : LanguageUtil.getAvailableLocales(groupId)) {
095                                    nameMap.put(curLocale, LanguageUtil.get(curLocale, name));
096                                    descriptionMap.put(
097                                            curLocale, LanguageUtil.get(curLocale, description));
098                            }
099    
100                            Attribute defaultLocaleAttribute =
101                                    structureElementRootElement.attribute("default-locale");
102    
103                            Locale ddmStructureDefaultLocale = LocaleUtil.fromLanguageId(
104                                    defaultLocaleAttribute.getValue());
105    
106                            definition = DDMXMLUtil.updateXMLDefaultLocale(
107                                    definition, ddmStructureDefaultLocale, locale);
108    
109                            if (name.equals(DLFileEntryTypeConstants.NAME_IG_IMAGE) &&
110                                    !UpgradeProcessUtil.isCreateIGImageDocumentType()) {
111    
112                                    continue;
113                            }
114    
115                            DDMForm ddmForm = DDMFormXSDDeserializerUtil.deserialize(
116                                    definition);
117    
118                            DDMFormLayout ddmFormLayout = DDMUtil.getDefaultDDMFormLayout(
119                                    ddmForm);
120    
121                            serviceContext.setAttribute(
122                                    "status", WorkflowConstants.STATUS_APPROVED);
123    
124                            ddmStructure = DDMStructureLocalServiceUtil.addStructure(
125                                    userId, groupId,
126                                    DDMStructureConstants.DEFAULT_PARENT_STRUCTURE_ID, classNameId,
127                                    ddmStructureKey, nameMap, descriptionMap, ddmForm,
128                                    ddmFormLayout, StorageType.JSON.toString(),
129                                    DDMStructureConstants.TYPE_DEFAULT, serviceContext);
130    
131                            Element templateElement = structureElement.element("template");
132    
133                            if (templateElement == null) {
134                                    continue;
135                            }
136    
137                            String templateFileName = templateElement.elementText("file-name");
138    
139                            String script = StringUtil.read(
140                                    classLoader,
141                                    FileUtil.getPath(fileName) + StringPool.SLASH +
142                                            templateFileName);
143    
144                            boolean cacheable = GetterUtil.getBoolean(
145                                    templateElement.elementText("cacheable"));
146    
147                            DDMTemplateLocalServiceUtil.addTemplate(
148                                    userId, groupId, PortalUtil.getClassNameId(DDMStructure.class),
149                                    ddmStructure.getStructureId(), ddmStructure.getClassNameId(),
150                                    null, nameMap, null, DDMTemplateConstants.TEMPLATE_TYPE_DISPLAY,
151                                    DDMTemplateConstants.TEMPLATE_MODE_CREATE,
152                                    TemplateConstants.LANG_TYPE_FTL, script, cacheable, false,
153                                    StringPool.BLANK, null, serviceContext);
154                    }
155            }
156    
157            public static String getDynamicDDMStructureDefinition(
158                            ClassLoader classLoader, String fileName,
159                            String dynamicDDMStructureName, Locale locale)
160                    throws Exception {
161    
162                    List<Element> structureElements = getDDMStructures(
163                            classLoader, fileName, locale);
164    
165                    for (Element structureElement : structureElements) {
166                            boolean dynamicStructure = GetterUtil.getBoolean(
167                                    structureElement.elementText("dynamic-structure"));
168    
169                            if (!dynamicStructure) {
170                                    continue;
171                            }
172    
173                            String name = structureElement.elementText("name");
174    
175                            if (!name.equals(dynamicDDMStructureName)) {
176                                    continue;
177                            }
178    
179                            Element structureElementRootElement = structureElement.element(
180                                    "root");
181    
182                            return structureElementRootElement.asXML();
183                    }
184    
185                    return null;
186            }
187    
188            protected static List<Element> getDDMStructures(
189                            ClassLoader classLoader, String fileName, Locale locale)
190                    throws Exception {
191    
192                    String xml = StringUtil.read(classLoader, fileName);
193    
194                    xml = StringUtil.replace(xml, "[$LOCALE_DEFAULT$]", locale.toString());
195    
196                    Document document = UnsecureSAXReaderUtil.read(xml);
197    
198                    Element rootElement = document.getRootElement();
199    
200                    return rootElement.elements("structure");
201            }
202    
203    }