View Javadoc
1   package org.codehaus.mojo.jdepend;
2   
3   /*
4    * #%L
5    * JDepend Maven Plugin
6    * %%
7    * Copyright (C) 2006 - 2014 Codehaus
8    * %%
9    * Licensed under the Apache License, Version 2.0 (the "License");
10   * you may not use this file except in compliance with the License.
11   * You may obtain a copy of the License at
12   * 
13   *    http://www.apache.org/licenses/LICENSE-2.0
14   * 
15   * Unless required by applicable law or agreed to in writing, software
16   * distributed under the License is distributed on an "AS IS" BASIS,
17   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18   * See the License for the specific language governing permissions and
19   * limitations under the License.
20   * #L%
21   */
22  
23  import java.io.File;
24  import java.io.IOException;
25  import java.util.ArrayList;
26  import java.util.List;
27  import java.util.Stack;
28  
29  import javax.xml.parsers.ParserConfigurationException;
30  import javax.xml.parsers.SAXParser;
31  import javax.xml.parsers.SAXParserFactory;
32  
33  import org.codehaus.mojo.jdepend.objects.CyclePackage;
34  import org.codehaus.mojo.jdepend.objects.JDPackage;
35  import org.codehaus.mojo.jdepend.objects.Stats;
36  import org.xml.sax.Attributes;
37  import org.xml.sax.SAXException;
38  import org.xml.sax.helpers.DefaultHandler;
39  
40  /**
41   * @author Who ever this implemented first.
42   */
43  public class JDependXMLReportParser
44      extends DefaultHandler
45  {
46      protected List<JDPackage> packages;
47  
48      protected JDPackage jdpackage;
49  
50      protected Stats stats;
51  
52      protected StringBuffer buffer = null;
53  
54      protected Stack<String> stack;
55  
56      protected List<CyclePackage> cycles;
57  
58      protected CyclePackage cyclePackage;
59  
60      ReportGenerator report;
61  
62      private boolean errFlag = false;
63  
64      /**
65       * Creates a new instance of JDependXMLReportParser.
66       * 
67       * @param xmlFile
68       * @throws ParserConfigurationException
69       * @throws SAXException
70       * @throws IOException
71       */
72      public JDependXMLReportParser( File xmlFile )
73          throws ParserConfigurationException, SAXException, IOException
74      {
75          SAXParserFactory factory = SAXParserFactory.newInstance();
76  
77          /* Create an empty stack */
78          stack = new Stack<String>();
79  
80          SAXParser saxParser = factory.newSAXParser();
81  
82          saxParser.parse( xmlFile, this );
83  
84      }
85  
86      /*
87       * (non-Javadoc)
88       * @see org.xml.sax.helpers.DefaultHandler#startElement(java.lang.String, java.lang.String, java.lang.String,
89       * org.xml.sax.Attributes)
90       */
91      public void startElement( String namespaceURI, String sName, String qName, Attributes attrs )
92          throws SAXException
93      {
94  
95          /* Push element name into stack */
96          stack.push( qName );
97  
98          // TODO only create a new buffer when the element is expected to have
99          // text
100         buffer = new StringBuffer();
101 
102         if ( qName.equals( "Packages" ) )
103         {
104             packages = new ArrayList<JDPackage>();
105         }
106         else if ( qName.equals( "Package" ) )
107         {
108             if ( isParentElement( "Packages" ) )
109             {
110                 jdpackage = new JDPackage();
111 
112                 if ( attrs != null )
113                 {
114                     jdpackage.setPackageName( attrs.getValue( 0 ) );
115                 }
116             }
117             else if ( isParentElement( "Cycles" ) )
118             {
119                 cyclePackage = new CyclePackage();
120 
121                 if ( attrs != null )
122                 {
123                     cyclePackage.setName( attrs.getValue( 0 ) );
124                 }
125             }
126         }
127         else if ( qName.equals( "Stats" ) )
128         {
129             stats = new Stats();
130         }
131         else if ( qName.equals( "Cycles" ) )
132         {
133             cycles = new ArrayList<CyclePackage>();
134         }
135     }
136 
137     /*
138      * (non-Javadoc)
139      * @see org.xml.sax.helpers.DefaultHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
140      */
141     public void endElement( String namespaceURI, String sName, String qName )
142         throws SAXException
143     {
144 
145         String elementValue = buffer != null ? buffer.toString().trim() : null;
146 
147         if ( qName.equals( "Package" ) )
148         {
149             if ( isParentElement( "Packages" ) )
150             {
151                 if ( errFlag == false )
152                 {
153                     jdpackage.setStats( stats );
154 
155                     packages.add( jdpackage );
156                 }
157                 errFlag = false;
158             }
159             else if ( isParentElement( "DependsUpon" ) )
160             {
161                 jdpackage.addDependsUpon( elementValue );
162             }
163             else if ( isParentElement( "UsedBy" ) )
164             {
165                 jdpackage.addUsedBy( elementValue );
166             }
167             else if ( isParentElement( "Package" ) )
168             {
169                 cyclePackage.addPackageList( elementValue );
170             }
171             else if ( isParentElement( "Cycles" ) )
172             {
173                 cycles.add( cyclePackage );
174             }
175         }
176         else if ( qName.equals( "TotalClasses" ) )
177         {
178             stats.setTotalClasses( elementValue );
179         }
180         else if ( qName.equals( "ConcreteClasses" ) )
181         {
182             if ( isParentElement( "Stats" ) )
183             {
184                 stats.setConcreteClasses( elementValue );
185             }
186         }
187         else if ( qName.equals( "AbstractClasses" ) )
188         {
189             if ( isParentElement( "Stats" ) )
190             {
191                 stats.setAbstractClasses( elementValue );
192             }
193         }
194         else if ( qName.equals( "Ca" ) )
195         {
196             stats.setCa( elementValue );
197         }
198         else if ( qName.equals( "Ce" ) )
199         {
200             stats.setCe( elementValue );
201         }
202         else if ( qName.equals( "A" ) )
203         {
204             stats.setA( elementValue );
205         }
206         else if ( qName.equals( "I" ) )
207         {
208             stats.setI( elementValue );
209         }
210         else if ( qName.equals( "D" ) )
211         {
212             stats.setD( elementValue );
213         }
214         else if ( qName.equals( "V" ) )
215         {
216             stats.setV( elementValue );
217         }
218         else if ( qName.equals( "Class" ) )
219         {
220             if ( isParentElement( "AbstractClasses" ) )
221             {
222                 jdpackage.addAbstractClasses( elementValue );
223             }
224             else if ( isParentElement( "ConcreteClasses" ) )
225             {
226                 jdpackage.addConcreteClasses( elementValue );
227             }
228         }
229         else if ( qName.equals( "error" ) )
230         {
231             if ( isParentElement( "Package" ) )
232             {
233                 errFlag = true;
234             }
235         }
236 
237         if ( stack.size() != 0 )
238         {
239             /* Remove element name in stack */
240             stack.pop();
241         }
242 
243         buffer = null;
244     }
245 
246     /*
247      * (non-Javadoc)
248      * @see org.xml.sax.helpers.DefaultHandler#characters(char[], int, int)
249      */
250     public void characters( char[] buff, int offset, int len )
251         throws SAXException
252     {
253         if ( buffer != null )
254         {
255             buffer.append( buff, offset, len );
256         }
257     }
258 
259     /**
260      * @return Packages.
261      */
262     public List<JDPackage> getPackages()
263     {
264         return this.packages;
265     }
266 
267     /**
268      * @return stats.
269      */
270     public Stats getStats()
271     {
272         return this.stats;
273     }
274 
275     /**
276      * @return parent index.
277      */
278     private int getParentIndex()
279     {
280         int parentIndex = 0;
281 
282         parentIndex = stack.size() - 2;
283 
284         return parentIndex;
285     }
286 
287     /**
288      * @param parentElement
289      * @return true otherwise false.
290      */
291     private boolean isParentElement( String parentElement )
292     {
293         boolean isParent = false;
294 
295         isParent = stack.get( getParentIndex() ).toString().equals( parentElement );
296 
297         return isParent;
298     }
299 }