| package org.apache.maven.plugin.jira; |
| |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you 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. |
| */ |
| |
| import java.io.File; |
| import java.io.FileInputStream; |
| import java.io.FileNotFoundException; |
| import java.io.InputStream; |
| import java.text.ParseException; |
| import java.text.SimpleDateFormat; |
| import java.util.ArrayList; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.Locale; |
| |
| import javax.xml.parsers.SAXParser; |
| import javax.xml.parsers.SAXParserFactory; |
| |
| import org.apache.maven.plugin.MojoExecutionException; |
| import org.apache.maven.plugin.issues.Issue; |
| import org.apache.maven.plugin.logging.Log; |
| import org.codehaus.plexus.util.IOUtil; |
| import org.xml.sax.Attributes; |
| import org.xml.sax.InputSource; |
| import org.xml.sax.SAXException; |
| import org.xml.sax.helpers.DefaultHandler; |
| |
| /** |
| * XML parser that extracts <code>Issue</code>s from JIRA. This works on an XML file downloaded from JIRA and creates a |
| * <code>List</code> of issues that is exposed to the user of the class. |
| * |
| * @version $Id$ |
| */ |
| public class JiraXML |
| extends DefaultHandler |
| { |
| private final List<Issue> issueList; |
| |
| private final StringBuilder currentElement = new StringBuilder( 1024 ); |
| |
| private String currentParent = ""; |
| |
| private final String datePattern; |
| |
| private Issue issue; |
| |
| private String jiraVersion = null; |
| |
| private final Log log; |
| |
| private SimpleDateFormat sdf = null; |
| |
| /** |
| * @param log not null. |
| * @param datePattern may be null. |
| * @since 2.4 |
| */ |
| public JiraXML( Log log, String datePattern ) |
| { |
| this.log = log; |
| this.datePattern = datePattern; |
| |
| if ( datePattern == null ) |
| { |
| sdf = null; |
| } |
| else |
| { |
| // @todo Do we need to be able to configure the locale of the JIRA server as well? |
| sdf = new SimpleDateFormat( datePattern, Locale.ENGLISH ); |
| } |
| |
| this.issueList = new ArrayList<Issue>( 16 ); |
| } |
| |
| /** |
| * Parse the given xml file. The list of issues can then be retrieved with {@link #getIssueList()}. |
| * |
| * @param xmlPath the file to pares. |
| * @throws MojoExecutionException |
| * @since 2.4 |
| */ |
| public void parseXML( File xmlPath ) |
| throws MojoExecutionException |
| { |
| InputStream xmlStream = null; |
| try |
| { |
| xmlStream = new FileInputStream( xmlPath ); |
| InputSource inputSource = new InputSource( xmlStream ); |
| parse( inputSource ); |
| } |
| catch ( FileNotFoundException e ) |
| { |
| throw new MojoExecutionException( "Failed to open JIRA XML file " + xmlPath, e ); |
| } |
| finally |
| { |
| IOUtil.close( xmlStream ); |
| } |
| } |
| |
| void parse( InputSource xmlSource ) |
| throws MojoExecutionException |
| { |
| try |
| { |
| SAXParserFactory factory = SAXParserFactory.newInstance(); |
| SAXParser saxParser = factory.newSAXParser(); |
| |
| saxParser.parse( xmlSource, this ); |
| } |
| catch ( Throwable t ) |
| { |
| throw new MojoExecutionException( "Failed to parse JIRA XML.", t ); |
| } |
| } |
| |
| public void startElement( String namespaceURI, String sName, String qName, Attributes attrs ) |
| throws SAXException |
| { |
| if ( qName.equals( "item" ) ) |
| { |
| issue = new Issue(); |
| |
| currentParent = "item"; |
| } |
| else if ( qName.equals( "key" ) ) |
| { |
| String id = attrs.getValue( "id" ); |
| if ( id != null ) |
| { |
| issue.setId( id.trim() ); |
| } |
| } |
| else if ( qName.equals( "build-info" ) ) |
| { |
| currentParent = "build-info"; |
| } |
| } |
| |
| public void endElement( String namespaceURI, String sName, String qName ) |
| throws SAXException |
| { |
| if ( qName.equals( "item" ) ) |
| { |
| issueList.add( issue ); |
| |
| currentParent = ""; |
| } |
| else if ( qName.equals( "key" ) ) |
| { |
| issue.setKey( currentElement.toString().trim() ); |
| } |
| else if ( qName.equals( "summary" ) ) |
| { |
| issue.setSummary( currentElement.toString().trim() ); |
| } |
| else if ( qName.equals( "type" ) ) |
| { |
| issue.setType( currentElement.toString().trim() ); |
| } |
| else if ( qName.equals( "link" ) && currentParent.equals( "item" ) ) |
| { |
| issue.setLink( currentElement.toString().trim() ); |
| } |
| else if ( qName.equals( "priority" ) ) |
| { |
| issue.setPriority( currentElement.toString().trim() ); |
| } |
| else if ( qName.equals( "status" ) ) |
| { |
| issue.setStatus( currentElement.toString().trim() ); |
| } |
| else if ( qName.equals( "resolution" ) ) |
| { |
| issue.setResolution( currentElement.toString().trim() ); |
| } |
| else if ( qName.equals( "assignee" ) ) |
| { |
| issue.setAssignee( currentElement.toString().trim() ); |
| } |
| else if ( qName.equals( "reporter" ) ) |
| { |
| issue.setReporter( currentElement.toString().trim() ); |
| } |
| else if ( qName.equals( "version" ) && currentParent.equals( "item" ) ) |
| { |
| issue.setVersion( currentElement.toString().trim() ); |
| } |
| else if ( qName.equals( "version" ) && currentParent.equals( "build-info" ) ) |
| { |
| jiraVersion = currentElement.toString().trim(); |
| } |
| else if ( qName.equals( "fixVersion" ) ) |
| { |
| issue.addFixVersion( currentElement.toString().trim() ); |
| } |
| else if ( qName.equals( "component" ) ) |
| { |
| issue.addComponent( currentElement.toString().trim() ); |
| } |
| else if ( qName.equals( "comment" ) ) |
| { |
| issue.addComment( currentElement.toString().trim() ); |
| } |
| else if ( qName.equals( "title" ) && currentParent.equals( "item" ) ) |
| { |
| issue.setTitle( currentElement.toString().trim() ); |
| } |
| else if ( qName.equals( "created" ) && currentParent.equals( "item" ) && sdf != null ) |
| { |
| try |
| { |
| issue.setCreated( sdf.parse( currentElement.toString().trim() ) ); |
| } |
| catch ( ParseException e ) |
| { |
| log.warn( "Element \"Created\". " + e.getMessage() + ". Using the pattern \"" + datePattern + "\"" ); |
| } |
| } |
| else if ( qName.equals( "updated" ) && currentParent.equals( "item" ) && sdf != null ) |
| { |
| try |
| { |
| issue.setUpdated( sdf.parse( currentElement.toString().trim() ) ); |
| } |
| catch ( ParseException e ) |
| { |
| log.warn( "Element \"Updated\". " + e.getMessage() + ". Using the pattern \"" + datePattern + "\"" ); |
| } |
| } |
| |
| currentElement.setLength( 0 ); |
| } |
| |
| public void characters( char[] buf, int offset, int len ) |
| throws SAXException |
| { |
| currentElement.append( buf, offset, len ); |
| } |
| |
| public List<Issue> getIssueList() |
| { |
| return Collections.unmodifiableList( this.issueList ); |
| } |
| |
| public String getJiraVersion() |
| { |
| return jiraVersion; |
| } |
| } |