001    /*
002     * Sonar, open source software quality management tool.
003     * Copyright (C) 2008-2011 SonarSource
004     * mailto:contact AT sonarsource DOT com
005     *
006     * Sonar is free software; you can redistribute it and/or
007     * modify it under the terms of the GNU Lesser General Public
008     * License as published by the Free Software Foundation; either
009     * version 3 of the License, or (at your option) any later version.
010     *
011     * Sonar is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014     * Lesser General Public License for more details.
015     *
016     * You should have received a copy of the GNU Lesser General Public
017     * License along with Sonar; if not, write to the Free Software
018     * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02
019     */
020    package org.sonar.api.checks.profiles;
021    
022    import com.thoughtworks.xstream.XStream;
023    import com.thoughtworks.xstream.converters.Converter;
024    import com.thoughtworks.xstream.converters.MarshallingContext;
025    import com.thoughtworks.xstream.converters.UnmarshallingContext;
026    import com.thoughtworks.xstream.io.HierarchicalStreamReader;
027    import com.thoughtworks.xstream.io.HierarchicalStreamWriter;
028    import com.thoughtworks.xstream.io.xml.CompactWriter;
029    import com.thoughtworks.xstream.io.xml.XppDriver;
030    import org.apache.commons.io.IOUtils;
031    import org.sonar.check.Priority;
032    
033    import java.io.InputStreamReader;
034    import java.io.Reader;
035    import java.io.Writer;
036    import java.util.Map;
037    
038    /**
039     * @since 2.1 (experimental)
040     * @deprecated since 2.3
041     */
042    @Deprecated
043    public final class CheckProfileXmlMarshaller {
044    
045      public static void toXml(CheckProfile profile, Writer writer) {
046        getXStream().toXML(profile, writer);
047      }
048    
049      public static CheckProfile fromXml(Reader xml) {
050        return (CheckProfile) getXStream().fromXML(xml);
051      }
052    
053      public static CheckProfile fromXmlInClasspath(String pathToXml) {
054        return fromXmlInClasspath(pathToXml, CheckProfileXmlMarshaller.class);
055      }
056    
057      public static CheckProfile fromXmlInClasspath(String pathToXml, Class clazz) {
058        Reader reader = new InputStreamReader(clazz.getResourceAsStream(pathToXml));
059        try {
060          return fromXml(reader);
061        } finally {
062          IOUtils.closeQuietly(reader);
063        }
064      }
065    
066      private static XStream getXStream() {
067        XStream xstream = new XStream(new CompactDriver());
068        xstream.setClassLoader(CheckProfileXmlMarshaller.class.getClassLoader());
069        xstream.registerConverter(new CheckConverter());
070        xstream.alias("profile", CheckProfile.class);
071        xstream.alias("check", Check.class);
072        xstream.addImplicitCollection(CheckProfile.class, "checks");
073        return xstream;
074      }
075    
076      private static class CompactDriver extends XppDriver {
077        @Override
078        public HierarchicalStreamWriter createWriter(Writer out) {
079          return new XDataPrintWriter(out);
080        }
081      }
082    
083    
084      private static class XDataPrintWriter extends CompactWriter {
085        public XDataPrintWriter(Writer writer) {
086          super(writer, XML_1_0);
087        }
088      }
089    
090      private static class CheckConverter implements Converter {
091    
092        public boolean canConvert(Class clazz) {
093          return clazz.equals(Check.class);
094        }
095    
096        public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
097          Check check = (Check) value;
098          writer.startNode("repository");
099          writer.setValue(check.getRepositoryKey());
100          writer.endNode();
101          writer.startNode("template");
102          writer.setValue(check.getTemplateKey());
103          writer.endNode();
104          writer.startNode("priority");
105          writer.setValue(check.getPriority().toString());
106          writer.endNode();
107          for (Map.Entry<String, String> entry : check.getProperties().entrySet()) {
108            if (entry.getValue() != null) {
109              writer.startNode("property");
110              writer.startNode("key");
111              writer.setValue(entry.getKey());
112              writer.endNode();
113              writer.startNode("value");
114              // TODO is escaping automatically supported by xstream ?
115              writer.setValue(entry.getValue());
116              writer.endNode();
117              writer.endNode();
118            }
119          }
120        }
121    
122        public Object unmarshal(HierarchicalStreamReader reader,
123                                UnmarshallingContext context) {
124          Check check = new Check();
125          while (reader.hasMoreChildren()) {
126            reader.moveDown();
127            readValue(reader, check);
128            reader.moveUp();
129          }
130          return check;
131        }
132    
133        private void readValue(HierarchicalStreamReader reader, Check check) {
134          if (reader.getNodeName().equals("repository")) {
135            check.setRepositoryKey(reader.getValue());
136    
137          } else if (reader.getNodeName().equals("template")) {
138            check.setTemplateKey(reader.getValue());
139    
140          } else if (reader.getNodeName().equals("priority")) {
141            check.setPriority(Priority.valueOf(reader.getValue()));
142    
143          } else if (reader.getNodeName().equals("property")) {
144            reader.moveDown();
145            String key = reader.getValue();
146            reader.moveUp();
147    
148            reader.moveDown();
149            String value = reader.getValue();
150            reader.moveUp();
151            check.addProperty(key, value);
152          }
153        }
154    
155      }
156    }