View Javadoc
1   /*
2    * This file is part of dependency-check-core.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   *
16   * Copyright (c) 2015 Jeremy Long. All Rights Reserved.
17   */
18  package org.owasp.dependencycheck.xml.pom;
19  
20  import java.util.ArrayDeque;
21  import java.util.Deque;
22  import org.xml.sax.Attributes;
23  import org.xml.sax.SAXException;
24  import org.xml.sax.helpers.DefaultHandler;
25  
26  /**
27   * A handler to read the pom.xml model.
28   *
29   * @author Jeremy Long
30   */
31  public class PomHandler extends DefaultHandler {
32  
33      /**
34       * The project element.
35       */
36      public static final String PROJECT = "project";
37      /**
38       * The artifactId element.
39       */
40      public static final String GROUPID = "groupId";
41      /**
42       * The artifactId element.
43       */
44      public static final String ARTIFACTID = "artifactId";
45      /**
46       * The version element.
47       */
48      public static final String VERSION = "version";
49      /**
50       * The parent element.
51       */
52      public static final String PARENT = "parent";
53      /**
54       * The name element.
55       */
56      public static final String NAME = "name";
57      /**
58       * The organization element.
59       */
60      public static final String ORGANIZATION = "organization";
61      /**
62       * The description element.
63       */
64      public static final String DESCRIPTION = "description";
65      /**
66       * The licenses element.
67       */
68      public static final String LICENSES = "licenses";
69      /**
70       * The license element.
71       */
72      public static final String LICENSE = "license";
73      /**
74       * The url element.
75       */
76      public static final String URL = "url";
77  
78      /**
79       * The pom model.
80       */
81      private final Model model = new Model();
82  
83      /**
84       * Returns the model obtained from the pom.xml.
85       *
86       * @return the model object
87       */
88      public Model getModel() {
89          return model;
90      }
91      /**
92       * The stack of elements processed; used to determine the parent node.
93       */
94      private final Deque<String> stack = new ArrayDeque<String>();
95      /**
96       * The license object.
97       */
98      private License license = null;
99  
100     /**
101      * The current node text being extracted from the element.
102      */
103     private StringBuilder currentText;
104 
105     /**
106      * Handles the start element event.
107      *
108      * @param uri the uri of the element being processed
109      * @param localName the local name of the element being processed
110      * @param qName the qName of the element being processed
111      * @param attributes the attributes of the element being processed
112      * @throws SAXException thrown if there is an exception processing
113      */
114     @Override
115     public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
116         currentText = new StringBuilder();
117         stack.push(qName);
118         if (LICENSE.equals(qName)) {
119             license = new License();
120         }
121     }
122 
123     /**
124      * Handles the end element event.
125      *
126      * @param uri the URI of the element
127      * @param localName the local name of the element
128      * @param qName the qName of the element
129      * @throws SAXException thrown if there is an exception processing
130      */
131     @Override
132     public void endElement(String uri, String localName, String qName) throws SAXException {
133         stack.pop();
134         final String parentNode = stack.peek();
135         if (PROJECT.equals(parentNode)) {
136             if (GROUPID.equals(qName)) {
137                 model.setGroupId(currentText.toString());
138             } else if (ARTIFACTID.equals(qName)) {
139                 model.setArtifactId(currentText.toString());
140             } else if (VERSION.equals(qName)) {
141                 model.setVersion(currentText.toString());
142             } else if (NAME.equals(qName)) {
143                 model.setName(currentText.toString());
144             } else if (ORGANIZATION.equals(qName)) {
145                 model.setOrganization(currentText.toString());
146             } else if (DESCRIPTION.equals(qName)) {
147                 model.setDescription(currentText.toString());
148             } else if (URL.equals(qName)) {
149                 model.setProjectURL(currentText.toString());
150             }
151         } else if (PARENT.equals(parentNode)) {
152             if (GROUPID.equals(qName)) {
153                 model.setParentGroupId(currentText.toString());
154             } else if (ARTIFACTID.equals(qName)) {
155                 model.setParentArtifactId(currentText.toString());
156             } else if (VERSION.equals(qName)) {
157                 model.setParentVersion(currentText.toString());
158             }
159         } else if (LICENSE.equals(parentNode)) {
160             if (license != null) {
161                 if (NAME.equals(qName)) {
162                     license.setName(currentText.toString());
163                 } else if (URL.equals(qName)) {
164                     license.setUrl(currentText.toString());
165                 }
166                 //} else {
167                 //TODO add error logging
168             }
169         } else if (LICENSES.equals(parentNode)) {
170             if (LICENSE.equals(qName)) {
171                 if (license != null) {
172                     model.addLicense(license);
173                     //} else {
174                     //TODO add error logging
175                 }
176             }
177         }
178     }
179 
180     /**
181      * Collects the body text of the node being processed.
182      *
183      * @param ch the char array of text
184      * @param start the start position to copy text from in the char array
185      * @param length the number of characters to copy from the char array
186      * @throws SAXException thrown if there is a parsing exception
187      */
188     @Override
189     public void characters(char[] ch, int start, int length) throws SAXException {
190         currentText.append(ch, start, length);
191     }
192 }