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 }