Java tutorial
/** * Copyright 2011 meltmedia * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.xchain.tools.monitoring; import org.apache.maven.artifact.Artifact; import org.apache.maven.plugin.AbstractMojo; import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.project.MavenProject; import org.apache.maven.model.Resource; import java.io.InputStream; import java.io.IOException; import java.io.File; import java.io.FileWriter; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.jar.JarFile; import java.util.jar.JarEntry; import org.xml.sax.Attributes; import org.apache.commons.digester.Digester; import org.apache.commons.digester.Rule; import org.apache.commons.digester.WithDefaultsRulesWrapper; import org.xml.sax.SAXException; import org.codehaus.plexus.util.xml.XMLWriter; import org.codehaus.plexus.util.xml.PrettyPrintXMLWriter; /** * @goal monitoring-info * @phase generate-resources * @requiresProject * @requiresDependencyResolution runtime * @author Christian Trimble */ public class MonitoringMojo extends AbstractMojo { /** * Location of the file. * @parameter expression="${project.build.directory}" * @required */ private File outputDirectory; /** * The monitor flag. If true, then the monitoring information will be generated. * @parameter expression="${build.monitor}" default-value="false" */ private boolean monitor; /** * The packaging type. * @parameter expression="${project.packaging}" * @required */ private String packaging; /** * The maven project for this artifact. * @parameter expression="${project}" * @required */ private MavenProject project; /** * The set of war dependencies that will be included in this project. * @parameter */ private Resource[] webResources; public void execute() throws MojoExecutionException { getLog().info("Executing the monitoring information plugin."); if (monitor) { getLog().info("Building monitoring information."); if (!"jar".equals(packaging) && !"war".equals(packaging)) { throw new MojoExecutionException( "Mojo information can only be created for projects packaged as 'jar' or 'war'."); } MonitoringInfo monitoringInfo = new MonitoringInfo(); // find all of the directories to get resources from. If they are filtered, then ignore them. List<Resource> resourceSet = (List<Resource>) project.getResources(); for (Resource resource : resourceSet) { monitoringInfo.getResourceList().add(copy(resource)); } // if this is a war, then we need to merge all of the monitoring-info.xml files into this file. if ("war".equals(packaging)) { if (webResources != null) { for (Resource resource : webResources) { monitoringInfo.getWarResourceList().add(copy(resource)); } // get all of the directories that hold resources, both static and generated. Set<Artifact> artifactSet = (Set<Artifact>) project.getArtifacts(); for (Artifact artifact : artifactSet) { // if this file is a jar, then try to load its monitoring-info.xml file and add it to this class. if ("war".equals(artifact.getType())) { mergeWarMonitoringInfo(monitoringInfo, artifact.getFile()); } } } } File metaInfDir = new File(project.getBuild().getOutputDirectory(), "META-INF"); metaInfDir.mkdirs(); getLog().info("Creating '" + metaInfDir.toString() + "'."); File monitoringFile = new File(metaInfDir, "monitoring-info.xml"); PrintWriter writer = null; XMLWriter xmlWriter = null; // write the artifact out. try { writer = new PrintWriter(monitoringFile, "UTF-8"); xmlWriter = new PrettyPrintXMLWriter(writer, " "); xmlWriter.startElement("monitoring-info"); // write the resource tags. for (Resource resource : monitoringInfo.getResourceList()) { xmlWriter.startElement("resource"); writeResource(xmlWriter, resource); xmlWriter.endElement(); } for (Resource warResource : monitoringInfo.getWarResourceList()) { xmlWriter.startElement("web-resource"); writeResource(xmlWriter, warResource); xmlWriter.endElement(); } xmlWriter.endElement(); writer.flush(); } catch (IOException ioe) { throw new MojoExecutionException("Could not write out META-INF/monitoring-info.xml file.", ioe); } finally { if (writer != null) { try { writer.close(); } catch (Exception ioe) { getLog().warn("Could not close writer for META-INF/monitoring-info.xml file.", ioe); } } } } } private void writeResource(XMLWriter xmlWriter, Resource resource) { xmlWriter.startElement("directory"); xmlWriter.writeText(resource.getDirectory()); xmlWriter.endElement(); xmlWriter.startElement("filtering"); xmlWriter.writeText("" + resource.isFiltering()); xmlWriter.endElement(); if (resource.getIncludes().size() > 0) { xmlWriter.startElement("includes"); for (String include : ((List<String>) resource.getIncludes())) { xmlWriter.startElement("include"); xmlWriter.writeText(include); xmlWriter.endElement(); } xmlWriter.endElement(); } if (resource.getExcludes().size() > 0) { xmlWriter.startElement("excludes"); for (String exclude : ((List<String>) resource.getExcludes())) { xmlWriter.startElement("exclude"); xmlWriter.writeText(exclude); xmlWriter.endElement(); } xmlWriter.endElement(); } } private class LoggingRule extends Rule { public void begin(String namespace, String name, Attributes attributes) throws Exception { getLog().warn("Unknown monitoring-info element encountered {" + namespace + "}" + name + "."); } } private void mergeWarMonitoringInfo(MonitoringInfo monitoringInfo, File file) throws MojoExecutionException { JarFile artifactJar = null; JarEntry monitoringInfoEntry = null; InputStream in = null; try { getLog().info("Getting monitoring info from file " + file.toString()); artifactJar = new JarFile(file); monitoringInfoEntry = artifactJar.getJarEntry("WEB-INF/classes/META-INF/monitoring-info.xml"); if (monitoringInfoEntry != null) { in = artifactJar.getInputStream(monitoringInfoEntry); // digest the xml file and get all of the entries. Digester digester = new Digester(); digester.push(monitoringInfo); digester.addRuleSet(new MonitoringInfoRuleSet()); WithDefaultsRulesWrapper wrapper = new WithDefaultsRulesWrapper(digester.getRules()); wrapper.addDefault(new LoggingRule()); digester.setRules(wrapper); digester.parse(in); } else { getLog().info("Monitoring info file not found in " + file.toString()); } } catch (SAXException se) { throw new MojoExecutionException("Could not parse a monitoring-info.xml file.", se); } catch (IOException ioe) { throw new MojoExecutionException("Could not open jar file.", ioe); } finally { if (in != null) { try { in.close(); } catch (IOException ioe) { getLog().warn("Could not close a jar entry input stream.", ioe); } } try { artifactJar.close(); } catch (IOException ioe) { getLog().warn("Could not close a jar.", ioe); } } } private Resource copy(Resource resource) { Resource copy = new Resource(); copy.setDirectory(resource.getDirectory()); copy.setTargetPath(resource.getTargetPath()); copy.setFiltering(resource.isFiltering()); copy.setModelEncoding(resource.getModelEncoding()); copy.setIncludes(copy(resource.getIncludes())); copy.setExcludes(copy(resource.getExcludes())); return copy; } private List copy(List list) { List copy = new ArrayList(); if (list != null) { copy.addAll(list); } return copy; } }