001/*
002 * (C) Copyright 2006-2012 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Nuxeo - initial API and implementation
018 *
019 */
020
021package org.nuxeo.template;
022
023import java.text.ParseException;
024import java.text.SimpleDateFormat;
025import java.util.ArrayList;
026import java.util.List;
027
028import org.apache.commons.logging.Log;
029import org.apache.commons.logging.LogFactory;
030import org.dom4j.Attribute;
031import org.dom4j.Document;
032import org.dom4j.DocumentException;
033import org.dom4j.DocumentFactory;
034import org.dom4j.DocumentHelper;
035import org.dom4j.Element;
036import org.dom4j.Namespace;
037import org.dom4j.QName;
038import org.dom4j.tree.DefaultElement;
039import org.nuxeo.ecm.core.api.DocumentModel;
040import org.nuxeo.template.api.InputType;
041import org.nuxeo.template.api.TemplateInput;
042
043/**
044 * {@link TemplateInput} parameters are stored in the {@link DocumentModel} as a single String Property via XML
045 * Serialization. This class contains the Serialization/Deserialization logic.
046 *
047 * @author Tiry (tdelprat@nuxeo.com)
048 */
049public class XMLSerializer {
050
051    protected static final Log log = LogFactory.getLog(XMLSerializer.class);
052
053    public static final String XML_NAMESPACE = "http://www.nuxeo.org/DocumentTemplate";
054
055    public static final String XML_NAMESPACE_PREFIX = "nxdt";
056
057    public static final Namespace ns = new Namespace(XML_NAMESPACE_PREFIX, XML_NAMESPACE);
058
059    public static final QName fieldsTag = DocumentFactory.getInstance().createQName("templateParams", ns);
060
061    public static final QName fieldTag = DocumentFactory.getInstance().createQName("field", ns);
062
063    public static final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss:sss");
064
065    public static String serialize(List<TemplateInput> params) {
066
067        Element root = DocumentFactory.getInstance().createElement(fieldsTag);
068
069        for (TemplateInput input : params) {
070
071            Element field = root.addElement(fieldTag);
072
073            field.addAttribute("name", input.getName());
074
075            InputType type = input.getType();
076            if (type == null) {
077                log.warn(input.getName() + " is null");
078            }
079            field.addAttribute("type", type.getValue());
080
081            if (input.isReadOnly()) {
082                field.addAttribute("readonly", "true");
083            }
084
085            if (input.isAutoLoop()) {
086                field.addAttribute("autoloop", "true");
087            }
088
089            if (InputType.StringValue.equals(type)) {
090                field.addAttribute("value", input.getStringValue());
091            } else if (InputType.DateValue.equals(type)) {
092                field.addAttribute("value", dateFormat.format(input.getDateValue()));
093            } else if (InputType.BooleanValue.equals(type)) {
094                field.addAttribute("value", input.getBooleanValue().toString());
095            } else {
096                field.addAttribute("source", input.getSource());
097            }
098
099            if (input.getDesciption() != null) {
100                field.setText(input.getDesciption());
101            }
102        }
103        return root.asXML();
104    }
105
106    public static List<TemplateInput> readFromXml(String xml) throws DocumentException {
107
108        List<TemplateInput> result = new ArrayList<TemplateInput>();
109
110        Document xmlDoc = DocumentHelper.parseText(xml);
111
112        @SuppressWarnings("rawtypes")
113        List nodes = xmlDoc.getRootElement().elements(fieldTag);
114
115        for (Object node : nodes) {
116
117            DefaultElement elem = (DefaultElement) node;
118            Attribute name = elem.attribute("name");
119            TemplateInput param = new TemplateInput(name.getValue());
120
121            InputType type = InputType.StringValue;
122
123            if (elem.attribute("type") != null) {
124                type = InputType.getByValue(elem.attribute("type").getValue());
125                param.setType(type);
126            }
127
128            String strValue = elem.attributeValue("value");
129            if (InputType.StringValue.equals(type)) {
130                param.setStringValue(strValue);
131            } else if (InputType.DateValue.equals(type)) {
132                try {
133                    param.setDateValue(dateFormat.parse(strValue));
134                } catch (ParseException e) {
135                    throw new DocumentException(e);
136                }
137            } else if (InputType.BooleanValue.equals(type)) {
138                param.setBooleanValue(new Boolean(strValue));
139            } else {
140                param.setSource(elem.attributeValue("source"));
141            }
142
143            if (elem.attribute("readonly") != null) {
144                param.setReadOnly(Boolean.parseBoolean(elem.attributeValue("readonly")));
145            }
146
147            if (elem.attribute("autoloop") != null) {
148                param.setAutoLoop(Boolean.parseBoolean(elem.attributeValue("autoloop")));
149            }
150
151            param.setDesciption(elem.getText());
152
153            result.add(param);
154        }
155
156        return result;
157    }
158
159}