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.core.report;
019:
020: import java.io.IOException;
021: import java.util.ArrayList;
022: import java.util.Arrays;
023: import java.util.Collection;
024: import java.util.Iterator;
025: import java.util.LinkedHashMap;
026: import java.util.LinkedHashSet;
027: import java.util.List;
028: import java.util.Map;
029:
030: import org.apache.ivy.core.cache.ResolutionCacheManager;
031: import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
032: import org.apache.ivy.core.module.id.ModuleId;
033: import org.apache.ivy.core.module.id.ModuleRevisionId;
034: import org.apache.ivy.core.resolve.IvyNode;
035: import org.apache.ivy.core.resolve.ResolveOptions;
036: import org.apache.ivy.plugins.report.ReportOutputter;
037: import org.apache.ivy.util.filter.Filter;
038:
039: /**
040: * Represents a whole resolution report for a module
041: */
042: public class ResolveReport {
043: private ModuleDescriptor md;
044:
045: /** String conf -> ConfigurationResolveReport report */
046: private Map confReports = new LinkedHashMap();
047:
048: private List problemMessages = new ArrayList();
049:
050: /**
051: * the list of all dependencies resolved, ordered from the more dependent to the less dependent
052: */
053: private List dependencies = new ArrayList();
054:
055: private List artifacts = new ArrayList();
056:
057: private long resolveTime;
058:
059: private long downloadTime;
060:
061: private String resolveId;
062:
063: private long downloadSize;
064:
065: public ResolveReport(ModuleDescriptor md) {
066: this (md, ResolveOptions.getDefaultResolveId(md));
067: }
068:
069: public ResolveReport(ModuleDescriptor md, String resolveId) {
070: this .md = md;
071: this .resolveId = resolveId;
072: }
073:
074: public void addReport(String conf, ConfigurationResolveReport report) {
075: confReports.put(conf, report);
076: }
077:
078: public ConfigurationResolveReport getConfigurationReport(String conf) {
079: return (ConfigurationResolveReport) confReports.get(conf);
080: }
081:
082: public String[] getConfigurations() {
083: return (String[]) confReports.keySet().toArray(
084: new String[confReports.size()]);
085: }
086:
087: public boolean hasError() {
088: boolean hasError = false;
089: for (Iterator it = confReports.values().iterator(); it
090: .hasNext()
091: && !hasError;) {
092: ConfigurationResolveReport report = (ConfigurationResolveReport) it
093: .next();
094: hasError |= report.hasError();
095: }
096: return hasError;
097: }
098:
099: public void output(ReportOutputter[] outputters,
100: ResolutionCacheManager cacheMgr, ResolveOptions options)
101: throws IOException {
102: for (int i = 0; i < outputters.length; i++) {
103: outputters[i].output(this , cacheMgr, options);
104: }
105: }
106:
107: public ModuleDescriptor getModuleDescriptor() {
108: return md;
109: }
110:
111: public IvyNode[] getEvictedNodes() {
112: Collection all = new LinkedHashSet();
113: for (Iterator iter = confReports.values().iterator(); iter
114: .hasNext();) {
115: ConfigurationResolveReport report = (ConfigurationResolveReport) iter
116: .next();
117: all.addAll(Arrays.asList(report.getEvictedNodes()));
118: }
119: return (IvyNode[]) all.toArray(new IvyNode[all.size()]);
120: }
121:
122: public IvyNode[] getUnresolvedDependencies() {
123: Collection all = new LinkedHashSet();
124: for (Iterator iter = confReports.values().iterator(); iter
125: .hasNext();) {
126: ConfigurationResolveReport report = (ConfigurationResolveReport) iter
127: .next();
128: all.addAll(Arrays
129: .asList(report.getUnresolvedDependencies()));
130: }
131: return (IvyNode[]) all.toArray(new IvyNode[all.size()]);
132: }
133:
134: /**
135: * Get every report on the download requests.
136: *
137: * @return the list of reports, never <code>null</code>
138: */
139: public ArtifactDownloadReport[] getFailedArtifactsReports() {
140: return getArtifactsReports(DownloadStatus.FAILED, true);
141: }
142:
143: /**
144: * Get every report on the download requests.
145: *
146: * @return the list of reports, never <code>null</code>
147: */
148: public ArtifactDownloadReport[] getAllArtifactsReports() {
149: return getArtifactsReports(null, true);
150: }
151:
152: /**
153: * Get the report on the download requests. The list of download report can be restricted to a
154: * specific download status, and also remove the download report for the evicted modules.
155: *
156: * @param downloadStatus
157: * the status of download to retreive. Set it to <code>null</code> for no
158: * restriction on the download status
159: * @param withEvicted
160: * set it to <code>true</code> if the report for the evicted modules have to be
161: * retrieved, <code>false</code> to exclude reports from modules evicted in all
162: * configurations.
163: * @return the list of reports, never <code>null</code>
164: * @see ConfigurationResolveReport#getArtifactsReports(DownloadStatus, boolean)
165: */
166: public ArtifactDownloadReport[] getArtifactsReports(
167: DownloadStatus downloadStatus, boolean withEvicted) {
168: Collection all = new LinkedHashSet();
169: for (Iterator iter = confReports.values().iterator(); iter
170: .hasNext();) {
171: ConfigurationResolveReport report = (ConfigurationResolveReport) iter
172: .next();
173: ArtifactDownloadReport[] reports = report
174: .getArtifactsReports(downloadStatus, withEvicted);
175: all.addAll(Arrays.asList(reports));
176: }
177: return (ArtifactDownloadReport[]) all
178: .toArray(new ArtifactDownloadReport[all.size()]);
179: }
180:
181: public ArtifactDownloadReport[] getArtifactsReports(
182: ModuleRevisionId mrid) {
183: Collection all = new LinkedHashSet();
184: for (Iterator iter = confReports.values().iterator(); iter
185: .hasNext();) {
186: ConfigurationResolveReport report = (ConfigurationResolveReport) iter
187: .next();
188: all.addAll(Arrays.asList(report.getDownloadReports(mrid)));
189: }
190: return (ArtifactDownloadReport[]) all
191: .toArray(new ArtifactDownloadReport[all.size()]);
192: }
193:
194: public boolean hasChanged() {
195: for (Iterator iter = confReports.values().iterator(); iter
196: .hasNext();) {
197: ConfigurationResolveReport report = (ConfigurationResolveReport) iter
198: .next();
199: if (report.hasChanged()) {
200: return true;
201: }
202: }
203: return false;
204: }
205:
206: public void setProblemMessages(List problems) {
207: problemMessages = problems;
208: }
209:
210: public List getProblemMessages() {
211: return problemMessages;
212: }
213:
214: public List getAllProblemMessages() {
215: List ret = new ArrayList(problemMessages);
216: for (Iterator iter = confReports.values().iterator(); iter
217: .hasNext();) {
218: ConfigurationResolveReport r = (ConfigurationResolveReport) iter
219: .next();
220: IvyNode[] unresolved = r.getUnresolvedDependencies();
221: for (int i = 0; i < unresolved.length; i++) {
222: String errMsg = unresolved[i].getProblemMessage();
223: if (errMsg.length() > 0) {
224: ret.add("unresolved dependency: "
225: + unresolved[i].getId() + ": " + errMsg);
226: } else {
227: ret.add("unresolved dependency: "
228: + unresolved[i].getId());
229: }
230: }
231: ArtifactDownloadReport[] adrs = r
232: .getFailedArtifactsReports();
233: for (int i = 0; i < adrs.length; i++) {
234: ret.add("download failed: " + adrs[i].getArtifact());
235: }
236: }
237: return ret;
238: }
239:
240: public void setDependencies(List dependencies, Filter artifactFilter) {
241: this .dependencies = dependencies;
242: // collect list of artifacts
243: artifacts = new ArrayList();
244: for (Iterator iter = dependencies.iterator(); iter.hasNext();) {
245: IvyNode dependency = (IvyNode) iter.next();
246: if (!dependency.isCompletelyEvicted()
247: && !dependency.hasProblem()) {
248: artifacts.addAll(Arrays.asList(dependency
249: .getSelectedArtifacts(artifactFilter)));
250: }
251: // update the configurations reports with the dependencies
252: // these reports will be completed later with download information, if any
253: String[] dconfs = dependency.getRootModuleConfigurations();
254: for (int j = 0; j < dconfs.length; j++) {
255: ConfigurationResolveReport configurationReport = getConfigurationReport(dconfs[j]);
256: if (configurationReport != null) {
257: configurationReport.addDependency(dependency);
258: }
259: }
260: }
261: }
262:
263: /**
264: * Returns the list of all dependencies concerned by this report as a List of IvyNode ordered
265: * from the more dependent to the least one
266: *
267: * @return The list of all dependencies.
268: */
269: public List getDependencies() {
270: return dependencies;
271: }
272:
273: /**
274: * Returns the list of all artifacts which should be downloaded per this resolve To know if the
275: * artifact have actually been downloaded use information found in ConfigurationResolveReport.
276: *
277: * @return The list of all artifacts.
278: */
279: public List getArtifacts() {
280: return artifacts;
281: }
282:
283: /**
284: * gives all the modules ids concerned by this report, from the most dependent to the least one
285: *
286: * @return a list of ModuleId
287: */
288: public List getModuleIds() {
289: List ret = new ArrayList();
290: List sortedDependencies = new ArrayList(dependencies);
291: for (Iterator iter = sortedDependencies.iterator(); iter
292: .hasNext();) {
293: IvyNode dependency = (IvyNode) iter.next();
294: ModuleId mid = dependency.getResolvedId().getModuleId();
295: if (!ret.contains(mid)) {
296: ret.add(mid);
297: }
298: }
299: return ret;
300: }
301:
302: public void setResolveTime(long elapsedTime) {
303: resolveTime = elapsedTime;
304: }
305:
306: public long getResolveTime() {
307: return resolveTime;
308: }
309:
310: public void setDownloadTime(long elapsedTime) {
311: downloadTime = elapsedTime;
312: }
313:
314: public long getDownloadTime() {
315: return downloadTime;
316: }
317:
318: public void setDownloadSize(long size) {
319: this .downloadSize = size;
320: }
321:
322: /**
323: * The total size of downloaded artifacts, in bytes.
324: * <p>
325: * This only includes artifacts actually downloaded to cache (DownloadStatus.SUCCESSFUL), and
326: * not artifacts already in cache or used at their original location.
327: * </p>
328: *
329: * @return The total size of downloaded artifacts, in bytes.
330: */
331: public long getDownloadSize() {
332: return downloadSize;
333: }
334:
335: public String getResolveId() {
336: return resolveId;
337: }
338: }
|