/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portal.upgrade.v6_2_0; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import com.liferay.portal.kernel.metadata.RawMetadataProcessor; import com.liferay.portal.kernel.upgrade.UpgradeProcess; import com.liferay.portal.kernel.util.ArrayUtil; import com.liferay.portal.kernel.util.LoggingTimer; import com.liferay.portal.kernel.util.PortalUtil; import com.liferay.portal.kernel.util.StringPool; import com.liferay.portal.kernel.util.StringUtil; import com.liferay.portal.kernel.util.Validator; import com.liferay.portal.kernel.xml.Document; import com.liferay.portal.kernel.xml.Element; import com.liferay.portal.kernel.xml.SAXReaderUtil; import com.liferay.portal.upgrade.v6_2_0.util.DDMTemplateTable; import com.liferay.util.xml.XMLUtil; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; /** * @author Juan Fernández * @author Marcellus Tavares */ public class UpgradeDynamicDataMapping extends UpgradeProcess { @Override protected void doUpgrade() throws Exception { updateSchema(); updateStructures(); updateStructuresClassNameId(); updateTemplates(); } protected void updateMetadataElement( Element metadataElement, String[] relocatedMetadadaEntryNames, String[] removedMetadataEntryNames) { Element parentElement = metadataElement.getParent(); List<Element> entryElements = metadataElement.elements("entry"); for (Element entryElement : entryElements) { String name = entryElement.attributeValue("name"); if (ArrayUtil.contains(removedMetadataEntryNames, name)) { metadataElement.remove(entryElement); } else if (ArrayUtil.contains(relocatedMetadadaEntryNames, name)) { parentElement.addAttribute(name, entryElement.getText()); metadataElement.remove(entryElement); } } } protected void updateSchema() throws Exception { try (LoggingTimer loggingTimer = new LoggingTimer()) { alter( DDMTemplateTable.class, new AlterTableAddColumn("classNameId LONG"), new AlterTableAddColumn("templateKey STRING"), new AlterColumnName("structureId", "classPK LONG")); long classNameId = PortalUtil.getClassNameId( "com.liferay.portlet.dynamicdatamapping.model.DDMStructure"); try { runSQL("update DDMTemplate set classNameId = " + classNameId); } catch (Exception e) { if (_log.isWarnEnabled()) { _log.warn(e, e); } } } } protected void updateStructure( long structureId, String structureKey, String xsd) throws Exception { try (PreparedStatement ps = connection.prepareStatement( "update DDMStructure set structureKey = ?, xsd = ? where " + "structureId = ?")) { ps.setString(1, structureKey); ps.setString(2, xsd); ps.setLong(3, structureId); ps.executeUpdate(); } catch (SQLException sqle) { if (_log.isWarnEnabled()) { _log.warn(sqle, sqle); } } } protected void updateStructures() throws Exception { try (LoggingTimer loggingTimer = new LoggingTimer(); PreparedStatement ps = connection.prepareStatement( "select structureId, structureKey, xsd from DDMStructure"); ResultSet rs = ps.executeQuery()) { while (rs.next()) { long structureId = rs.getLong("structureId"); String structureKey = rs.getString("structureKey"); String xsd = rs.getString("xsd"); if (Validator.isNull(structureKey)) { structureKey = String.valueOf(System.currentTimeMillis()); } else { structureKey = StringUtil.toUpperCase(structureKey.trim()); } updateStructure( structureId, structureKey, updateXSD(xsd, structureKey)); } } } protected void updateStructuresClassNameId() throws Exception { try (LoggingTimer loggingTimer = new LoggingTimer(); PreparedStatement ps = connection.prepareStatement( "update DDMStructure set classNameId = ? where classNameId = " + "?")) { ps.setLong( 1, PortalUtil.getClassNameId( "com.liferay.portlet.documentlibrary.model." + "DLFileEntryMetadata")); ps.setLong( 2, PortalUtil.getClassNameId( "com.liferay.portlet.documentlibrary.model.DLFileEntry")); ps.executeUpdate(); } catch (SQLException sqle) { if (_log.isWarnEnabled()) { _log.warn(sqle, sqle); } } } protected void updateTemplate( long templateId, String templateKey, String script) throws Exception { try (PreparedStatement ps = connection.prepareStatement( "update DDMTemplate set templateKey = ?, script = ? where " + "templateId = ?")) { ps.setString(1, templateKey); ps.setString(2, script); ps.setLong(3, templateId); ps.executeUpdate(); } } protected void updateTemplates() throws Exception { try (LoggingTimer loggingTimer = new LoggingTimer(); PreparedStatement ps = connection.prepareStatement( "select templateId, templateKey, script from DDMTemplate " + "where language = 'xsd'"); ResultSet rs = ps.executeQuery()) { while (rs.next()) { long templateId = rs.getLong("templateId"); String templateKey = rs.getString("templateKey"); String script = rs.getString("script"); if (Validator.isNull(templateKey)) { templateKey = String.valueOf(System.currentTimeMillis()); } else { templateKey = StringUtil.toUpperCase(templateKey.trim()); } updateTemplate( templateId, templateKey, updateXSD(script, StringPool.BLANK)); } } } protected String updateXSD(String xsd, String structureKey) throws Exception { Document document = SAXReaderUtil.read(xsd); Element rootElement = document.getRootElement(); List<Element> dynamicElementElements = rootElement.elements( "dynamic-element"); for (Element dynamicElementElement : dynamicElementElements) { updateXSDDynamicElement(dynamicElementElement, structureKey); } return XMLUtil.formatXML(document); } protected void updateXSDDynamicElement( Element element, String structureKey) { Element metadataElement = element.element("meta-data"); updateMetadataElement( metadataElement, new String[] { "multiple", "name", "readOnly", "repeatable", "required", "showLabel", "type", "width" }, new String[] { "acceptFiles", "displayChildLabelAsValue", "fieldCssClass", "folder" }); if (StringUtil.equalsIgnoreCase( structureKey, RawMetadataProcessor.TIKA_RAW_METADATA)) { element.addAttribute("indexType", "text"); } List<Element> dynamicElementElements = element.elements( "dynamic-element"); for (Element dynamicElementElement : dynamicElementElements) { updateXSDDynamicElement(dynamicElementElement, structureKey); } } private static final Log _log = LogFactoryUtil.getLog( UpgradeDynamicDataMapping.class); }