*/
package org.sonar.api.rules;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Maps;
+import com.google.common.io.Closeables;
import org.apache.commons.io.FileUtils;
-import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.CharEncoding;
import org.apache.commons.lang.StringUtils;
import org.codehaus.staxmate.SMInputFactory;
import org.codehaus.staxmate.in.SMHierarchicCursor;
import org.codehaus.staxmate.in.SMInputCursor;
+import org.sonar.api.PropertyType;
import org.sonar.api.ServerComponent;
import org.sonar.api.utils.SonarException;
import org.sonar.check.Cardinality;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
-import java.io.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
+import java.util.Map;
/**
* @since 2.3
*/
public final class XMLRuleParser implements ServerComponent {
+ private final static Map<String, String> TYPE_MAP = typeMapWithDeprecatedValues();
public List<Rule> parse(File file) {
Reader reader = null;
throw new SonarException("Fail to load the file: " + file, e);
} finally {
- IOUtils.closeQuietly(reader);
+ Closeables.closeQuietly(reader);
}
}
throw new SonarException("Fail to load the xml stream", e);
} finally {
- IOUtils.closeQuietly(reader);
+ Closeables.closeQuietly(reader);
}
}
String typeAttribute = ruleC.getAttrValue("type");
if (StringUtils.isNotBlank(typeAttribute)) {
/* BACKWARD COMPATIBILITY WITH DEPRECATED FORMAT */
- param.setType(StringUtils.trim(typeAttribute));
+ param.setType(type(StringUtils.trim(typeAttribute)));
}
SMInputCursor paramC = ruleC.childElementCursor();
param.setDescription(propText);
} else if (StringUtils.equalsIgnoreCase("type", propNodeName)) {
- param.setType(propText);
+ param.setType(type(propText));
} else if (StringUtils.equalsIgnoreCase("defaultValue", propNodeName)) {
param.setDefaultValue(propText);
throw new SonarException("Node <key> is missing in <param>");
}
}
+
+ private static Map<String, String> typeMapWithDeprecatedValues() {
+ Map<String, String> map = Maps.newHashMap();
+ map.put("i", PropertyType.INTEGER.name());
+ map.put("s", PropertyType.STRING.name());
+ map.put("b", PropertyType.BOOLEAN.name());
+ map.put("r", PropertyType.REGULAR_EXPRESSION.name());
+ map.put("s{}", "s{}");
+ map.put("i{}", "i{}");
+ for (PropertyType propertyType : PropertyType.values()) {
+ map.put(propertyType.name(), propertyType.name());
+ }
+ return map;
+ }
+
+ @VisibleForTesting
+ static String type(String type) {
+ String validType = TYPE_MAP.get(type);
+ if (null != validType) {
+ return validType;
+ }
+
+ if (type.matches(".\\[.+\\]")) {
+ return type;
+ }
+ throw new SonarException("Invalid property type [" + type + "]");
+ }
}
import org.hamcrest.core.Is;
import org.junit.Test;
+import org.sonar.api.PropertyType;
import org.sonar.api.utils.SonarException;
import org.sonar.check.Cardinality;
import java.io.StringReader;
import java.util.List;
+import static com.google.common.collect.Iterables.getOnlyElement;
+import static org.fest.assertions.Assertions.assertThat;
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsNot.not;
import static org.hamcrest.core.IsNull.nullValue;
new XMLRuleParser().parse(new StringReader("<rules><rule><key>foo</key><name>Foo</name><param></param></rule></rules>"));
}
+ @Test
+ public void should_read_rule_parameter_type() {
+ assertThat(typeOf("<rules><rule><key>foo</key><name>Foo</name><param><key>key</key><type>STRING</type></param></rule></rules>")).isEqualTo(PropertyType.STRING.name());
+ assertThat(typeOf("<rules><rule><key>foo</key><name>Foo</name><param><key>key</key><type>INTEGER</type></param></rule></rules>")).isEqualTo(PropertyType.INTEGER.name());
+ assertThat(typeOf("<rules><rule><key>foo</key><name>Foo</name><param><key>key</key><type>s</type></param></rule></rules>")).isEqualTo(PropertyType.STRING.name());
+ assertThat(typeOf("<rules><rule><key>foo</key><name>Foo</name><param><key>key</key><type>s{}</type></param></rule></rules>")).isEqualTo("s{}");
+ assertThat(typeOf("<rules><rule><key>foo</key><name>Foo</name><param><key>key</key><type>i{}</type></param></rule></rules>")).isEqualTo("i{}");
+ assertThat(typeOf("<rules><rule><key>foo</key><name>Foo</name><param><key>key</key><type>s[foo,bar]</type></param></rule></rules>")).isEqualTo("s[foo,bar]");
+ }
+
+ static String typeOf(String xml) {
+ return getOnlyElement(new XMLRuleParser().parse(new StringReader(xml))).getParam("key").getType();
+ }
+
+ @Test(expected = SonarException.class)
+ public void fail_on_invalid_rule_parameter_type() {
+ new XMLRuleParser().parse(new StringReader("<rules><rule><key>foo</key><name>Foo</name><param><key>key</key><type>INVALID</type></param></rule></rules>"));
+ }
+
@Test
public void testUtf8Encoding() {
List<Rule> rules = new XMLRuleParser().parse(getClass().getResourceAsStream("/org/sonar/api/rules/XMLRuleParserTest/utf8.xml"));