
com.liferay.dynamic.data.mapping.util.impl.DDMXMLImpl Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of com.liferay.dynamic.data.mapping.service Show documentation
Show all versions of com.liferay.dynamic.data.mapping.service Show documentation
Liferay Dynamic Data Mapping Service
/**
* 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.dynamic.data.mapping.util.impl;
import com.liferay.dynamic.data.mapping.exception.StructureDefinitionException;
import com.liferay.dynamic.data.mapping.exception.StructureDuplicateElementException;
import com.liferay.dynamic.data.mapping.model.DDMStructure;
import com.liferay.dynamic.data.mapping.model.DDMStructureConstants;
import com.liferay.dynamic.data.mapping.storage.Field;
import com.liferay.dynamic.data.mapping.storage.FieldConstants;
import com.liferay.dynamic.data.mapping.storage.Fields;
import com.liferay.dynamic.data.mapping.util.DDMXML;
import com.liferay.portal.kernel.exception.PortalException;
import com.liferay.portal.kernel.exception.SystemException;
import com.liferay.portal.kernel.log.Log;
import com.liferay.portal.kernel.log.LogFactoryUtil;
import com.liferay.portal.kernel.security.pacl.DoPrivileged;
import com.liferay.portal.kernel.util.HtmlUtil;
import com.liferay.portal.kernel.util.LocaleUtil;
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.Node;
import com.liferay.portal.kernel.xml.SAXReader;
import com.liferay.portal.kernel.xml.XMLSchema;
import com.liferay.portal.kernel.xml.XPath;
import com.liferay.portal.xml.XMLSchemaImpl;
import java.io.IOException;
import java.io.Serializable;
import java.util.Date;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Reference;
/**
* @author Bruno Basto
* @author Brian Wing Shun Chan
*/
@Component(immediate = true)
@DoPrivileged
public class DDMXMLImpl implements DDMXML {
@Override
public Fields getFields(DDMStructure structure, String xml)
throws PortalException {
return getFields(structure, null, xml, null);
}
@Override
public Fields getFields(
DDMStructure structure, XPath xPath, String xml,
List fieldNames)
throws PortalException {
Document document = null;
try {
document = _saxReader.read(xml);
}
catch (DocumentException de) {
if (_log.isDebugEnabled()) {
_log.debug(de.getMessage(), de);
}
return null;
}
if ((xPath != null) && !xPath.booleanValueOf(document)) {
return null;
}
Fields fields = new Fields();
Element rootElement = document.getRootElement();
List dynamicElementElements = rootElement.elements(
"dynamic-element");
for (Element dynamicElementElement : dynamicElementElements) {
String fieldName = dynamicElementElement.attributeValue("name");
if (!structure.hasField(fieldName) ||
((fieldNames != null) && !fieldNames.contains(fieldName))) {
continue;
}
String fieldDataType = structure.getFieldDataType(fieldName);
List dynamicContentElements =
dynamicElementElement.elements("dynamic-content");
for (Element dynamicContentElement : dynamicContentElements) {
String fieldValue = dynamicContentElement.getText();
String languageId = dynamicContentElement.attributeValue(
"language-id");
Locale locale = LocaleUtil.fromLanguageId(languageId);
Serializable fieldValueSerializable =
FieldConstants.getSerializable(fieldDataType, fieldValue);
Field field = fields.get(fieldName);
if (field == null) {
field = new Field();
String defaultLanguageId =
dynamicElementElement.attributeValue(
"default-language-id");
if (Validator.isNull(defaultLanguageId)) {
defaultLanguageId = rootElement.attributeValue(
"default-locale");
}
Locale defaultLocale = LocaleUtil.fromLanguageId(
defaultLanguageId);
field.setDefaultLocale(defaultLocale);
field.setDDMStructureId(structure.getStructureId());
field.setName(fieldName);
field.setValue(locale, fieldValueSerializable);
fields.put(field);
}
else {
field.addValue(locale, fieldValueSerializable);
}
}
}
return fields;
}
@Override
public String getXML(Document document, Fields fields) {
Element rootElement = null;
try {
if (document != null) {
rootElement = document.getRootElement();
}
else {
document = _saxReader.createDocument();
rootElement = document.addElement("root");
}
Iterator itr = fields.iterator(true);
while (itr.hasNext()) {
Field field = itr.next();
List nodes = getElementsByName(document, field.getName());
for (Node node : nodes) {
document.remove(node);
}
appendField(rootElement, field);
}
return document.formattedString();
}
catch (IOException ioe) {
throw new SystemException(ioe);
}
}
@Override
public String getXML(Fields fields) {
return getXML(null, fields);
}
public XMLSchema getXMLSchema() {
if (_xmlSchema == null) {
XMLSchemaImpl xmlSchema = new XMLSchemaImpl();
xmlSchema.setSchemaLanguage("http://www.w3.org/2001/XMLSchema");
xmlSchema.setSystemId(
"http://www.liferay.com/dtd/liferay-ddm-structure_6_2_0.xsd");
_xmlSchema = xmlSchema;
}
return _xmlSchema;
}
@Override
public String validateXML(String xml) throws PortalException {
try {
Document document = _saxReader.read(xml, getXMLSchema());
validate(document);
return document.asXML();
}
catch (StructureDefinitionException sde) {
throw sde;
}
catch (StructureDuplicateElementException sdee) {
throw sdee;
}
catch (Exception e) {
if (_log.isDebugEnabled()) {
_log.debug("Invalid XML content " + e.getMessage(), e);
}
throw new StructureDefinitionException(e);
}
}
protected void appendField(Element element, Field field) {
Element dynamicElementElement = element.addElement("dynamic-element");
dynamicElementElement.addAttribute(
"default-language-id",
LocaleUtil.toLanguageId(field.getDefaultLocale()));
dynamicElementElement.addAttribute("name", field.getName());
for (Locale locale : field.getAvailableLocales()) {
List values = field.getValues(locale);
for (Serializable value : values) {
Element dynamicContentElement =
dynamicElementElement.addElement("dynamic-content");
dynamicContentElement.addAttribute(
"language-id", LocaleUtil.toLanguageId(locale));
updateField(dynamicContentElement, value);
}
}
}
protected List getElementsByName(Document document, String name) {
name = HtmlUtil.escapeXPathAttribute(name);
XPath xPathSelector = _saxReader.createXPath(
"//dynamic-element[@name=".concat(name).concat("]"));
return xPathSelector.selectNodes(document);
}
@Reference(unbind = "-")
protected void setSAXReader(SAXReader saxReader) {
_saxReader = saxReader;
}
protected void updateField(
Element dynamicContentElement, Serializable fieldValue) {
dynamicContentElement.clearContent();
if (fieldValue instanceof Date) {
Date valueDate = (Date)fieldValue;
fieldValue = valueDate.getTime();
}
String valueString = String.valueOf(fieldValue);
dynamicContentElement.addCDATA(valueString.trim());
}
protected void validate(Document document) throws Exception {
XPath xPathSelector = _saxReader.createXPath("//dynamic-element");
List nodes = xPathSelector.selectNodes(document);
Set elementNames = new HashSet<>();
for (Node node : nodes) {
Element element = (Element)node;
String name = StringUtil.toLowerCase(
element.attributeValue("name"));
if (Validator.isNull(name)) {
throw new StructureDefinitionException(
"Element must have a name attribute " +
element.formattedString());
}
if (name.startsWith(DDMStructureConstants.XSD_NAME_RESERVED)) {
throw new StructureDefinitionException(
"Element name " + name + " is reserved");
}
if (elementNames.contains(name)) {
throw new StructureDuplicateElementException(
"Element with name " + name + " already exists");
}
elementNames.add(name);
}
}
private static final Log _log = LogFactoryUtil.getLog(DDMXMLImpl.class);
private SAXReader _saxReader;
private XMLSchema _xmlSchema;
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy