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