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