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.report;
019:
020: import java.io.OutputStream;
021: import java.io.PrintWriter;
022: import java.util.ArrayList;
023: import java.util.Collection;
024: import java.util.Date;
025: import java.util.Iterator;
026: import java.util.List;
027: import java.util.Map;
028: import java.util.Map.Entry;
029:
030: import org.apache.ivy.Ivy;
031: import org.apache.ivy.core.cache.ArtifactOrigin;
032: import org.apache.ivy.core.module.descriptor.License;
033: import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
034: import org.apache.ivy.core.module.id.ModuleId;
035: import org.apache.ivy.core.module.id.ModuleRevisionId;
036: import org.apache.ivy.core.report.ArtifactDownloadReport;
037: import org.apache.ivy.core.report.ConfigurationResolveReport;
038: import org.apache.ivy.core.report.MetadataArtifactDownloadReport;
039: import org.apache.ivy.core.resolve.IvyNode;
040: import org.apache.ivy.core.resolve.IvyNodeCallers.Caller;
041: import org.apache.ivy.core.resolve.IvyNodeEviction.EvictionData;
042: import org.apache.ivy.util.StringUtils;
043: import org.apache.ivy.util.XMLHelper;
044:
045: /**
046: * XmlReportWriter allows to write ResolveReport in an xml format.
047: */
048: public class XmlReportWriter {
049:
050: public void output(ConfigurationResolveReport report,
051: OutputStream stream) {
052: output(report, new String[] { report.getConfiguration() },
053: stream);
054: }
055:
056: public void output(ConfigurationResolveReport report,
057: String[] confs, OutputStream stream) {
058: PrintWriter out = new PrintWriter(stream);
059: ModuleRevisionId mrid = report.getModuleDescriptor()
060: .getModuleRevisionId();
061: out.println("<?xml version=\"1.0\" encoding=\"ISO-8859-1\"?>");
062: out
063: .println("<?xml-stylesheet type=\"text/xsl\" href=\"ivy-report.xsl\"?>");
064: out.println("<ivy-report version=\"1.0\">");
065: out.println("\t<info");
066: out.println("\t\torganisation=\""
067: + XMLHelper.escape(mrid.getOrganisation()) + "\"");
068: out.println("\t\tmodule=\"" + XMLHelper.escape(mrid.getName())
069: + "\"");
070: out.println("\t\trevision=\""
071: + XMLHelper.escape(mrid.getRevision()) + "\"");
072: if (mrid.getBranch() != null) {
073: out.println("\t\tbranch=\""
074: + XMLHelper.escape(mrid.getBranch()) + "\"");
075: }
076: Map extraAttributes = mrid.getExtraAttributes();
077: for (Iterator it = extraAttributes.entrySet().iterator(); it
078: .hasNext();) {
079: Map.Entry entry = (Entry) it.next();
080: out.println("\t\textra-" + entry.getKey() + "=\""
081: + XMLHelper.escape(entry.getValue().toString())
082: + "\"");
083: }
084: out.println("\t\tconf=\""
085: + XMLHelper.escape(report.getConfiguration()) + "\"");
086: out.println("\t\tconfs=\""
087: + XMLHelper.escape(StringUtils.join(confs, ", "))
088: + "\"");
089: out.println("\t\tdate=\""
090: + Ivy.DATE_FORMAT.format(report.getDate()) + "\"/>");
091:
092: out.println("\t<dependencies>");
093:
094: // create a list of ModuleRevisionIds indicating the position for each dependency
095: List dependencies = new ArrayList(report.getModuleRevisionIds());
096:
097: for (Iterator iter = report.getModuleIds().iterator(); iter
098: .hasNext();) {
099: ModuleId mid = (ModuleId) iter.next();
100: out.println("\t\t<module organisation=\""
101: + XMLHelper.escape(mid.getOrganisation()) + "\""
102: + " name=\"" + XMLHelper.escape(mid.getName())
103: + "\" >");
104: for (Iterator it2 = report.getNodes(mid).iterator(); it2
105: .hasNext();) {
106: IvyNode dep = (IvyNode) it2.next();
107: ouputRevision(report, out, dependencies, dep);
108: }
109: out.println("\t\t</module>");
110: }
111: out.println("\t</dependencies>");
112: out.println("</ivy-report>");
113: out.flush();
114: }
115:
116: private void ouputRevision(ConfigurationResolveReport report,
117: PrintWriter out, List dependencies, IvyNode dep) {
118: Map extraAttributes;
119: ModuleDescriptor md = null;
120: if (dep.getModuleRevision() != null) {
121: md = dep.getModuleRevision().getDescriptor();
122: }
123: StringBuffer details = new StringBuffer();
124: if (dep.isLoaded()) {
125: details.append(" status=\"");
126: details.append(XMLHelper.escape(dep.getDescriptor()
127: .getStatus()));
128: details.append("\" pubdate=\"");
129: details.append(Ivy.DATE_FORMAT.format(new Date(dep
130: .getPublication())));
131: details.append("\" resolver=\"");
132: details.append(XMLHelper.escape(dep.getModuleRevision()
133: .getResolver().getName()));
134: details.append("\" artresolver=\"");
135: details.append(XMLHelper.escape(dep.getModuleRevision()
136: .getArtifactResolver().getName()));
137: details.append("\"");
138: }
139: if (dep.isEvicted(report.getConfiguration())) {
140: EvictionData ed = dep.getEvictedData(report
141: .getConfiguration());
142: if (ed.getConflictManager() != null) {
143: details.append(" evicted=\"").append(
144: XMLHelper.escape(ed.getConflictManager()
145: .toString())).append("\"");
146: } else {
147: details.append(" evicted=\"transitive\"");
148: }
149: details.append(" evicted-reason=\"").append(
150: XMLHelper.escape(ed.getDetail() == null ? "" : ed
151: .getDetail())).append("\"");
152: }
153: if (dep.hasProblem()) {
154: details.append(" error=\"").append(
155: XMLHelper.escape(dep.getProblem().getMessage()))
156: .append("\"");
157: }
158: if (md != null && md.getHomePage() != null) {
159: details.append(" homepage=\"").append(
160: XMLHelper.escape(md.getHomePage())).append("\"");
161: }
162: extraAttributes = md != null ? md.getExtraAttributes() : dep
163: .getResolvedId().getExtraAttributes();
164: for (Iterator iterator = extraAttributes.keySet().iterator(); iterator
165: .hasNext();) {
166: String attName = (String) iterator.next();
167: details.append(" extra-").append(attName).append("=\"")
168: .append(
169: XMLHelper.escape(extraAttributes.get(
170: attName).toString())).append("\"");
171: }
172: String defaultValue = dep.getDescriptor() != null ? " default=\""
173: + dep.getDescriptor().isDefault() + "\""
174: : "";
175: int position = dependencies.indexOf(dep.getResolvedId());
176: out.println("\t\t\t<revision name=\""
177: + XMLHelper.escape(dep.getResolvedId().getRevision())
178: + "\""
179: + (dep.getResolvedId().getBranch() == null ? ""
180: : " branch=\""
181: + XMLHelper.escape(dep.getResolvedId()
182: .getBranch()) + "\"")
183: + details
184: + " downloaded=\""
185: + dep.isDownloaded()
186: + "\""
187: + " searched=\""
188: + dep.isSearched()
189: + "\""
190: + defaultValue
191: + " conf=\""
192: + toString(dep.getConfigurations(report
193: .getConfiguration())) + "\"" + " position=\""
194: + position + "\">");
195: if (md != null) {
196: License[] licenses = md.getLicenses();
197: for (int i = 0; i < licenses.length; i++) {
198: String lurl;
199: if (licenses[i].getUrl() != null) {
200: lurl = " url=\""
201: + XMLHelper.escape(licenses[i].getUrl())
202: + "\"";
203: } else {
204: lurl = "";
205: }
206: out.println("\t\t\t\t<license name=\""
207: + XMLHelper.escape(licenses[i].getName())
208: + "\"" + lurl + "/>");
209: }
210: }
211: if (dep.getModuleRevision() != null) {
212: MetadataArtifactDownloadReport madr = dep
213: .getModuleRevision().getReport();
214: out.print("\t\t\t\t<metadata-artifact");
215: out.print(" status=\""
216: + XMLHelper.escape(madr.getDownloadStatus()
217: .toString()) + "\"");
218: out.print(" details=\""
219: + XMLHelper.escape(madr.getDownloadDetails())
220: + "\"");
221: out.print(" size=\"" + madr.getSize() + "\"");
222: out.print(" time=\"" + madr.getDownloadTimeMillis() + "\"");
223: if (madr.getLocalFile() != null) {
224: out.print(" location=\""
225: + XMLHelper.escape(madr.getLocalFile()
226: .getAbsolutePath()) + "\"");
227: }
228:
229: out.print(" searched=\"" + madr.isSearched() + "\"");
230: if (madr.getOriginalLocalFile() != null) {
231: out.print(" original-local-location=\""
232: + XMLHelper.escape(madr.getOriginalLocalFile()
233: .getAbsolutePath()) + "\"");
234: }
235:
236: ArtifactOrigin origin = madr.getArtifactOrigin();
237: if (origin != null) {
238: out.print(" origin-is-local=\""
239: + String.valueOf(origin.isLocal()) + "\"");
240: out
241: .print(" origin-location=\""
242: + XMLHelper
243: .escape(origin.getLocation())
244: + "\"");
245: }
246: out.println("/>");
247:
248: }
249: if (dep.isEvicted(report.getConfiguration())) {
250: EvictionData ed = dep.getEvictedData(report
251: .getConfiguration());
252: Collection selected = ed.getSelected();
253: if (selected != null) {
254: for (Iterator it3 = selected.iterator(); it3.hasNext();) {
255: IvyNode sel = (IvyNode) it3.next();
256: out.println("\t\t\t\t<evicted-by rev=\""
257: + XMLHelper.escape(sel.getResolvedId()
258: .getRevision()) + "\"/>");
259: }
260: }
261: }
262: Caller[] callers = dep.getCallers(report.getConfiguration());
263: for (int i = 0; i < callers.length; i++) {
264: StringBuffer callerDetails = new StringBuffer();
265: Map callerExtraAttributes = callers[i]
266: .getDependencyDescriptor().getExtraAttributes();
267: for (Iterator iterator = callerExtraAttributes.keySet()
268: .iterator(); iterator.hasNext();) {
269: String attName = (String) iterator.next();
270: callerDetails.append(" extra-").append(attName).append(
271: "=\"").append(
272: XMLHelper.escape(callerExtraAttributes.get(
273: attName).toString())).append("\"");
274: }
275:
276: out.println("\t\t\t\t<caller organisation=\""
277: + XMLHelper.escape(callers[i].getModuleRevisionId()
278: .getOrganisation())
279: + "\""
280: + " name=\""
281: + XMLHelper.escape(callers[i].getModuleRevisionId()
282: .getName())
283: + "\""
284: + " conf=\""
285: + XMLHelper.escape(toString(callers[i]
286: .getCallerConfigurations()))
287: + "\""
288: + " rev=\""
289: + XMLHelper.escape(callers[i]
290: .getAskedDependencyId().getRevision())
291: + "\""
292: + " callerrev=\""
293: + XMLHelper.escape(callers[i].getModuleRevisionId()
294: .getRevision()) + "\"" + callerDetails
295: + "/>");
296: }
297: ArtifactDownloadReport[] adr = report.getDownloadReports(dep
298: .getResolvedId());
299: out.println("\t\t\t\t<artifacts>");
300: for (int i = 0; i < adr.length; i++) {
301: out.print("\t\t\t\t\t<artifact name=\""
302: + XMLHelper.escape(adr[i].getName()) + "\" type=\""
303: + XMLHelper.escape(adr[i].getType()) + "\" ext=\""
304: + XMLHelper.escape(adr[i].getExt()) + "\"");
305: extraAttributes = adr[i].getArtifact().getExtraAttributes();
306: for (Iterator iterator = extraAttributes.keySet()
307: .iterator(); iterator.hasNext();) {
308: String attName = (String) iterator.next();
309: out.print(" extra-"
310: + attName
311: + "=\""
312: + XMLHelper.escape(extraAttributes.get(attName)
313: .toString()) + "\"");
314: }
315: out.print(" status=\""
316: + XMLHelper.escape(adr[i].getDownloadStatus()
317: .toString()) + "\"");
318: out.print(" details=\""
319: + XMLHelper.escape(adr[i].getDownloadDetails())
320: + "\"");
321: out.print(" size=\"" + adr[i].getSize() + "\"");
322: out.print(" time=\"" + adr[i].getDownloadTimeMillis()
323: + "\"");
324: if (adr[i].getLocalFile() != null) {
325: out.print(" location=\""
326: + XMLHelper.escape(adr[i].getLocalFile()
327: .getAbsolutePath()) + "\"");
328: }
329:
330: ArtifactOrigin origin = adr[i].getArtifactOrigin();
331: if (origin != null) {
332: out.println(">");
333: out.println("\t\t\t\t\t\t<origin-location is-local=\""
334: + String.valueOf(origin.isLocal()) + "\""
335: + " location=\""
336: + XMLHelper.escape(origin.getLocation())
337: + "\"/>");
338: out.println("\t\t\t\t\t</artifact>");
339: } else {
340: out.println("/>");
341: }
342: }
343: out.println("\t\t\t\t</artifacts>");
344: out.println("\t\t\t</revision>");
345: }
346:
347: private String toString(String[] strs) {
348: StringBuffer buf = new StringBuffer();
349: for (int i = 0; i < strs.length; i++) {
350: buf.append(strs[i]);
351: if (i + 1 < strs.length) {
352: buf.append(", ");
353: }
354: }
355: return XMLHelper.escape(buf.toString());
356: }
357: }
|