View Javadoc

1   package org.apache.maven.plugin.jira;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.File;
23  import java.text.ParseException;
24  import java.text.SimpleDateFormat;
25  import java.util.ArrayList;
26  import java.util.Collections;
27  import java.util.List;
28  import java.util.Locale;
29  
30  import javax.xml.parsers.SAXParser;
31  import javax.xml.parsers.SAXParserFactory;
32  
33  import org.apache.maven.plugin.issues.Issue;
34  import org.apache.maven.plugin.logging.Log;
35  import org.xml.sax.Attributes;
36  import org.xml.sax.SAXException;
37  import org.xml.sax.helpers.DefaultHandler;
38  
39  /**
40   * XML parser that extracts <code>Issue</code>s from JIRA. This works on an XML
41   * file downloaded from JIRA and creates a <code>List</code> of issues that is
42   * exposed to the user of the class.
43   *
44   * @version $Id: JiraXML.html 816601 2012-05-08 12:50:18Z hboutemy $
45   */
46  public class JiraXML
47      extends DefaultHandler
48  {
49      private final List<Issue> issueList;
50  
51      private final StringBuffer currentElement = new StringBuffer( 1024 );
52  
53      private String currentParent = "";
54  
55      private final String datePattern;
56  
57      private Issue issue;
58  
59      private String jiraVersion = null;
60  
61      private final Log log;
62  
63      private SimpleDateFormat sdf = null;
64  
65      /**
66       *
67       * @param log not null.
68       * @param datePattern may be null.
69       * @since 2.4
70       */
71      public JiraXML( Log log, String datePattern )
72      {
73          this.log = log;
74          this.datePattern = datePattern;
75  
76          if ( datePattern == null )
77          {
78              sdf = null;
79          }
80          else
81          {
82              // @todo Do we need to be able to configure the locale of the JIRA server as well?
83              sdf = new SimpleDateFormat( datePattern, Locale.ENGLISH );
84          }
85  
86          this.issueList = new ArrayList<Issue>( 16 );
87      }
88  
89      /**
90       * Parse the given xml file. The list of issues can then be retrieved with {@link #getIssueList()}.
91       *
92       * @param xmlPath the file to pares.
93       *
94       * @since 2.4
95       */
96      public void parseXML( File xmlPath )
97      {
98          parse( xmlPath );
99      }
100 
101     private void parse( File xmlPath )
102     {
103         try
104         {
105             SAXParserFactory factory = SAXParserFactory.newInstance();
106             SAXParser saxParser = factory.newSAXParser();
107 
108             saxParser.parse( xmlPath, this );
109         }
110         catch ( Throwable t )
111         {
112             log.warn( t );
113         }
114     }
115 
116     public void startElement( String namespaceURI, String sName, String qName, Attributes attrs )
117         throws SAXException
118     {
119         if ( qName.equals( "item" ) )
120         {
121             issue = new Issue();
122 
123             currentParent = "item";
124         }
125         else if ( qName.equals( "key" ) )
126         {
127             String id = attrs.getValue( "id" );
128             if ( id != null )
129             {
130                 issue.setId( id.trim() );
131             }
132         }
133         else if ( qName.equals( "build-info" ) )
134         {
135             currentParent = "build-info";
136         }
137     }
138 
139     public void endElement( String namespaceURI, String sName, String qName )
140         throws SAXException
141     {
142         if ( qName.equals( "item" ) )
143         {
144             issueList.add( issue );
145 
146             currentParent = "";
147         }
148         else if ( qName.equals( "key" ) )
149         {
150             issue.setKey( currentElement.toString().trim() );
151         }
152         else if ( qName.equals( "summary" ) )
153         {
154             issue.setSummary( currentElement.toString().trim() );
155         }
156         else if ( qName.equals( "type" ) )
157         {
158             issue.setType( currentElement.toString().trim() );
159         }
160         else if ( qName.equals( "link" ) && currentParent.equals( "item" ) )
161         {
162             issue.setLink( currentElement.toString().trim() );
163         }
164         else if ( qName.equals( "priority" ) )
165         {
166             issue.setPriority( currentElement.toString().trim() );
167         }
168         else if ( qName.equals( "status" ) )
169         {
170             issue.setStatus( currentElement.toString().trim() );
171         }
172         else if ( qName.equals( "resolution" ) )
173         {
174             issue.setResolution( currentElement.toString().trim() );
175         }
176         else if ( qName.equals( "assignee" ) )
177         {
178             issue.setAssignee( currentElement.toString().trim() );
179         }
180         else if ( qName.equals( "reporter" ) )
181         {
182             issue.setReporter( currentElement.toString().trim() );
183         }
184         else if ( qName.equals( "version" ) && currentParent.equals( "item" ) )
185         {
186             issue.setVersion( currentElement.toString().trim() );
187         }
188         else if ( qName.equals( "version" ) && currentParent.equals( "build-info" ) )
189         {
190             jiraVersion = currentElement.toString().trim();
191         }
192         else if ( qName.equals( "fixVersion" ) )
193         {
194             issue.addFixVersion( currentElement.toString().trim() );
195         }
196         else if ( qName.equals( "component" ) )
197         {
198             issue.addComponent( currentElement.toString().trim() );
199         }
200         else if ( qName.equals( "comment" ) )
201         {
202             issue.addComment( currentElement.toString().trim() );
203         }
204         else if ( qName.equals( "title" ) && currentParent.equals( "item" ) )
205         {
206             issue.setTitle( currentElement.toString().trim() );
207         }
208         else if ( qName.equals( "created" ) && currentParent.equals( "item" ) && sdf != null )
209         {
210             try
211             {
212                 issue.setCreated( sdf.parse( currentElement.toString().trim() ) );
213             }
214             catch ( ParseException e )
215             {
216                 log.warn( "Element \"Created\". " + e.getMessage() + ". Using the pattern \"" + datePattern + "\"" );
217             }
218         }
219         else if ( qName.equals( "updated" ) && currentParent.equals( "item" ) && sdf != null )
220         {
221             try
222             {
223                 issue.setUpdated( sdf.parse( currentElement.toString().trim() ) );
224             }
225             catch ( ParseException e )
226             {
227                 log.warn( "Element \"Updated\". " + e.getMessage() + ". Using the pattern \"" + datePattern + "\"" );
228             }
229         }
230 
231         currentElement.setLength( 0 );
232     }
233 
234     public void characters( char[] buf, int offset, int len )
235         throws SAXException
236     {
237         currentElement.append( buf, offset, len );
238     }
239 
240     public List<Issue> getIssueList()
241     {
242         return Collections.unmodifiableList( this.issueList );
243     }
244 
245     public String getJiraVersion()
246     {
247         return jiraVersion;
248     }
249 }