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 String DATE_FORMAT = "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                field.addAttribute("type", type.getValue());
078            } else {
079                log.warn(input.getName() + " is null");
080            }
081
082            if (input.isReadOnly()) {
083                field.addAttribute("readonly", "true");
084            }
085
086            if (input.isAutoLoop()) {
087                field.addAttribute("autoloop", "true");
088            }
089
090            if (InputType.StringValue.equals(type)) {
091                field.addAttribute("value", input.getStringValue());
092            } else if (InputType.DateValue.equals(type)) {
093                SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
094                field.addAttribute("value", dateFormat.format(input.getDateValue()));
095            } else if (InputType.BooleanValue.equals(type)) {
096                field.addAttribute("value", input.getBooleanValue().toString());
097            } else {
098                field.addAttribute("source", input.getSource());
099            }
100
101            if (input.getDesciption() != null) {
102                field.setText(input.getDesciption());
103            }
104        }
105        return root.asXML();
106    }
107
108    public static List<TemplateInput> readFromXml(String xml) throws DocumentException {
109
110        List<TemplateInput> result = new ArrayList<TemplateInput>();
111
112        Document xmlDoc = DocumentHelper.parseText(xml);
113
114        @SuppressWarnings("rawtypes")
115        List nodes = xmlDoc.getRootElement().elements(fieldTag);
116
117        for (Object node : nodes) {
118
119            DefaultElement elem = (DefaultElement) node;
120            Attribute name = elem.attribute("name");
121            TemplateInput param = new TemplateInput(name.getValue());
122
123            InputType type = InputType.StringValue;
124
125            if (elem.attribute("type") != null) {
126                type = InputType.getByValue(elem.attribute("type").getValue());
127                param.setType(type);
128            }
129
130            String strValue = elem.attributeValue("value");
131            if (InputType.StringValue.equals(type)) {
132                param.setStringValue(strValue);
133            } else if (InputType.DateValue.equals(type)) {
134                try {
135                    SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT);
136                    param.setDateValue(dateFormat.parse(strValue));
137                } catch (ParseException e) {
138                    throw new DocumentException(e);
139                }
140            } else if (InputType.BooleanValue.equals(type)) {
141                param.setBooleanValue(new Boolean(strValue));
142            } else {
143                param.setSource(elem.attributeValue("source"));
144            }
145
146            if (elem.attribute("readonly") != null) {
147                param.setReadOnly(Boolean.parseBoolean(elem.attributeValue("readonly")));
148            }
149
150            if (elem.attribute("autoloop") != null) {
151                param.setAutoLoop(Boolean.parseBoolean(elem.attributeValue("autoloop")));
152            }
153
154            param.setDesciption(elem.getText());
155
156            result.add(param);
157        }
158
159        return result;
160    }
161
162}