package org.apache.maven.changes; import org.codehaus.plexus.util.xml.Xpp3Dom; import org.codehaus.plexus.util.xml.Xpp3DomBuilder; import org.codehaus.plexus.util.xml.pull.XmlPullParserException; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.io.Reader; import java.util.ArrayList; import java.util.List; /* * Copyright 2001-2005 The Apache Software Foundation. * * 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. */ /** * Parses a <tt>changes.xml</tt> file and returns the list of {@link Release} elements. * * @author <a href="snicoll@apache.org">Stephane Nicoll</a> * @version $Id$ */ public final class ReleaseParser { public static Release[] parse( final File changesFile ) throws IOException, InvalidChangesException { final Reader r = new FileReader( changesFile ); return parse( r ); } public static Release[] parse( final Reader changesReader ) throws InvalidChangesException, IOException { try { final Xpp3Dom doc = parseDocument( changesReader ); final Xpp3Dom releasesRoot = doc.getChild( "body" ); final List releases = new ArrayList(); final Xpp3Dom[] releaseElements = releasesRoot.getChildren( "release" ); for ( int i = 0; i < releaseElements.length; i++ ) { Xpp3Dom releaseElement = releaseElements[i]; releases.add( parseRelease( releaseElement ) ); } return (Release[]) releases.toArray( new Release[releases.size()] ); } catch ( XmlPullParserException e ) { throw new InvalidChangesException( "Invalid changes.xml file", e ); } } public static Release parse( final File changesFile, String releaseVersion ) throws ReleaseNotFoundException, InvalidChangesException, IOException { final Reader reader = new FileReader( changesFile ); return parse( reader, releaseVersion ); } public static Release parse( final Reader changesReader, String releaseVersion ) throws ReleaseNotFoundException, InvalidChangesException, IOException { try { final Xpp3Dom doc = parseDocument( changesReader ); final Xpp3Dom releasesRoot = doc.getChild( "body" ); // TODO Baaah easier to use xpath here "/document/body/release[@version='"+releaseVersion+"']" final Xpp3Dom[] releaseElements = releasesRoot.getChildren( "release" ); for ( int i = 0; i < releaseElements.length; i++ ) { Xpp3Dom releaseElement = releaseElements[i]; if ( releaseVersion.equals( releaseElement.getAttribute( "version" ) ) ) { return parseRelease( releaseElement ); } } throw new ReleaseNotFoundException( "Release version[" + releaseVersion + "] does not exist." ); } catch ( XmlPullParserException e ) { throw new InvalidChangesException( "Invalid changes.xml file", e ); } } private static Xpp3Dom parseDocument( final Reader reader ) throws IOException, XmlPullParserException { try { return Xpp3DomBuilder.build( reader ); } finally { if ( reader != null ) { reader.close(); } } } private static Release parseRelease( final Xpp3Dom releaseRoot ) throws InvalidChangesException { final String version = releaseRoot.getAttribute( "version" ); if ( version == null || version.equals( "" ) ) { throw new InvalidChangesException( "Invalid release, version attribute should be set." ); } final String releaseDate = releaseRoot.getAttribute( "date" ); final String description = releaseRoot.getAttribute( "description" ); // Actions final List actions = new ArrayList(); final Xpp3Dom actionElements[] = releaseRoot.getChildren( "action" ); for ( int i = 0; i < actionElements.length; i++ ) { Xpp3Dom actionElement = actionElements[i]; actions.add( parseIssueAction( actionElement ) ); } Action[] parsedActions = (Action[]) actions.toArray( new Action[actions.size()] ); return new Release( version, releaseDate, description, parsedActions ); } private static Action parseIssueAction( final Xpp3Dom actionRoot ) throws InvalidChangesException { final String author = actionRoot.getAttribute( "dev" ); if ( author == null || author.equals( "" ) ) { throw new InvalidChangesException( "Invalid action, dev attribute should be set." ); } final String issueId = actionRoot.getAttribute( "issue" ); final String typeString = actionRoot.getAttribute( "type" ); final ActionType type = ActionType.getActionType( typeString ); if ( type == null ) { throw new InvalidChangesException( "Invalid action, type[" + typeString + "] is not supported, " + "valid values are[" + ActionType.getActionTypes() + "]" ); } final String dueTo = actionRoot.getAttribute( "due-to" ); final String dueToEmail = actionRoot.getAttribute( "due-to-email" ); final String description = actionRoot.getValue(); return new Action( author, issueId, type, description, dueTo, dueToEmail ); } }