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.events;
016    
017    import com.liferay.portal.kernel.events.ActionException;
018    import com.liferay.portal.kernel.events.SimpleAction;
019    import com.liferay.portal.kernel.language.LanguageUtil;
020    import com.liferay.portal.kernel.metadata.RawMetadataProcessorUtil;
021    import com.liferay.portal.kernel.upgrade.util.UpgradeProcessUtil;
022    import com.liferay.portal.kernel.util.ArrayUtil;
023    import com.liferay.portal.kernel.util.GetterUtil;
024    import com.liferay.portal.kernel.util.LocaleUtil;
025    import com.liferay.portal.kernel.util.StringBundler;
026    import com.liferay.portal.kernel.util.StringPool;
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.model.Group;
031    import com.liferay.portal.service.GroupLocalServiceUtil;
032    import com.liferay.portal.service.ServiceContext;
033    import com.liferay.portal.service.UserLocalServiceUtil;
034    import com.liferay.portal.util.PortalUtil;
035    import com.liferay.portlet.documentlibrary.NoSuchFileEntryTypeException;
036    import com.liferay.portlet.documentlibrary.model.DLFileEntryMetadata;
037    import com.liferay.portlet.documentlibrary.model.DLFileEntryTypeConstants;
038    import com.liferay.portlet.documentlibrary.service.DLFileEntryTypeLocalServiceUtil;
039    import com.liferay.portlet.documentlibrary.util.RawMetadataProcessor;
040    import com.liferay.portlet.dynamicdatamapping.io.DDMFormXSDDeserializerUtil;
041    import com.liferay.portlet.dynamicdatamapping.model.DDMForm;
042    import com.liferay.portlet.dynamicdatamapping.model.DDMFormLayout;
043    import com.liferay.portlet.dynamicdatamapping.model.DDMStructure;
044    import com.liferay.portlet.dynamicdatamapping.model.DDMStructureConstants;
045    import com.liferay.portlet.dynamicdatamapping.service.DDMStructureLocalServiceUtil;
046    import com.liferay.portlet.dynamicdatamapping.storage.StorageType;
047    import com.liferay.portlet.dynamicdatamapping.util.DDMUtil;
048    import com.liferay.portlet.dynamicdatamapping.util.DefaultDDMStructureUtil;
049    
050    import java.io.StringReader;
051    
052    import java.lang.reflect.Field;
053    
054    import java.util.ArrayList;
055    import java.util.HashMap;
056    import java.util.List;
057    import java.util.Locale;
058    import java.util.Map;
059    
060    /**
061     * @author Sergio Gonz??lez
062     * @author Miguel Pastor
063     * @author Roberto D??az
064     */
065    public class AddDefaultDocumentLibraryStructuresAction extends SimpleAction {
066    
067            @Override
068            public void run(String[] ids) throws ActionException {
069                    try {
070                            doRun(GetterUtil.getLong(ids[0]));
071                    }
072                    catch (Exception e) {
073                            throw new ActionException(e);
074                    }
075            }
076    
077            protected void addDLFileEntryType(
078                            long userId, long groupId, String languageKey,
079                            String dlFileEntryTypeKey, List<String> ddmStructureNames,
080                            ServiceContext serviceContext)
081                    throws Exception {
082    
083                    List<Long> ddmStructureIds = new ArrayList<>();
084    
085                    for (String ddmStructureName : ddmStructureNames) {
086                            String ddmStructureKey = ddmStructureName;
087    
088                            DDMStructure ddmStructure =
089                                    DDMStructureLocalServiceUtil.fetchStructure(
090                                            groupId,
091                                            PortalUtil.getClassNameId(DLFileEntryMetadata.class),
092                                            ddmStructureKey);
093    
094                            if (ddmStructure == null) {
095                                    continue;
096                            }
097    
098                            ddmStructureIds.add(ddmStructure.getStructureId());
099                    }
100    
101                    Locale locale = PortalUtil.getSiteDefaultLocale(groupId);
102    
103                    String definition =
104                            DefaultDDMStructureUtil.getDynamicDDMStructureDefinition(
105                                    AddDefaultDocumentLibraryStructuresAction.class.
106                                            getClassLoader(),
107                                    "com/liferay/portal/events/dependencies" +
108                                            "/document-library-structures.xml",
109                                    languageKey, locale);
110    
111                    DDMForm ddmForm = DDMFormXSDDeserializerUtil.deserialize(definition);
112    
113                    serviceContext.setAttribute("ddmForm", ddmForm);
114    
115                    try {
116                            DLFileEntryTypeLocalServiceUtil.getFileEntryType(
117                                    groupId, dlFileEntryTypeKey);
118                    }
119                    catch (NoSuchFileEntryTypeException nsfete) {
120                            Map<Locale, String> localizationMap = getLocalizationMap(
121                                    languageKey);
122    
123                            DLFileEntryTypeLocalServiceUtil.addFileEntryType(
124                                    userId, groupId, dlFileEntryTypeKey, localizationMap,
125                                    localizationMap,
126                                    ArrayUtil.toArray(
127                                            ddmStructureIds.toArray(new Long[ddmStructureIds.size()])),
128                                    serviceContext);
129                    }
130            }
131    
132            protected void addDLFileEntryTypes(
133                            long userId, long groupId, ServiceContext serviceContext)
134                    throws Exception {
135    
136                    List<String> ddmStructureNames = new ArrayList<>();
137    
138                    addDLFileEntryType(
139                            userId, groupId, DLFileEntryTypeConstants.NAME_CONTRACT,
140                            DLFileEntryTypeConstants.FILE_ENTRY_TYPE_KEY_CONTRACT,
141                            ddmStructureNames, serviceContext);
142    
143                    ddmStructureNames.clear();
144    
145                    ddmStructureNames.add("Marketing Campaign Theme Metadata");
146    
147                    addDLFileEntryType(
148                            userId, groupId, DLFileEntryTypeConstants.NAME_MARKETING_BANNER,
149                            DLFileEntryTypeConstants.FILE_ENTRY_TYPE_KEY_MARKETING_BANNER,
150                            ddmStructureNames, serviceContext);
151    
152                    ddmStructureNames.clear();
153    
154                    ddmStructureNames.add("Learning Module Metadata");
155    
156                    addDLFileEntryType(
157                            userId, groupId, DLFileEntryTypeConstants.NAME_ONLINE_TRAINING,
158                            DLFileEntryTypeConstants.FILE_ENTRY_TYPE_KEY_ONLINE_TRAINING,
159                            ddmStructureNames, serviceContext);
160    
161                    ddmStructureNames.clear();
162    
163                    ddmStructureNames.add("Meeting Metadata");
164    
165                    addDLFileEntryType(
166                            userId, groupId, DLFileEntryTypeConstants.NAME_SALES_PRESENTATION,
167                            DLFileEntryTypeConstants.FILE_ENTRY_TYPE_KEY_SALES_PRESENTATION,
168                            ddmStructureNames, serviceContext);
169    
170                    if (UpgradeProcessUtil.isCreateIGImageDocumentType()) {
171                            addDLFileEntryType(
172                                    userId, groupId, DLFileEntryTypeConstants.NAME_IG_IMAGE,
173                                    DLFileEntryTypeConstants.FILE_ENTRY_TYPE_KEY_IG_IMAGE,
174                                    ddmStructureNames, serviceContext);
175                    }
176            }
177    
178            protected void addDLRawMetadataStructures(
179                            long userId, long groupId, ServiceContext serviceContext)
180                    throws Exception {
181    
182                    Locale locale = PortalUtil.getSiteDefaultLocale(groupId);
183    
184                    String xsd = buildDLRawMetadataXML(
185                            RawMetadataProcessorUtil.getFields(), locale);
186    
187                    Document document = UnsecureSAXReaderUtil.read(new StringReader(xsd));
188    
189                    Element rootElement = document.getRootElement();
190    
191                    List<Element> structureElements = rootElement.elements("structure");
192    
193                    for (Element structureElement : structureElements) {
194                            String name = structureElement.elementText("name");
195                            String description = structureElement.elementText("description");
196    
197                            Element structureElementRootElement = structureElement.element(
198                                    "root");
199    
200                            String structureElementRootXML =
201                                    structureElementRootElement.asXML();
202    
203                            DDMStructure ddmStructure =
204                                    DDMStructureLocalServiceUtil.fetchStructure(
205                                            groupId,
206                                            PortalUtil.getClassNameId(RawMetadataProcessor.class),
207                                            name);
208    
209                            DDMForm ddmForm = DDMFormXSDDeserializerUtil.deserialize(
210                                    structureElementRootXML);
211    
212                            if (ddmStructure != null) {
213                                    ddmStructure.setDDMForm(ddmForm);
214    
215                                    DDMStructureLocalServiceUtil.updateDDMStructure(ddmStructure);
216                            }
217                            else {
218                                    Map<Locale, String> nameMap = new HashMap<>();
219    
220                                    nameMap.put(locale, name);
221    
222                                    Map<Locale, String> descriptionMap = new HashMap<>();
223    
224                                    descriptionMap.put(locale, description);
225    
226                                    DDMFormLayout ddmFormLayout = DDMUtil.getDefaultDDMFormLayout(
227                                            ddmForm);
228    
229                                    DDMStructureLocalServiceUtil.addStructure(
230                                            userId, groupId,
231                                            DDMStructureConstants.DEFAULT_PARENT_STRUCTURE_ID,
232                                            PortalUtil.getClassNameId(RawMetadataProcessor.class), name,
233                                            nameMap, descriptionMap, ddmForm, ddmFormLayout,
234                                            StorageType.JSON.toString(),
235                                            DDMStructureConstants.TYPE_DEFAULT, serviceContext);
236                            }
237                    }
238            }
239    
240            protected String buildDLRawMetadataElementXML(Field field, Locale locale) {
241                    StringBundler sb = new StringBundler(15);
242    
243                    sb.append("<dynamic-element dataType=\"string\" indexType=\"text\" ");
244                    sb.append("name=\"");
245    
246                    Class<?> fieldClass = field.getDeclaringClass();
247    
248                    sb.append(fieldClass.getSimpleName());
249                    sb.append(StringPool.UNDERLINE);
250                    sb.append(field.getName());
251                    sb.append("\" required=\"false\" showLabel=\"true\" type=\"text\">");
252                    sb.append("<meta-data locale=\"");
253                    sb.append(locale);
254                    sb.append("\">");
255                    sb.append("<entry name=\"label\"><![CDATA[metadata.");
256                    sb.append(fieldClass.getSimpleName());
257                    sb.append(StringPool.PERIOD);
258                    sb.append(field.getName());
259                    sb.append("]]></entry><entry name=\"predefinedValue\">");
260                    sb.append("<![CDATA[]]></entry></meta-data></dynamic-element>");
261    
262                    return sb.toString();
263            }
264    
265            protected String buildDLRawMetadataStructureXML(
266                    String name, Field[] fields, Locale locale) {
267    
268                    StringBundler sb = new StringBundler(12 + fields.length);
269    
270                    sb.append("<structure><name><![CDATA[");
271                    sb.append(name);
272                    sb.append("]]></name>");
273                    sb.append("<description><![CDATA[");
274                    sb.append(name);
275                    sb.append("]]></description>");
276                    sb.append("<root available-locales=\"");
277                    sb.append(locale);
278                    sb.append("\" default-locale=\"");
279                    sb.append(locale);
280                    sb.append("\">");
281    
282                    for (Field field : fields) {
283                            sb.append(buildDLRawMetadataElementXML(field, locale));
284                    }
285    
286                    sb.append("</root></structure>");
287    
288                    return sb.toString();
289            }
290    
291            protected String buildDLRawMetadataXML(
292                    Map<String, Field[]> fields, Locale locale) {
293    
294                    StringBundler sb = new StringBundler(2 + fields.size());
295    
296                    sb.append("<?xml version=\"1.0\"?><root>");
297    
298                    for (String key : fields.keySet()) {
299                            sb.append(
300                                    buildDLRawMetadataStructureXML(key, fields.get(key), locale));
301                    }
302    
303                    sb.append("</root>");
304    
305                    return sb.toString();
306            }
307    
308            protected void doRun(long companyId) throws Exception {
309                    ServiceContext serviceContext = new ServiceContext();
310    
311                    serviceContext.setAddGuestPermissions(true);
312                    serviceContext.setAddGroupPermissions(true);
313    
314                    Group group = GroupLocalServiceUtil.getCompanyGroup(companyId);
315    
316                    serviceContext.setScopeGroupId(group.getGroupId());
317    
318                    long defaultUserId = UserLocalServiceUtil.getDefaultUserId(companyId);
319    
320                    serviceContext.setUserId(defaultUserId);
321    
322                    DefaultDDMStructureUtil.addDDMStructures(
323                            defaultUserId, group.getGroupId(),
324                            PortalUtil.getClassNameId(DLFileEntryMetadata.class),
325                            AddDefaultDocumentLibraryStructuresAction.class.getClassLoader(),
326                            "com/liferay/portal/events/dependencies" +
327                                    "/document-library-structures.xml",
328                            serviceContext);
329                    addDLFileEntryTypes(defaultUserId, group.getGroupId(), serviceContext);
330                    addDLRawMetadataStructures(
331                            defaultUserId, group.getGroupId(), serviceContext);
332            }
333    
334            protected Map<Locale, String> getLocalizationMap(String content) {
335                    Map<Locale, String> localizationMap = new HashMap<>();
336    
337                    Locale defaultLocale = LocaleUtil.getDefault();
338    
339                    String defaultValue = LanguageUtil.get(defaultLocale, content);
340    
341                    for (Locale locale : LanguageUtil.getSupportedLocales()) {
342                            String value = LanguageUtil.get(locale, content);
343    
344                            if (!locale.equals(defaultLocale) && value.equals(defaultValue)) {
345                                    continue;
346                            }
347    
348                            localizationMap.put(locale, value);
349                    }
350    
351                    return localizationMap;
352            }
353    
354    }