001/*
002 * (C) Copyright 2006-20012 Nuxeo SAS (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Nuxeo - initial API and implementation
016 *
017 */
018
019package org.nuxeo.template;
020
021import java.text.ParseException;
022import java.text.SimpleDateFormat;
023import java.util.ArrayList;
024import java.util.List;
025
026import org.apache.commons.logging.Log;
027import org.apache.commons.logging.LogFactory;
028import org.dom4j.Attribute;
029import org.dom4j.Document;
030import org.dom4j.DocumentException;
031import org.dom4j.DocumentFactory;
032import org.dom4j.DocumentHelper;
033import org.dom4j.Element;
034import org.dom4j.Namespace;
035import org.dom4j.QName;
036import org.dom4j.tree.DefaultElement;
037import org.nuxeo.ecm.core.api.DocumentModel;
038import org.nuxeo.template.api.InputType;
039import org.nuxeo.template.api.TemplateInput;
040
041/**
042 * {@link TemplateInput} parameters are stored in the {@link DocumentModel} as a single String Property via XML
043 * Serialization. This class contains the Serialization/Deserialization logic.
044 *
045 * @author Tiry (tdelprat@nuxeo.com)
046 */
047public class XMLSerializer {
048
049    protected static final Log log = LogFactory.getLog(XMLSerializer.class);
050
051    public static final String XML_NAMESPACE = "http://www.nuxeo.org/DocumentTemplate";
052
053    public static final String XML_NAMESPACE_PREFIX = "nxdt";
054
055    public static final Namespace ns = new Namespace(XML_NAMESPACE_PREFIX, XML_NAMESPACE);
056
057    public static final QName fieldsTag = DocumentFactory.getInstance().createQName("templateParams", ns);
058
059    public static final QName fieldTag = DocumentFactory.getInstance().createQName("field", ns);
060
061    public static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss:sss");
062
063    public static String serialize(List<TemplateInput> params) {
064
065        Element root = DocumentFactory.getInstance().createElement(fieldsTag);
066
067        for (TemplateInput input : params) {
068
069            Element field = root.addElement(fieldTag);
070
071            field.addAttribute("name", input.getName());
072
073            InputType type = input.getType();
074            if (type == null) {
075                log.warn(input.getName() + " is null");
076            }
077            field.addAttribute("type", type.getValue());
078
079            if (input.isReadOnly()) {
080                field.addAttribute("readonly", "true");
081            }
082
083            if (input.isAutoLoop()) {
084                field.addAttribute("autoloop", "true");
085            }
086
087            if (InputType.StringValue.equals(type)) {
088                field.addAttribute("value", input.getStringValue());
089            } else if (InputType.DateValue.equals(type)) {
090                field.addAttribute("value", dateFormat.format(input.getDateValue()));
091            } else if (InputType.BooleanValue.equals(type)) {
092                field.addAttribute("value", input.getBooleanValue().toString());
093            } else {
094                field.addAttribute("source", input.getSource());
095            }
096
097            if (input.getDesciption() != null) {
098                field.setText(input.getDesciption());
099            }
100        }
101        return root.asXML();
102    }
103
104    public static List<TemplateInput> readFromXml(String xml) throws DocumentException {
105
106        List<TemplateInput> result = new ArrayList<TemplateInput>();
107
108        Document xmlDoc = DocumentHelper.parseText(xml);
109
110        @SuppressWarnings("rawtypes")
111        List nodes = xmlDoc.getRootElement().elements(fieldTag);
112
113        for (Object node : nodes) {
114
115            DefaultElement elem = (DefaultElement) node;
116            Attribute name = elem.attribute("name");
117            TemplateInput param = new TemplateInput(name.getValue());
118
119            InputType type = InputType.StringValue;
120
121            if (elem.attribute("type") != null) {
122                type = InputType.getByValue(elem.attribute("type").getValue());
123                param.setType(type);
124            }
125
126            String strValue = elem.attributeValue("value");
127            if (InputType.StringValue.equals(type)) {
128                param.setStringValue(strValue);
129            } else if (InputType.DateValue.equals(type)) {
130                try {
131                    param.setDateValue(dateFormat.parse(strValue));
132                } catch (ParseException e) {
133                    throw new DocumentException(e);
134                }
135            } else if (InputType.BooleanValue.equals(type)) {
136                param.setBooleanValue(new Boolean(strValue));
137            } else {
138                param.setSource(elem.attributeValue("source"));
139            }
140
141            if (elem.attribute("readonly") != null) {
142                param.setReadOnly(Boolean.parseBoolean(elem.attributeValue("readonly")));
143            }
144
145            if (elem.attribute("autoloop") != null) {
146                param.setAutoLoop(Boolean.parseBoolean(elem.attributeValue("autoloop")));
147            }
148
149            param.setDesciption(elem.getText());
150
151            result.add(param);
152        }
153
154        return result;
155    }
156
157}