
com.liferay.journal.internal.upgrade.v0_0_5.UpgradeJournal Maven / Gradle / Ivy
/**
* 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.journal.internal.upgrade.v0_0_5;
import com.liferay.dynamic.data.mapping.model.DDMStructure;
import com.liferay.dynamic.data.mapping.service.DDMStorageLinkLocalService;
import com.liferay.dynamic.data.mapping.service.DDMStructureLocalService;
import com.liferay.dynamic.data.mapping.service.DDMTemplateLinkLocalService;
import com.liferay.dynamic.data.mapping.util.DefaultDDMStructureHelper;
import com.liferay.journal.constants.JournalPortletKeys;
import com.liferay.journal.model.JournalArticle;
import com.liferay.petra.content.ContentUtil;
import com.liferay.petra.xml.XMLUtil;
import com.liferay.portal.kernel.model.Company;
import com.liferay.portal.kernel.model.Group;
import com.liferay.portal.kernel.model.GroupConstants;
import com.liferay.portal.kernel.security.permission.ResourceActions;
import com.liferay.portal.kernel.service.CompanyLocalService;
import com.liferay.portal.kernel.service.GroupLocalService;
import com.liferay.portal.kernel.service.ResourceActionLocalService;
import com.liferay.portal.kernel.service.ServiceContext;
import com.liferay.portal.kernel.service.UserLocalService;
import com.liferay.portal.kernel.upgrade.UpgradeProcess;
import com.liferay.portal.kernel.upgrade.util.UpgradeProcessUtil;
import com.liferay.portal.kernel.util.DateFormatFactoryUtil;
import com.liferay.portal.kernel.util.GetterUtil;
import com.liferay.portal.kernel.util.LocaleUtil;
import com.liferay.portal.kernel.util.LoggingTimer;
import com.liferay.portal.kernel.util.PortalUtil;
import com.liferay.portal.kernel.util.SetUtil;
import com.liferay.portal.kernel.util.StringBundler;
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.DocumentException;
import com.liferay.portal.kernel.xml.Element;
import com.liferay.portal.kernel.xml.SAXReaderUtil;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/**
* @author Gergely Mathe
* @author Eudaldo Alonso
*/
public class UpgradeJournal extends UpgradeProcess {
public UpgradeJournal(
CompanyLocalService companyLocalService,
DDMStorageLinkLocalService ddmStorageLinkLocalService,
DDMStructureLocalService ddmStructureLocalService,
DDMTemplateLinkLocalService ddmTemplateLinkLocalService,
DefaultDDMStructureHelper defaultDDMStructureHelper,
GroupLocalService groupLocalService,
ResourceActionLocalService resourceActionLocalService,
ResourceActions resourceActions, UserLocalService userLocalService) {
_companyLocalService = companyLocalService;
_ddmStorageLinkLocalService = ddmStorageLinkLocalService;
_ddmStructureLocalService = ddmStructureLocalService;
_ddmTemplateLinkLocalService = ddmTemplateLinkLocalService;
_defaultDDMStructureHelper = defaultDDMStructureHelper;
_groupLocalService = groupLocalService;
_resourceActionLocalService = resourceActionLocalService;
_resourceActions = resourceActions;
_userLocalService = userLocalService;
}
protected String addBasicWebContentStructureAndTemplate(long companyId)
throws Exception {
initJournalDDMCompositeModelsResourceActions();
Group group = _groupLocalService.getCompanyGroup(companyId);
long defaultUserId = _userLocalService.getDefaultUserId(companyId);
Class> clazz = getClass();
_defaultDDMStructureHelper.addDDMStructures(
defaultUserId, group.getGroupId(),
PortalUtil.getClassNameId(JournalArticle.class),
clazz.getClassLoader(),
"com/liferay/journal/internal/upgrade/v1_0_0/dependencies" +
"/basic-web-content-structure.xml",
new ServiceContext());
String defaultLanguageId = UpgradeProcessUtil.getDefaultLanguageId(
companyId);
Locale defaultLocale = LocaleUtil.fromLanguageId(defaultLanguageId);
List structureElements = getDDMStructures(defaultLocale);
Element structureElement = structureElements.get(0);
return StringUtil.toUpperCase(structureElement.elementText("name"));
}
protected void addDDMStorageLink(Map> ddmStructureIdsMap)
throws Exception {
long journalArticleClassNameId = PortalUtil.getClassNameId(
JournalArticle.class.getName());
for (Map.Entry> entry :
ddmStructureIdsMap.entrySet()) {
long ddmStructureId = getDDMStructureId(
entry.getKey(), entry.getValue());
_ddmStorageLinkLocalService.addStorageLink(
journalArticleClassNameId, entry.getKey(), ddmStructureId,
new ServiceContext());
}
}
protected void addDDMStorageLinks() throws Exception {
try (LoggingTimer loggingTimer = new LoggingTimer()) {
StringBundler sb = new StringBundler(8);
sb.append("select DDMStructure.structureId, JournalArticle.id_ ");
sb.append("from JournalArticle inner join DDMStructure on (");
sb.append("DDMStructure.groupId in (select distinct Group_.");
sb.append("groupId from Group_ where (Group_.groupId = ");
sb.append("JournalArticle.groupId) or (Group_.companyId = ");
sb.append("JournalArticle.companyId and Group_.friendlyURL = ?)) ");
sb.append("and DDMStructure.structureKey = JournalArticle.");
sb.append("DDMStructureKey and JournalArticle.classNameId != ?)");
try (PreparedStatement ps =
connection.prepareStatement(sb.toString())) {
ps.setString(1, GroupConstants.GLOBAL_FRIENDLY_URL);
ps.setLong(
2, PortalUtil.getClassNameId(DDMStructure.class.getName()));
try (ResultSet rs = ps.executeQuery()) {
Map> ddmStructureIdsMap = new HashMap<>();
while (rs.next()) {
long structureId = rs.getLong("structureId");
long id = rs.getLong("id_");
List ddmStructureIds = ddmStructureIdsMap.get(id);
if (ddmStructureIds == null) {
ddmStructureIds = new ArrayList<>();
}
ddmStructureIds.add(structureId);
ddmStructureIdsMap.put(id, ddmStructureIds);
}
addDDMStorageLink(ddmStructureIdsMap);
}
}
}
}
protected void addDDMTemplateLinks() throws Exception {
try (LoggingTimer loggingTimer = new LoggingTimer()) {
long classNameId = PortalUtil.getClassNameId(
DDMStructure.class.getName());
StringBundler sb = new StringBundler(6);
sb.append("select DDMTemplate.templateId, JournalArticle.id_ ");
sb.append("from JournalArticle inner join DDMTemplate on (");
sb.append("DDMTemplate.groupId = JournalArticle.groupId and ");
sb.append("DDMTemplate.templateKey = ");
sb.append("JournalArticle.DDMTemplateKey and ");
sb.append("JournalArticle.classNameId != ?)");
try (PreparedStatement ps = connection.prepareStatement(
sb.toString())) {
ps.setLong(1, classNameId);
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
long templateId = rs.getLong("templateId");
long id = rs.getLong("id_");
_ddmTemplateLinkLocalService.addTemplateLink(
classNameId, id, templateId);
}
}
}
}
}
protected boolean containsDateFieldType(String content) {
if (content.indexOf(_TYPE_ATTRIBUTE_DDM_DATE) != -1) {
return true;
}
return false;
}
protected String convertStaticContentToDynamic(String content)
throws Exception {
Document document = SAXReaderUtil.read(content);
Document newDocument = SAXReaderUtil.createDocument();
Element rootElement = document.getRootElement();
String availableLocales = rootElement.attributeValue(
"available-locales");
String defaultLocale = rootElement.attributeValue("default-locale");
Element newRootElement = SAXReaderUtil.createElement("root");
newRootElement.addAttribute("available-locales", availableLocales);
newRootElement.addAttribute("default-locale", defaultLocale);
newDocument.add(newRootElement);
Element dynamicElementElement = SAXReaderUtil.createElement(
"dynamic-element");
dynamicElementElement.addAttribute("name", "content");
dynamicElementElement.addAttribute("type", "text_area");
dynamicElementElement.addAttribute("index-type", "keyword");
dynamicElementElement.addAttribute("index", String.valueOf(0));
newRootElement.add(dynamicElementElement);
List staticContentElements = rootElement.elements(
"static-content");
for (Element staticContentElement : staticContentElements) {
String languageId = staticContentElement.attributeValue(
"language-id");
String text = staticContentElement.getText();
Element dynamicContentElement = SAXReaderUtil.createElement(
"dynamic-content");
dynamicContentElement.addAttribute("language-id", languageId);
dynamicContentElement.addCDATA(text);
dynamicElementElement.add(dynamicContentElement);
}
return XMLUtil.formatXML(newDocument);
}
@Override
protected void doUpgrade() throws Exception {
updateJournalArticles();
addDDMStorageLinks();
addDDMTemplateLinks();
}
protected Set getArticleDynamicElements(Element rootElement) {
List dynamicElementNames = new ArrayList<>();
List dynamicElementElements = rootElement.elements(
"dynamic-element");
for (Element element : dynamicElementElements) {
dynamicElementNames.add(element.attributeValue("name"));
dynamicElementNames.addAll(getArticleDynamicElements(element));
}
return SetUtil.fromList(dynamicElementNames);
}
protected Set getArticleFieldNames(long articleId)
throws Exception {
Set articleFieldNames = new HashSet<>();
try (LoggingTimer loggingTimer = new LoggingTimer()) {
String sql =
"select JournalArticle.content from JournalArticle where " +
"JournalArticle.id_ = ?";
try (PreparedStatement ps = connection.prepareStatement(sql)) {
ps.setLong(1, articleId);
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) {
String content = rs.getString("content");
Document document = SAXReaderUtil.read(content);
Element rootElement = document.getRootElement();
articleFieldNames = getArticleDynamicElements(
rootElement);
}
}
}
}
return articleFieldNames;
}
protected long getBestDDMStructureIdMatch(
long id, long ddmStructureId1, long ddmStructureId2)
throws Exception {
DDMStructure ddmStructure1 = _ddmStructureLocalService.getStructure(
ddmStructureId1);
Set fieldNames1 = ddmStructure1.getFieldNames();
Set articleFieldNames = getArticleFieldNames(id);
fieldNames1.removeAll(articleFieldNames);
DDMStructure ddmStructure2 = _ddmStructureLocalService.getStructure(
ddmStructureId2);
Set fieldNames2 = ddmStructure2.getFieldNames();
fieldNames2.removeAll(articleFieldNames);
if (fieldNames1.size() <= fieldNames2.size()) {
return ddmStructure1.getStructureId();
}
return ddmStructure2.getStructureId();
}
protected String getContent(String fileName) {
Class> clazz = getClass();
return ContentUtil.get(
clazz.getClassLoader(),
"com/liferay/journal/internal/upgrade/v1_0_0/dependencies/" +
fileName);
}
protected long getDDMStructureId(long id, List ddmStructureIds)
throws Exception {
if (ddmStructureIds.size() == 1) {
return ddmStructureIds.get(0);
}
return getBestDDMStructureIdMatch(
id, ddmStructureIds.get(0), ddmStructureIds.get(1));
}
protected List getDDMStructures(Locale locale)
throws DocumentException {
String xml = getContent("basic-web-content-structure.xml");
xml = StringUtil.replace(xml, "[$LOCALE_DEFAULT$]", locale.toString());
Document document = SAXReaderUtil.read(xml);
Element rootElement = document.getRootElement();
return rootElement.elements("structure");
}
protected Map getInvalidDDMFormFieldNamesMap(
String content) {
Map invalidDDMFormFieldNamesMap = new HashMap<>();
Matcher matcher = _nameAttributePattern.matcher(content);
while (matcher.find()) {
String oldFieldName = matcher.group(1);
String newFieldName = oldFieldName.replaceAll(
_INVALID_FIELD_NAME_CHARS_REGEX, StringPool.BLANK);
if (!oldFieldName.equals(newFieldName)) {
invalidDDMFormFieldNamesMap.put(oldFieldName, newFieldName);
}
}
return invalidDDMFormFieldNamesMap;
}
protected void initJournalDDMCompositeModelsResourceActions()
throws Exception {
_resourceActions.read(
null, UpgradeJournal.class.getClassLoader(),
"/META-INF/resource-actions/journal_ddm_composite_models.xml");
List modelNames = _resourceActions.getPortletModelResources(
JournalPortletKeys.JOURNAL);
for (String modelName : modelNames) {
List modelActions =
_resourceActions.getModelResourceActions(modelName);
_resourceActionLocalService.checkResourceActions(
modelName, modelActions);
}
}
protected void transformDateFieldValue(Element dynamicContentElement) {
String value = dynamicContentElement.getText();
if (!Validator.isNumber(value)) {
return;
}
Date date = new Date(GetterUtil.getLong(value));
dynamicContentElement.clearContent();
dynamicContentElement.addCDATA(_dateFormat.format(date));
}
protected void transformDateFieldValues(
List dynamicElementElements) {
if ((dynamicElementElements == null) ||
dynamicElementElements.isEmpty()) {
return;
}
for (Element dynamicElementElement : dynamicElementElements) {
String type = GetterUtil.getString(
dynamicElementElement.attributeValue("type"));
if (type.equals("ddm-date")) {
List dynamicContentElements =
dynamicElementElement.elements("dynamic-content");
for (Element dynamicContentElement : dynamicContentElements) {
transformDateFieldValue(dynamicContentElement);
}
}
List childDynamicElementElements =
dynamicElementElement.elements("dynamic-element");
transformDateFieldValues(childDynamicElementElements);
}
}
protected String transformDateFieldValues(String content) throws Exception {
if (!containsDateFieldType(content)) {
return content;
}
Document document = SAXReaderUtil.read(content);
Element rootElement = document.getRootElement();
List dynamicElementElements = rootElement.elements(
"dynamic-element");
transformDateFieldValues(dynamicElementElements);
return XMLUtil.formatXML(document);
}
protected String transformFieldNames(String content) {
Map invalidDDMFormFieldNamesMap =
getInvalidDDMFormFieldNamesMap(content);
for (Map.Entry entry :
invalidDDMFormFieldNamesMap.entrySet()) {
content = StringUtil.replace(
content, entry.getKey(), entry.getValue());
}
return content;
}
protected void updateJournalArticle(
long id, String ddmStructureKey, String ddmTemplateKey,
String content)
throws Exception {
try (PreparedStatement ps = connection.prepareStatement(
"update JournalArticle set DDMStructureKey = ?, " +
"DDMTemplateKey = ?, content = ? where id_ = ?")) {
ps.setString(1, ddmStructureKey);
ps.setString(2, ddmTemplateKey);
ps.setString(3, content);
ps.setLong(4, id);
ps.executeUpdate();
}
}
protected void updateJournalArticleContent(long id, String content)
throws Exception {
try (PreparedStatement ps = connection.prepareStatement(
"update JournalArticle set content = ? where id_ = ?")) {
ps.setString(1, content);
ps.setLong(2, id);
ps.executeUpdate();
}
}
protected void updateJournalArticles() throws Exception {
try (LoggingTimer loggingTimer = new LoggingTimer()) {
List companies = _companyLocalService.getCompanies();
for (Company company : companies) {
updateJournalArticles(company.getCompanyId());
}
}
}
protected void updateJournalArticles(long companyId) throws Exception {
try (PreparedStatement ps = connection.prepareStatement(
"select id_, content, DDMStructureKey from " +
"JournalArticle where companyId = " + companyId);
ResultSet rs = ps.executeQuery()) {
String name = addBasicWebContentStructureAndTemplate(companyId);
while (rs.next()) {
long id = rs.getLong("id_");
String content = rs.getString("content");
String ddmStructureKey = rs.getString("DDMStructureKey");
if (Validator.isNull(ddmStructureKey)) {
content = convertStaticContentToDynamic(content);
updateJournalArticle(id, name, name, content);
continue;
}
String updatedContent = transformDateFieldValues(content);
updatedContent = transformFieldNames(updatedContent);
if (!content.equals(updatedContent)) {
updateJournalArticleContent(id, updatedContent);
}
}
}
}
private static final String _INVALID_FIELD_NAME_CHARS_REGEX =
"([\\p{Punct}&&[^_]]|\\p{Space})+";
private static final String _TYPE_ATTRIBUTE_DDM_DATE = "type=\"ddm-date\"";
private static final DateFormat _dateFormat =
DateFormatFactoryUtil.getSimpleDateFormat("yyyy-MM-dd");
private final CompanyLocalService _companyLocalService;
private final DDMStorageLinkLocalService _ddmStorageLinkLocalService;
private final DDMStructureLocalService _ddmStructureLocalService;
private final DDMTemplateLinkLocalService _ddmTemplateLinkLocalService;
private final DefaultDDMStructureHelper _defaultDDMStructureHelper;
private final GroupLocalService _groupLocalService;
private final Pattern _nameAttributePattern = Pattern.compile(
"name=\"([^\"]+)\"");
private final ResourceActionLocalService _resourceActionLocalService;
private final ResourceActions _resourceActions;
private final UserLocalService _userLocalService;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy