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.upgrade.v6_2_0;
016    
017    import com.liferay.portal.kernel.log.Log;
018    import com.liferay.portal.kernel.log.LogFactoryUtil;
019    import com.liferay.portal.kernel.metadata.RawMetadataProcessor;
020    import com.liferay.portal.kernel.upgrade.UpgradeProcess;
021    import com.liferay.portal.kernel.util.ArrayUtil;
022    import com.liferay.portal.kernel.util.LoggingTimer;
023    import com.liferay.portal.kernel.util.PortalUtil;
024    import com.liferay.portal.kernel.util.StringPool;
025    import com.liferay.portal.kernel.util.StringUtil;
026    import com.liferay.portal.kernel.util.Validator;
027    import com.liferay.portal.kernel.xml.Document;
028    import com.liferay.portal.kernel.xml.Element;
029    import com.liferay.portal.kernel.xml.SAXReaderUtil;
030    import com.liferay.portal.upgrade.v6_2_0.util.DDMTemplateTable;
031    import com.liferay.util.xml.XMLUtil;
032    
033    import java.sql.PreparedStatement;
034    import java.sql.ResultSet;
035    import java.sql.SQLException;
036    
037    import java.util.List;
038    
039    /**
040     * @author Juan Fern??ndez
041     * @author Marcellus Tavares
042     */
043    public class UpgradeDynamicDataMapping extends UpgradeProcess {
044    
045            @Override
046            protected void doUpgrade() throws Exception {
047                    updateSchema();
048    
049                    updateStructures();
050                    updateStructuresClassNameId();
051    
052                    updateTemplates();
053            }
054    
055            protected void updateMetadataElement(
056                    Element metadataElement, String[] relocatedMetadadaEntryNames,
057                    String[] removedMetadataEntryNames) {
058    
059                    Element parentElement = metadataElement.getParent();
060    
061                    List<Element> entryElements = metadataElement.elements("entry");
062    
063                    for (Element entryElement : entryElements) {
064                            String name = entryElement.attributeValue("name");
065    
066                            if (ArrayUtil.contains(removedMetadataEntryNames, name)) {
067                                    metadataElement.remove(entryElement);
068                            }
069                            else if (ArrayUtil.contains(relocatedMetadadaEntryNames, name)) {
070                                    parentElement.addAttribute(name, entryElement.getText());
071    
072                                    metadataElement.remove(entryElement);
073                            }
074                    }
075            }
076    
077            protected void updateSchema() throws Exception {
078                    try (LoggingTimer loggingTimer = new LoggingTimer()) {
079                            alter(
080                                    DDMTemplateTable.class,
081                                    new AlterTableAddColumn("classNameId LONG"),
082                                    new AlterTableAddColumn("templateKey STRING"),
083                                    new AlterColumnName("structureId", "classPK LONG"));
084    
085                            long classNameId = PortalUtil.getClassNameId(
086                                    "com.liferay.portlet.dynamicdatamapping.model.DDMStructure");
087    
088                            try {
089                                    runSQL("update DDMTemplate set classNameId = " + classNameId);
090                            }
091                            catch (Exception e) {
092                                    if (_log.isWarnEnabled()) {
093                                            _log.warn(e, e);
094                                    }
095                            }
096                    }
097            }
098    
099            protected void updateStructure(
100                            long structureId, String structureKey, String xsd)
101                    throws Exception {
102    
103                    try (PreparedStatement ps = connection.prepareStatement(
104                                    "update DDMStructure set structureKey = ?, xsd = ? where " +
105                                            "structureId = ?")) {
106    
107                            ps.setString(1, structureKey);
108                            ps.setString(2, xsd);
109                            ps.setLong(3, structureId);
110    
111                            ps.executeUpdate();
112                    }
113                    catch (SQLException sqle) {
114                            if (_log.isWarnEnabled()) {
115                                    _log.warn(sqle, sqle);
116                            }
117                    }
118            }
119    
120            protected void updateStructures() throws Exception {
121                    try (LoggingTimer loggingTimer = new LoggingTimer();
122                            PreparedStatement ps = connection.prepareStatement(
123                                    "select structureId, structureKey, xsd from DDMStructure");
124                            ResultSet rs = ps.executeQuery()) {
125    
126                            while (rs.next()) {
127                                    long structureId = rs.getLong("structureId");
128                                    String structureKey = rs.getString("structureKey");
129                                    String xsd = rs.getString("xsd");
130    
131                                    if (Validator.isNull(structureKey)) {
132                                            structureKey = String.valueOf(System.currentTimeMillis());
133                                    }
134                                    else {
135                                            structureKey = StringUtil.toUpperCase(structureKey.trim());
136                                    }
137    
138                                    updateStructure(
139                                            structureId, structureKey, updateXSD(xsd, structureKey));
140                            }
141                    }
142            }
143    
144            protected void updateStructuresClassNameId() throws Exception {
145                    try (LoggingTimer loggingTimer = new LoggingTimer();
146                            PreparedStatement ps = connection.prepareStatement(
147                                    "update DDMStructure set classNameId = ? where " +
148                                            "classNameId = ?")) {
149    
150                            ps.setLong(
151                                    1,
152                                    PortalUtil.getClassNameId(
153                                            "com.liferay.portlet.documentlibrary.model." +
154                                                    "DLFileEntryMetadata"));
155                            ps.setLong(
156                                    2,
157                                    PortalUtil.getClassNameId(
158                                            "com.liferay.portlet.documentlibrary.model.DLFileEntry"));
159    
160                            ps.executeUpdate();
161                    }
162                    catch (SQLException sqle) {
163                            if (_log.isWarnEnabled()) {
164                                    _log.warn(sqle, sqle);
165                            }
166                    }
167            }
168    
169            protected void updateTemplate(
170                            long templateId, String templateKey, String script)
171                    throws Exception {
172    
173                    try (PreparedStatement ps = connection.prepareStatement(
174                                    "update DDMTemplate set templateKey = ?, script = ? where " +
175                                            "templateId = ?")) {
176    
177                            ps.setString(1, templateKey);
178                            ps.setString(2, script);
179                            ps.setLong(3, templateId);
180    
181                            ps.executeUpdate();
182                    }
183            }
184    
185            protected void updateTemplates() throws Exception {
186                    try (LoggingTimer loggingTimer = new LoggingTimer();
187                            PreparedStatement ps = connection.prepareStatement(
188                                    "select templateId, templateKey, script from DDMTemplate " +
189                                            "where language = 'xsd'");
190                            ResultSet rs = ps.executeQuery()) {
191    
192                            while (rs.next()) {
193                                    long templateId = rs.getLong("templateId");
194                                    String templateKey = rs.getString("templateKey");
195                                    String script = rs.getString("script");
196    
197                                    if (Validator.isNull(templateKey)) {
198                                            templateKey = String.valueOf(System.currentTimeMillis());
199                                    }
200                                    else {
201                                            templateKey = StringUtil.toUpperCase(templateKey.trim());
202                                    }
203    
204                                    updateTemplate(
205                                            templateId, templateKey,
206                                            updateXSD(script, StringPool.BLANK));
207                            }
208                    }
209            }
210    
211            protected String updateXSD(String xsd, String structureKey)
212                    throws Exception {
213    
214                    Document document = SAXReaderUtil.read(xsd);
215    
216                    Element rootElement = document.getRootElement();
217    
218                    List<Element> dynamicElementElements = rootElement.elements(
219                            "dynamic-element");
220    
221                    for (Element dynamicElementElement : dynamicElementElements) {
222                            updateXSDDynamicElement(dynamicElementElement, structureKey);
223                    }
224    
225                    return XMLUtil.formatXML(document);
226            }
227    
228            protected void updateXSDDynamicElement(
229                    Element element, String structureKey) {
230    
231                    Element metadataElement = element.element("meta-data");
232    
233                    updateMetadataElement(
234                            metadataElement,
235                            new String[] {
236                                    "multiple", "name", "readOnly", "repeatable", "required",
237                                    "showLabel", "type", "width"
238                            },
239                            new String[] {
240                                    "acceptFiles", "displayChildLabelAsValue", "fieldCssClass",
241                                    "folder"
242                            });
243    
244                    if (StringUtil.equalsIgnoreCase(
245                                    structureKey, RawMetadataProcessor.TIKA_RAW_METADATA)) {
246    
247                            element.addAttribute("indexType", "text");
248                    }
249    
250                    List<Element> dynamicElementElements = element.elements(
251                            "dynamic-element");
252    
253                    for (Element dynamicElementElement : dynamicElementElements) {
254                            updateXSDDynamicElement(dynamicElementElement, structureKey);
255                    }
256            }
257    
258            private static final Log _log = LogFactoryUtil.getLog(
259                    UpgradeDynamicDataMapping.class);
260    
261    }