001 /*
002 * Sonar, open source software quality management tool.
003 * Copyright (C) 2009 SonarSource SA
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 * EXPERIMENTAL - will be used in version 2.3
040 */
041 public final class CheckProfileXmlMarshaller {
042
043 public static void toXml(CheckProfile profile, Writer writer) {
044 getXStream().toXML(profile, writer);
045 }
046
047 public static CheckProfile fromXml(Reader xml) {
048 return (CheckProfile) getXStream().fromXML(xml);
049 }
050
051 public static CheckProfile fromXmlInClasspath(String pathToXml) {
052 return fromXmlInClasspath(pathToXml, CheckProfileXmlMarshaller.class);
053 }
054
055 public static CheckProfile fromXmlInClasspath(String pathToXml, Class clazz) {
056 Reader reader = new InputStreamReader(clazz.getResourceAsStream(pathToXml));
057 try {
058 return fromXml(reader);
059 } finally {
060 IOUtils.closeQuietly(reader);
061 }
062 }
063
064 private static XStream getXStream() {
065 XStream xstream = new XStream(new CompactDriver());
066 xstream.setClassLoader(CheckProfileXmlMarshaller.class.getClassLoader());
067 xstream.registerConverter(new CheckConverter());
068 xstream.alias("profile", CheckProfile.class);
069 xstream.alias("check", Check.class);
070 xstream.addImplicitCollection(CheckProfile.class, "checks");
071 return xstream;
072 }
073
074 private static class CompactDriver extends XppDriver {
075 @Override
076 public HierarchicalStreamWriter createWriter(Writer out) {
077 return new XDataPrintWriter(out);
078 }
079 }
080
081
082 private static class XDataPrintWriter extends CompactWriter {
083 public XDataPrintWriter(Writer writer) {
084 super(writer, XML_1_0);
085 }
086 }
087
088 private static class CheckConverter implements Converter {
089
090 public boolean canConvert(Class clazz) {
091 return clazz.equals(Check.class);
092 }
093
094 public void marshal(Object value, HierarchicalStreamWriter writer, MarshallingContext context) {
095 Check check = (Check) value;
096 writer.startNode("repository");
097 writer.setValue(check.getRepositoryKey());
098 writer.endNode();
099 writer.startNode("template");
100 writer.setValue(check.getTemplateKey());
101 writer.endNode();
102 writer.startNode("priority");
103 writer.setValue(check.getPriority().toString());
104 writer.endNode();
105 for (Map.Entry<String, String> entry : check.getProperties().entrySet()) {
106 if (entry.getValue() != null) {
107 writer.startNode("property");
108 writer.startNode("key");
109 writer.setValue(entry.getKey());
110 writer.endNode();
111 writer.startNode("value");
112 // TODO is escaping automatically supported by xstream ?
113 writer.setValue(entry.getValue());
114 writer.endNode();
115 writer.endNode();
116 }
117 }
118 }
119
120 public Object unmarshal(HierarchicalStreamReader reader,
121 UnmarshallingContext context) {
122 Check check = new Check();
123 while (reader.hasMoreChildren()) {
124 reader.moveDown();
125 readValue(reader, check);
126 reader.moveUp();
127 }
128 return check;
129 }
130
131 private void readValue(HierarchicalStreamReader reader, Check check) {
132 if (reader.getNodeName().equals("repository")) {
133 check.setRepositoryKey(reader.getValue());
134
135 } else if (reader.getNodeName().equals("template")) {
136 check.setTemplateKey(reader.getValue());
137
138 } else if (reader.getNodeName().equals("priority")) {
139 check.setPriority(Priority.valueOf(reader.getValue()));
140
141 } else if (reader.getNodeName().equals("property")) {
142 reader.moveDown();
143 String key = reader.getValue();
144 reader.moveUp();
145
146 reader.moveDown();
147 String value = reader.getValue();
148 reader.moveUp();
149 check.addProperty(key, value);
150 }
151 }
152
153 }
154 }