001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: *
017: */
018: package org.apache.ivy.plugins.parser.m2;
019:
020: import java.io.IOException;
021: import java.net.URL;
022: import java.util.HashMap;
023: import java.util.Iterator;
024: import java.util.LinkedList;
025: import java.util.List;
026: import java.util.Map;
027:
028: import org.apache.ivy.core.IvyPatternHelper;
029: import org.apache.ivy.core.module.id.ModuleId;
030: import org.apache.ivy.core.module.id.ModuleRevisionId;
031: import org.apache.ivy.plugins.repository.Resource;
032: import org.apache.ivy.util.XMLHelper;
033: import org.w3c.dom.Document;
034: import org.w3c.dom.Element;
035: import org.w3c.dom.Node;
036: import org.w3c.dom.NodeList;
037: import org.xml.sax.SAXException;
038: import org.xml.sax.SAXParseException;
039:
040: /**
041: * Provides the method to read some data out of the DOM tree of a pom
042: * file.
043: */
044: public class PomReader {
045:
046: private static final String PACKAGING = "packaging";
047: private static final String DEPENDENCY = "dependency";
048: private static final String DEPENDENCIES = "dependencies";
049: private static final String DEPENDENCY_MGT = "dependencyManagement";
050: private static final String PROJECT = "project";
051: private static final String GROUP_ID = "groupId";
052: private static final String ARTIFACT_ID = "artifactId";
053: private static final String VERSION = "version";
054: private static final String PARENT = "parent";
055: private static final String SCOPE = "scope";
056: private static final String CLASSIFIER = "classifier";
057: private static final String OPTIONAL = "optional";
058: private static final String EXCLUSIONS = "exclusions";
059: private static final String EXCLUSION = "exclusion";
060: private static final String DISTRIBUTION_MGT = "distributionManagement";
061: private static final String RELOCATION = "relocation";
062: private static final String PROPERTIES = "properties";
063:
064: private HashMap properties = new HashMap();
065:
066: private final Element projectElement;
067: private final Element parentElement;
068:
069: public PomReader(URL descriptorURL, Resource res)
070: throws IOException, SAXException {
071: Document pomDomDoc = XMLHelper.parseToDom(descriptorURL, res);
072: projectElement = pomDomDoc.getDocumentElement();
073: if (!PROJECT.equals(projectElement.getNodeName())) {
074: throw new SAXParseException("project must be the root tag",
075: res.getName(), res.getName(), 0, 0);
076: }
077: parentElement = getFirstChildElement(projectElement, PARENT);
078: //TODO read the properties because it must be used to interpret every other field
079: }
080:
081: public boolean hasParent() {
082: return parentElement != null;
083: }
084:
085: /**
086: * Add a property if not yet set and value is not null.
087: * This garantee that property keep the first value that is put on it and that the properties
088: * are never null.
089: */
090: public void setProperty(String prop, String val) {
091: if (!properties.containsKey(prop) && val != null) {
092: properties.put(prop, val);
093: }
094: }
095:
096: public String getGroupId() {
097: String groupId = getFirstChildText(projectElement, GROUP_ID);
098: if (groupId == null) {
099: groupId = getFirstChildText(parentElement, GROUP_ID);
100: }
101: return replaceProps(groupId);
102:
103: }
104:
105: public String getParentGroupId() {
106: String groupId = getFirstChildText(parentElement, GROUP_ID);
107: if (groupId == null) {
108: groupId = getFirstChildText(projectElement, GROUP_ID);
109: }
110: return replaceProps(groupId);
111: }
112:
113: public String getArtifactId() {
114: String val = getFirstChildText(projectElement, ARTIFACT_ID);
115: if (val == null) {
116: val = getFirstChildText(parentElement, ARTIFACT_ID);
117: }
118: return replaceProps(val);
119: }
120:
121: public String getParentArtifactId() {
122: String val = getFirstChildText(parentElement, ARTIFACT_ID);
123: if (val == null) {
124: val = getFirstChildText(projectElement, ARTIFACT_ID);
125: }
126: return replaceProps(val);
127: }
128:
129: public String getVersion() {
130: String val = getFirstChildText(projectElement, VERSION);
131: if (val == null) {
132: val = getFirstChildText(parentElement, VERSION);
133: }
134: return replaceProps(val);
135: }
136:
137: public String getParentVersion() {
138: String val = getFirstChildText(parentElement, VERSION);
139: if (val == null) {
140: val = getFirstChildText(projectElement, VERSION);
141: }
142: return replaceProps(val);
143: }
144:
145: public String getPackaging() {
146: String val = getFirstChildText(projectElement, PACKAGING);
147: if (val == null) {
148: val = "jar";
149: }
150: return val;
151: }
152:
153: public ModuleRevisionId getRelocation() {
154: Element distrMgt = getFirstChildElement(projectElement,
155: DISTRIBUTION_MGT);
156: Element relocation = getFirstChildElement(distrMgt, RELOCATION);
157: if (relocation == null) {
158: return null;
159: } else {
160: String relocGroupId = getFirstChildText(relocation,
161: GROUP_ID);
162: String relocArtId = getFirstChildText(relocation,
163: ARTIFACT_ID);
164: String relocVersion = getFirstChildText(relocation, VERSION);
165: relocGroupId = relocGroupId == null ? getGroupId()
166: : relocGroupId;
167: relocArtId = relocArtId == null ? getArtifactId()
168: : relocArtId;
169: relocVersion = relocVersion == null ? getVersion()
170: : relocVersion;
171: return ModuleRevisionId.newInstance(relocGroupId,
172: relocArtId, relocVersion);
173: }
174: }
175:
176: public List /* <PomDependencyData> */getDependencies() {
177: Element dependenciesElement = getFirstChildElement(
178: projectElement, DEPENDENCIES);
179: LinkedList dependencies = new LinkedList();
180: if (dependenciesElement != null) {
181: NodeList childs = dependenciesElement.getChildNodes();
182: for (int i = 0; i < childs.getLength(); i++) {
183: Node node = childs.item(i);
184: if (node instanceof Element
185: && DEPENDENCY.equals(node.getNodeName())) {
186: dependencies.add(new PomDependencyData(
187: (Element) node));
188: }
189: }
190: }
191: return dependencies;
192: }
193:
194: public List /* <PomDependencyMgt> */getDependencyMgt() {
195: Element dependenciesElement = getFirstChildElement(
196: projectElement, DEPENDENCY_MGT);
197: dependenciesElement = getFirstChildElement(dependenciesElement,
198: DEPENDENCIES);
199: LinkedList dependencies = new LinkedList();
200: if (dependenciesElement != null) {
201: NodeList childs = dependenciesElement.getChildNodes();
202: for (int i = 0; i < childs.getLength(); i++) {
203: Node node = childs.item(i);
204: if (node instanceof Element
205: && DEPENDENCY.equals(node.getNodeName())) {
206: dependencies.add(new PomDependencyMgt(
207: (Element) node));
208: }
209: }
210: }
211: return dependencies;
212: }
213:
214: public class PomDependencyMgt {
215: private final Element depElement;
216:
217: PomDependencyMgt(Element depElement) {
218: this .depElement = depElement;
219: }
220:
221: public String getGroupId() {
222: String val = getFirstChildText(depElement, GROUP_ID);
223: return replaceProps(val);
224: }
225:
226: public String getArtifaceId() {
227: String val = getFirstChildText(depElement, ARTIFACT_ID);
228: return replaceProps(val);
229: }
230:
231: public String getVersion() {
232: String val = getFirstChildText(depElement, VERSION);
233: return replaceProps(val);
234: }
235:
236: }
237:
238: public class PomDependencyData extends PomDependencyMgt {
239: private final Element depElement;
240:
241: PomDependencyData(Element depElement) {
242: super (depElement);
243: this .depElement = depElement;
244: }
245:
246: public String getScope() {
247: String val = getFirstChildText(depElement, SCOPE);
248: if (val == null) {
249: return "compile";
250: } else {
251: return replaceProps(val);
252: }
253: }
254:
255: public String getClassifier() {
256: String val = getFirstChildText(depElement, CLASSIFIER);
257: return replaceProps(val);
258: }
259:
260: public boolean isOptional() {
261: return getFirstChildElement(depElement, OPTIONAL) != null;
262: }
263:
264: public List /*<ModuleId>*/getExcludedModules() {
265: Element exclusionsElement = getFirstChildElement(
266: depElement, EXCLUSIONS);
267: LinkedList exclusions = new LinkedList();
268: if (exclusionsElement != null) {
269: NodeList childs = exclusionsElement.getChildNodes();
270: for (int i = 0; i < childs.getLength(); i++) {
271: Node node = childs.item(i);
272: if (node instanceof Element
273: && EXCLUSION.equals(node.getNodeName())) {
274: String groupId = getFirstChildText(
275: (Element) node, GROUP_ID);
276: String arteficatId = getFirstChildText(
277: (Element) node, ARTIFACT_ID);
278: exclusions.add(ModuleId.newInstance(groupId,
279: arteficatId));
280: }
281: }
282: }
283: return exclusions;
284: }
285:
286: }
287:
288: /**
289: * @return the content of the properties tag into the pom.
290: */
291: public Map/* <String,String> */getPomProperties() {
292: Map pomProperties = new HashMap();
293: Element propsEl = getFirstChildElement(projectElement,
294: PROPERTIES);
295: if (propsEl != null) {
296: propsEl.normalize();
297: }
298: for (Iterator it = getAllChilds(propsEl).iterator(); it
299: .hasNext();) {
300: Element prop = (Element) it.next();
301: pomProperties.put(prop.getNodeName(), getTextContent(prop));
302: }
303: return pomProperties;
304: }
305:
306: private String replaceProps(String val) {
307: if (val == null) {
308: return null;
309: } else {
310: return IvyPatternHelper
311: .substituteVariables(val, properties).trim();
312: }
313: }
314:
315: private static String getTextContent(Element element) {
316: StringBuffer result = new StringBuffer();
317:
318: NodeList childNodes = element.getChildNodes();
319: for (int i = 0; i < childNodes.getLength(); i++) {
320: Node child = childNodes.item(i);
321:
322: switch (child.getNodeType()) {
323: case Node.CDATA_SECTION_NODE:
324: case Node.TEXT_NODE:
325: result.append(child.getNodeValue());
326: break;
327: }
328: }
329:
330: return result.toString();
331: }
332:
333: private static String getFirstChildText(Element parentElem,
334: String name) {
335: Element node = getFirstChildElement(parentElem, name);
336: if (node != null) {
337: return getTextContent(node);
338: } else {
339: return null;
340: }
341: }
342:
343: private static Element getFirstChildElement(Element parentElem,
344: String name) {
345: if (parentElem == null) {
346: return null;
347: }
348: NodeList childs = parentElem.getChildNodes();
349: for (int i = 0; i < childs.getLength(); i++) {
350: Node node = childs.item(i);
351: if (node instanceof Element
352: && name.equals(node.getNodeName())) {
353: return (Element) node;
354: }
355: }
356: return null;
357: }
358:
359: private static List/* <Element> */getAllChilds(Element parent) {
360: List r = new LinkedList();
361: if (parent != null) {
362: NodeList childs = parent.getChildNodes();
363: for (int i = 0; i < childs.getLength(); i++) {
364: Node node = childs.item(i);
365: if (node instanceof Element) {
366: r.add(node);
367: }
368: }
369: }
370: return r;
371: }
372:
373: }
|