2
* Licensed to the Apache Software Foundation (ASF) under one or more
3
* contributor license agreements. See the NOTICE file distributed with
4
* this work for additional information regarding copyright ownership.
5
* The ASF licenses this file to You under the Apache License, Version 2.0
6
* (the "License"); you may not use this file except in compliance with
7
* the License. You may obtain a copy of the License at
9
* http://www.apache.org/licenses/LICENSE-2.0
11
* Unless required by applicable law or agreed to in writing, software
12
* distributed under the License is distributed on an "AS IS" BASIS,
13
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
* See the License for the specific language governing permissions and
15
* limitations under the License.
18
package org.apache.ivy.plugins.report;
21
import java.text.ParseException;
22
import java.util.ArrayList;
23
import java.util.Date;
24
import java.util.HashMap;
25
import java.util.Iterator;
26
import java.util.List;
28
import java.util.SortedMap;
29
import java.util.TreeMap;
31
import javax.xml.parsers.SAXParser;
32
import javax.xml.parsers.SAXParserFactory;
34
import org.apache.ivy.Ivy;
35
import org.apache.ivy.core.cache.ArtifactOrigin;
36
import org.apache.ivy.core.module.descriptor.Artifact;
37
import org.apache.ivy.core.module.descriptor.DefaultArtifact;
38
import org.apache.ivy.core.module.id.ModuleRevisionId;
39
import org.apache.ivy.core.report.ArtifactDownloadReport;
40
import org.apache.ivy.core.report.DownloadStatus;
41
import org.apache.ivy.core.report.MetadataArtifactDownloadReport;
42
import org.apache.ivy.util.extendable.ExtendableItemHelper;
43
import org.xml.sax.Attributes;
44
import org.xml.sax.SAXException;
45
import org.xml.sax.helpers.DefaultHandler;
47
public class XmlReportParser {
48
private static class SaxXmlReportParser {
49
private final class XmlReportParserHandler extends DefaultHandler {
50
private String organisation;
52
private String module;
54
private String branch;
56
private String revision;
64
private ModuleRevisionId mrid;
66
private boolean isDefault;
68
private SortedMap revisionsMap = new TreeMap(); // Use a TreeMap to order by
70
private List revisionArtifacts = null;
72
public void startElement(String uri, String localName, String qName,
73
Attributes attributes) throws SAXException {
74
if ("module".equals(qName)) {
75
organisation = attributes.getValue("organisation");
76
module = attributes.getValue("name");
77
} else if ("revision".equals(qName)) {
78
revisionArtifacts = new ArrayList();
79
branch = attributes.getValue("branch");
80
revision = attributes.getValue("name");
81
isDefault = Boolean.valueOf(attributes.getValue("default")).booleanValue();
82
// retrieve position from file. If no position is found, it may be an old
83
// report generated with a previous version,
84
// in which case, we put it at the last position
85
String pos = attributes.getValue("position");
86
position = pos == null ? getMaxPos() + 1 : Integer.valueOf(pos).intValue();
87
if (attributes.getValue("error") != null
88
|| attributes.getValue("evicted") != null) {
91
revisionsMap.put(new Integer(position), revisionArtifacts);
92
mrid = ModuleRevisionId.newInstance(organisation, module, branch,
93
revision, ExtendableItemHelper.getExtraAttributes(attributes,
97
defaultMrids.add(mrid);
99
Artifact metadataArtifact =
100
DefaultArtifact.newIvyArtifact(mrid, pubdate);
101
MetadataArtifactDownloadReport madr =
102
new MetadataArtifactDownloadReport(metadataArtifact);
103
metadataReports.put(mrid, madr);
107
pubdate = Ivy.DATE_FORMAT.parse(attributes.getValue("pubdate"));
109
} catch (ParseException e) {
110
throw new IllegalArgumentException("invalid publication date for "
111
+ organisation + " " + module + " " + revision + ": "
112
+ attributes.getValue("pubdate"));
115
} else if ("metadata-artifact".equals(qName)) {
119
MetadataArtifactDownloadReport madr =
120
(MetadataArtifactDownloadReport) metadataReports.get(mrid);
122
madr.setDownloadStatus(
123
DownloadStatus.fromString(attributes.getValue("status")));
124
madr.setDownloadDetails(attributes.getValue("details"));
125
madr.setSize(Long.parseLong(attributes.getValue("size")));
126
madr.setDownloadTimeMillis(Long.parseLong(attributes.getValue("time")));
127
madr.setSearched(parseBoolean(attributes.getValue("searched")));
128
if (attributes.getValue("location") != null) {
129
madr.setLocalFile(new File(attributes.getValue("location")));
131
if (attributes.getValue("original-local-location") != null) {
132
madr.setOriginalLocalFile(
133
new File(attributes.getValue("original-local-location")));
135
if (attributes.getValue("origin-location") != null) {
136
if (ArtifactOrigin.isUnknown(attributes.getValue("origin-location"))) {
137
madr.setArtifactOrigin(ArtifactOrigin.unkwnown(madr.getArtifact()));
139
madr.setArtifactOrigin(
142
parseBoolean(attributes.getValue("origin-is-local")),
143
attributes.getValue("origin-location")));
147
} else if ("artifact".equals(qName)) {
151
String status = attributes.getValue("status");
152
String artifactName = attributes.getValue("name");
153
String type = attributes.getValue("type");
154
String ext = attributes.getValue("ext");
155
Artifact artifact = new DefaultArtifact(mrid, pubdate, artifactName,
156
type, ext, ExtendableItemHelper.getExtraAttributes(attributes,
158
ArtifactDownloadReport aReport = new ArtifactDownloadReport(artifact);
159
aReport.setDownloadStatus(DownloadStatus.fromString(status));
160
aReport.setDownloadDetails(attributes.getValue("details"));
161
aReport.setSize(Long.parseLong(attributes.getValue("size")));
162
aReport.setDownloadTimeMillis(Long.parseLong(attributes.getValue("time")));
163
if (attributes.getValue("location") != null) {
164
aReport.setLocalFile(new File(attributes.getValue("location")));
166
revisionArtifacts.add(aReport);
167
} else if ("origin-location".equals(qName)) {
171
ArtifactDownloadReport aReport = (ArtifactDownloadReport)
172
revisionArtifacts.get(revisionArtifacts.size() - 1);
174
if (ArtifactOrigin.isUnknown(attributes.getValue("location"))) {
175
aReport.setArtifactOrigin(ArtifactOrigin.unkwnown(aReport.getArtifact()));
177
aReport.setArtifactOrigin(
179
aReport.getArtifact(),
180
parseBoolean(attributes.getValue("is-local")),
181
attributes.getValue("location")));
183
} else if ("info".equals(qName)) {
184
String organisation = attributes.getValue("organisation");
185
String name = attributes.getValue("module");
186
String branch = attributes.getValue("branch");
187
String revision = attributes.getValue("revision");
188
Map extraAttributes = new HashMap();
189
for (int i = 0; i < attributes.getLength(); i++) {
190
String attName = attributes.getQName(i);
191
if (attName.startsWith("extra-")) {
192
String extraAttrName = attName.substring("extra-".length());
193
String extraAttrValue = attributes.getValue(i);
194
extraAttributes.put(extraAttrName, extraAttrValue);
197
mRevisionId = ModuleRevisionId.newInstance(organisation, name, branch,
198
revision, extraAttributes);
202
public void endElement(String uri, String localName, String qname)
203
throws SAXException {
204
if ("dependencies".equals(qname)) {
205
// add the artifacts in the correct order
206
for (Iterator it = revisionsMap.values().iterator(); it.hasNext();) {
207
List artifactReports = (List) it.next();
208
SaxXmlReportParser.this.artifactReports.addAll(artifactReports);
209
for (Iterator iter = artifactReports.iterator(); iter.hasNext();) {
210
ArtifactDownloadReport artifactReport
211
= (ArtifactDownloadReport) iter.next();
212
if (artifactReport.getDownloadStatus() != DownloadStatus.FAILED) {
213
artifacts.add(artifactReport.getArtifact());
221
private int getMaxPos() {
222
return revisionsMap.isEmpty() ? -1 : ((Integer) revisionsMap.keySet()
223
.toArray()[revisionsMap.size() - 1]).intValue();
227
private List/*<ModuleRevisionId>*/ mrids;
229
private List/*<ModuleRevisionId>*/ defaultMrids;
231
private List/*<ModuleRevisionId>*/ realMrids;
233
private List/*<Artifact>*/ artifacts;
235
private List/*<ArtifactDownloadReport>*/ artifactReports;
237
private Map/*<ModuleRevisionId,MetadataArtifactDownloadReport>*/ metadataReports;
239
private ModuleRevisionId mRevisionId;
243
SaxXmlReportParser(File report) {
244
artifacts = new ArrayList();
245
artifactReports = new ArrayList();
246
mrids = new ArrayList();
247
defaultMrids = new ArrayList();
248
realMrids = new ArrayList();
249
metadataReports = new HashMap();
250
this.report = report;
253
public void parse() throws Exception {
254
SAXParser saxParser = SAXParserFactory.newInstance().newSAXParser();
255
saxParser.parse(report, new XmlReportParserHandler());
258
private static boolean parseBoolean(String str) {
259
return (str != null) && str.equalsIgnoreCase("true");
262
public List getArtifacts() {
266
public List getArtifactReports() {
267
return artifactReports;
270
public List getModuleRevisionIds() {
274
public List getRealModuleRevisionIds() {
278
public ModuleRevisionId getResolvedModule() {
282
public MetadataArtifactDownloadReport getMetadataArtifactReport(ModuleRevisionId id) {
283
return (MetadataArtifactDownloadReport) metadataReports.get(id);
287
private SaxXmlReportParser parser = null;
289
public void parse(File report) throws ParseException {
290
if (!report.exists()) {
291
throw new IllegalStateException("Report file '" + report.getAbsolutePath()
292
+ "' does not exist.");
295
parser = new SaxXmlReportParser(report);
298
} catch (Exception e) {
299
ParseException pe = new ParseException("failed to parse report: " + report + ": "
300
+ e.getMessage(), 0);
306
public Artifact[] getArtifacts() {
307
return (Artifact[]) parser.getArtifacts().toArray(
308
new Artifact[parser.getArtifacts().size()]);
311
public ArtifactDownloadReport[] getArtifactReports() {
312
return (ArtifactDownloadReport[]) parser.getArtifactReports().toArray(
313
new ArtifactDownloadReport[parser.getArtifactReports().size()]);
316
public ModuleRevisionId[] getDependencyRevisionIds() {
317
return (ModuleRevisionId[]) parser.getModuleRevisionIds().toArray(
318
new ModuleRevisionId[parser.getModuleRevisionIds().size()]);
321
public ModuleRevisionId[] getRealDependencyRevisionIds() {
322
return (ModuleRevisionId[]) parser.getRealModuleRevisionIds().toArray(
323
new ModuleRevisionId[parser.getRealModuleRevisionIds().size()]);
326
public MetadataArtifactDownloadReport getMetadataArtifactReport(ModuleRevisionId id) {
327
return parser.getMetadataArtifactReport(id);
331
* Returns the <tt>ModuleRevisionId</tt> of the resolved module.
333
public ModuleRevisionId getResolvedModule() {
334
return parser.getResolvedModule();