// ===================================================================== // // Copyright (C) 2012 - 2016, Philip Graf // // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 // which accompanies this distribution, and is available at // http://www.eclipse.org/legal/epl-v10.html // // ===================================================================== package ch.acanda.eclipse.pmd.repository; import static com.google.common.collect.Iterables.transform; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; import java.io.StringWriter; import java.nio.charset.Charset; import org.xml.sax.InputSource; import org.xml.sax.SAXException; import org.xml.sax.XMLReader; import org.xml.sax.helpers.XMLReaderFactory; import ch.acanda.eclipse.pmd.PMDPlugin; import ch.acanda.eclipse.pmd.domain.ProjectModel; import ch.acanda.eclipse.pmd.domain.RuleSetModel; import com.google.common.base.Charsets; import com.google.common.base.Function; /** * <pre> * {@code * <?xml version="1.0" encoding="UTF-8"?> * <eclipse-pmd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" * xsi:noNamespaceSchemaLocation="http://www.acanda.ch/eclipse-pmd/eclipse-pmd_0.8.0.xsd"> * <analysis enabled="true" /> * <rulesets> * <ruleset name="Rules for this specific project" * ref="pmd.xml" refcontext="project" /> * <ruleset name="Rules for all projects" * ref="ch.acanda.pmd/pmd.xml" refcontext="workspace" /> * <ruleset name="Company rules" * ref="e:\pmd.xml" refcontext="filesystem" /> * <ruleset name="Sonar" * ref="http://example.org/profiles/export?format=pmd&language=java&name=MyProfile" refcontext="remote" /> * </rulesets> * </eclipse-pmd> * } * </pre> * * @author Philip Graf */ public class ProjectModelSerializer { static final String TAG_NAME_ECLIPSE_PMD = "eclipse-pmd"; static final String TAG_NAME_ANALYSIS = "analysis"; static final String TAG_NAME_RULESETS = "rulesets"; static final String TAG_NAME_RULESET = "ruleset"; static final String ATTRIBUTE_VALUE_REMOTE = "remote"; static final String ATTRIBUTE_VALUE_FILESYSTEM = "filesystem"; static final String ATTRIBUTE_VALUE_PROJECT = "project"; static final String ATTRIBUTE_VALUE_WORKSPACE = "workspace"; static final String ATTRIBUTE_NAME_ENABLED = "enabled"; static final String ATTRIBUTE_NAME_REF = "ref"; static final String ATTRIBUTE_NAME_REFCONTEXT = "refcontext"; static final String ATTRIBUTE_NAME_NAME = "name"; static final String SCHEMA_VERSION = "0.8"; public static final Charset ENCODING = Charsets.UTF_8; private static final Function<RuleSetModel, String> TO_XML_TAGS = new RuleSetConfigurationToXMLTag(); public String serialize(final ProjectModel model) { final StringWriter result = new StringWriter(1024); final PrintWriter writer = new PrintWriter(result); writer.format("<?xml version=\"1.0\" encoding=\"%s\"?>\n", ENCODING); writer.format("<%s xmlns=\"http://acanda.ch/eclipse-pmd/%2$s\"" + " xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + " xsi:schemaLocation=\"http://acanda.ch/eclipse-pmd/%2$s" + " http://acanda.ch/eclipse-pmd/eclipse-pmd-%2$s.xsd\">\n", TAG_NAME_ECLIPSE_PMD, SCHEMA_VERSION); writer.format(" <%s %s=\"%b\" />\n", TAG_NAME_ANALYSIS, ATTRIBUTE_NAME_ENABLED, model.isPMDEnabled()); if (!model.getRuleSets().isEmpty()) { writer.format(" <%s>\n", TAG_NAME_RULESETS); for (final String tag : transform(model.getRuleSets(), TO_XML_TAGS)) { writer.append(" ").append(tag).append('\n'); } writer.format(" </%s>\n", TAG_NAME_RULESETS); } writer.format("</%s>", TAG_NAME_ECLIPSE_PMD); return result.toString(); } public ProjectModel deserialize(final InputStream configurationStream, final String projectName) throws IOException { final ProjectConfigurationContentHandler contentHandler = new ProjectConfigurationContentHandler(); try { final XMLReader reader = XMLReaderFactory.createXMLReader(); reader.setContentHandler(contentHandler); reader.parse(new InputSource(configurationStream)); } catch (final SAXException e) { PMDPlugin.getDefault().error("Cannot read eclipse-pmd project configuration", e); } return contentHandler.getProjectModel(projectName); } }