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.ant;
019:
020: import java.io.File;
021: import java.io.IOException;
022: import java.util.ArrayList;
023: import java.util.Iterator;
024: import java.util.List;
025:
026: import org.apache.ivy.Ivy;
027: import org.apache.ivy.core.cache.ResolutionCacheManager;
028: import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
029: import org.apache.ivy.core.module.id.ModuleId;
030: import org.apache.ivy.core.module.id.ModuleRevisionId;
031: import org.apache.ivy.core.report.ResolveReport;
032: import org.apache.ivy.core.resolve.ResolveOptions;
033: import org.apache.ivy.core.settings.IvySettings;
034: import org.apache.ivy.plugins.matcher.PatternMatcher;
035: import org.apache.ivy.plugins.report.XmlReportOutputter;
036: import org.apache.ivy.util.FileUtil;
037: import org.apache.tools.ant.BuildException;
038: import org.apache.tools.ant.taskdefs.XSLTProcess;
039:
040: /**
041: * Generates a report of dependencies of a set of modules in the repository. The set of modules is
042: * specified using organisation/module and matcher.
043: */
044: public class IvyRepositoryReport extends IvyTask {
045: private String organisation = "*";
046:
047: private String module;
048:
049: private String branch;
050:
051: private String revision = "latest.integration";
052:
053: private String matcher = PatternMatcher.EXACT_OR_REGEXP;
054:
055: private File todir = new File(".");
056:
057: private boolean graph = false;
058:
059: private boolean dot = false;
060:
061: private boolean xml = true;
062:
063: private boolean xsl = false;
064:
065: private String xslFile;
066:
067: private String outputname = "ivy-repository-report";
068:
069: private String xslext = "html";
070:
071: private List params = new ArrayList();
072:
073: public void doExecute() throws BuildException {
074: Ivy ivy = getIvyInstance();
075: IvySettings settings = ivy.getSettings();
076: if (xsl && xslFile == null) {
077: throw new BuildException(
078: "xsl file is mandatory when using xsl generation");
079: }
080: if (module == null && PatternMatcher.EXACT.equals(matcher)) {
081: throw new BuildException(
082: "no module name provided for ivy repository graph task: "
083: + "It can either be set explicitely via the attribute 'module' or "
084: + "via 'ivy.module' property or a prior call to <resolve/>");
085: } else if (module == null
086: && !PatternMatcher.EXACT.equals(matcher)) {
087: module = PatternMatcher.ANY_EXPRESSION;
088: }
089: ModuleRevisionId mrid = ModuleRevisionId.newInstance(
090: organisation, module, revision);
091:
092: try {
093: ModuleId[] mids = ivy
094: .listModules(new ModuleId(organisation, module),
095: settings.getMatcher(matcher));
096: ModuleRevisionId[] mrids = new ModuleRevisionId[mids.length];
097: for (int i = 0; i < mrids.length; i++) {
098: if (branch != null) {
099: mrids[i] = new ModuleRevisionId(mids[i], branch,
100: revision);
101: } else {
102: mrids[i] = new ModuleRevisionId(mids[i], revision);
103: }
104: }
105: DefaultModuleDescriptor md = DefaultModuleDescriptor
106: .newCallerInstance(mrids, true, false);
107: String resolveId = ResolveOptions.getDefaultResolveId(md);
108: ResolveReport report = ivy.resolve(md, new ResolveOptions()
109: .setResolveId(resolveId).setValidate(
110: doValidate(settings)));
111:
112: ResolutionCacheManager cacheMgr = getIvyInstance()
113: .getResolutionCacheManager();
114: new XmlReportOutputter().output(report, cacheMgr,
115: new ResolveOptions());
116: if (graph) {
117: gengraph(cacheMgr, md.getModuleRevisionId()
118: .getOrganisation(), md.getModuleRevisionId()
119: .getName());
120: }
121: if (dot) {
122: gendot(cacheMgr, md.getModuleRevisionId()
123: .getOrganisation(), md.getModuleRevisionId()
124: .getName());
125: }
126: if (xml) {
127:
128: FileUtil.copy(cacheMgr
129: .getConfigurationResolveReportInCache(
130: resolveId, "default"), new File(todir,
131: outputname + ".xml"), null);
132: }
133: if (xsl) {
134: genreport(cacheMgr, md.getModuleRevisionId()
135: .getOrganisation(), md.getModuleRevisionId()
136: .getName());
137: }
138: } catch (Exception e) {
139: throw new BuildException(
140: "impossible to generate graph for " + mrid + ": "
141: + e, e);
142: }
143: }
144:
145: private void genreport(ResolutionCacheManager cache,
146: String organisation, String module) throws IOException {
147: // first process the report with xslt
148: XSLTProcess xslt = new XSLTProcess();
149: xslt.setTaskName(getTaskName());
150: xslt.setProject(getProject());
151: xslt.init();
152:
153: String resolveId = ResolveOptions
154: .getDefaultResolveId(new ModuleId(organisation, module));
155: xslt.setIn(cache.getConfigurationResolveReportInCache(
156: resolveId, "default"));
157: xslt.setOut(new File(todir, outputname + "." + xslext));
158:
159: xslt.setStyle(xslFile);
160:
161: XSLTProcess.Param param = xslt.createParam();
162: param.setName("extension");
163: param.setExpression(xslext);
164:
165: // add the provided XSLT parameters
166: for (Iterator it = params.iterator(); it.hasNext();) {
167: param = (XSLTProcess.Param) it.next();
168: XSLTProcess.Param realParam = xslt.createParam();
169: realParam.setName(param.getName());
170: realParam.setExpression(param.getExpression());
171: }
172:
173: xslt.execute();
174: }
175:
176: private void gengraph(ResolutionCacheManager cache,
177: String organisation, String module) throws IOException {
178: gen(cache, organisation, module, getGraphStylePath(cache
179: .getResolutionCacheRoot()), "graphml");
180: }
181:
182: private String getGraphStylePath(File cache) throws IOException {
183: // style should be a file (and not an url)
184: // so we have to copy it from classpath to cache
185: File style = new File(cache, "ivy-report-graph-all.xsl");
186: FileUtil.copy(XmlReportOutputter.class
187: .getResourceAsStream("ivy-report-graph-all.xsl"),
188: style, null);
189: return style.getAbsolutePath();
190: }
191:
192: private void gendot(ResolutionCacheManager cache,
193: String organisation, String module) throws IOException {
194: gen(cache, organisation, module, getDotStylePath(cache
195: .getResolutionCacheRoot()), "dot");
196: }
197:
198: private String getDotStylePath(File cache) throws IOException {
199: // style should be a file (and not an url)
200: // so we have to copy it from classpath to cache
201: File style = new File(cache, "ivy-report-dot-all.xsl");
202: FileUtil.copy(XmlReportOutputter.class
203: .getResourceAsStream("ivy-report-dot-all.xsl"), style,
204: null);
205: return style.getAbsolutePath();
206: }
207:
208: private void gen(ResolutionCacheManager cache, String organisation,
209: String module, String style, String ext) throws IOException {
210: XSLTProcess xslt = new XSLTProcess();
211: xslt.setTaskName(getTaskName());
212: xslt.setProject(getProject());
213: xslt.init();
214:
215: String resolveId = ResolveOptions
216: .getDefaultResolveId(new ModuleId(organisation, module));
217: xslt.setIn(cache.getConfigurationResolveReportInCache(
218: resolveId, "default"));
219: xslt.setOut(new File(todir, outputname + "." + ext));
220: xslt.setBasedir(cache.getResolutionCacheRoot());
221: xslt.setStyle(style);
222: xslt.execute();
223: }
224:
225: public File getTodir() {
226: return todir;
227: }
228:
229: public void setTodir(File todir) {
230: this .todir = todir;
231: }
232:
233: public boolean isGraph() {
234: return graph;
235: }
236:
237: public void setGraph(boolean graph) {
238: this .graph = graph;
239: }
240:
241: public String getXslfile() {
242: return xslFile;
243: }
244:
245: public void setXslfile(String xslFile) {
246: this .xslFile = xslFile;
247: }
248:
249: public boolean isXml() {
250: return xml;
251: }
252:
253: public void setXml(boolean xml) {
254: this .xml = xml;
255: }
256:
257: public boolean isXsl() {
258: return xsl;
259: }
260:
261: public void setXsl(boolean xsl) {
262: this .xsl = xsl;
263: }
264:
265: public String getXslext() {
266: return xslext;
267: }
268:
269: public void setXslext(String xslext) {
270: this .xslext = xslext;
271: }
272:
273: public XSLTProcess.Param createParam() {
274: XSLTProcess.Param result = new XSLTProcess.Param();
275: params.add(result);
276: return result;
277: }
278:
279: public String getOutputname() {
280: return outputname;
281: }
282:
283: public void setOutputname(String outputpattern) {
284: outputname = outputpattern;
285: }
286:
287: public void setCache(File cache) {
288: cacheAttributeNotSupported();
289: }
290:
291: public String getMatcher() {
292: return matcher;
293: }
294:
295: public void setMatcher(String matcher) {
296: this .matcher = matcher;
297: }
298:
299: public String getModule() {
300: return module;
301: }
302:
303: public void setModule(String module) {
304: this .module = module;
305: }
306:
307: public String getOrganisation() {
308: return organisation;
309: }
310:
311: public void setOrganisation(String organisation) {
312: this .organisation = organisation;
313: }
314:
315: public String getRevision() {
316: return revision;
317: }
318:
319: public void setRevision(String revision) {
320: this .revision = revision;
321: }
322:
323: public String getBranch() {
324: return branch;
325: }
326:
327: public void setBranch(String branch) {
328: this .branch = branch;
329: }
330:
331: public boolean isDot() {
332: return dot;
333: }
334:
335: public void setDot(boolean dot) {
336: this.dot = dot;
337: }
338: }
|