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