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.xml;
019:
020: import java.io.File;
021: import java.io.FileOutputStream;
022: import java.io.IOException;
023: import java.io.OutputStreamWriter;
024: import java.io.PrintWriter;
025: import java.util.Arrays;
026: import java.util.Iterator;
027: import java.util.Map;
028: import java.util.Map.Entry;
029:
030: import org.apache.ivy.Ivy;
031: import org.apache.ivy.core.module.descriptor.Artifact;
032: import org.apache.ivy.core.module.descriptor.Configuration;
033: import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
034: import org.apache.ivy.core.module.descriptor.DependencyArtifactDescriptor;
035: import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
036: import org.apache.ivy.core.module.descriptor.ExcludeRule;
037: import org.apache.ivy.core.module.descriptor.IncludeRule;
038: import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
039: import org.apache.ivy.util.XMLHelper;
040: import org.apache.ivy.util.extendable.ExtendableItem;
041:
042: /**
043: *
044: */
045: public final class XmlModuleDescriptorWriter {
046:
047: private XmlModuleDescriptorWriter() {
048: //Utility class
049: }
050:
051: public static void write(ModuleDescriptor md, File output)
052: throws IOException {
053: write(md, null, output);
054: }
055:
056: public static void write(ModuleDescriptor md, String licenseHeader,
057: File output) throws IOException {
058: if (output.getParentFile() != null) {
059: output.getParentFile().mkdirs();
060: }
061: PrintWriter out = new PrintWriter(new OutputStreamWriter(
062: new FileOutputStream(output), "UTF-8"));
063: try {
064: out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
065: if (licenseHeader != null) {
066: out.print(licenseHeader);
067: }
068: StringBuffer xmlNamespace = new StringBuffer();
069: Map namespaces = md.getExtraAttributesNamespaces();
070: for (Iterator iter = namespaces.entrySet().iterator(); iter
071: .hasNext();) {
072: Entry ns = (Entry) iter.next();
073: xmlNamespace.append(" xmlns:").append(ns.getKey())
074: .append("=\"").append(ns.getValue()).append(
075: "\"");
076: }
077: out.println("<ivy-module version=\"1.0\"" + xmlNamespace
078: + ">");
079: printInfoTag(md, out);
080: printConfigurations(md, out);
081: printPublications(md, out);
082: printDependencies(md, out);
083: out.println("</ivy-module>");
084: } finally {
085: out.close();
086: }
087: }
088:
089: private static void printDependencies(ModuleDescriptor md,
090: PrintWriter out) {
091: DependencyDescriptor[] dds = md.getDependencies();
092: if (dds.length > 0) {
093: out.println("\t<dependencies>");
094: for (int i = 0; i < dds.length; i++) {
095: out.print("\t\t<dependency");
096: out.print(" org=\""
097: + XMLHelper.escape(dds[i]
098: .getDependencyRevisionId()
099: .getOrganisation()) + "\"");
100: out.print(" name=\""
101: + XMLHelper.escape(dds[i]
102: .getDependencyRevisionId().getName())
103: + "\"");
104: out.print(" rev=\""
105: + XMLHelper.escape(dds[i]
106: .getDependencyRevisionId()
107: .getRevision()) + "\"");
108: if (dds[i].isForce()) {
109: out.print(" force=\"" + dds[i].isForce() + "\"");
110: }
111: if (dds[i].isChanging()) {
112: out.print(" changing=\"" + dds[i].isChanging()
113: + "\"");
114: }
115: if (!dds[i].isTransitive()) {
116: out.print(" transitive=\"" + dds[i].isTransitive()
117: + "\"");
118: }
119: out.print(" conf=\"");
120: String[] modConfs = dds[i].getModuleConfigurations();
121: for (int j = 0; j < modConfs.length; j++) {
122: String[] depConfs = dds[i]
123: .getDependencyConfigurations(modConfs[j]);
124: out.print(XMLHelper.escape(modConfs[j]) + "->");
125: for (int k = 0; k < depConfs.length; k++) {
126: out.print(XMLHelper.escape(depConfs[k]));
127: if (k + 1 < depConfs.length) {
128: out.print(",");
129: }
130: }
131: if (j + 1 < modConfs.length) {
132: out.print(";");
133: }
134: }
135: out.print("\"");
136:
137: printExtraAttributes(dds[i], out, " ");
138:
139: DependencyArtifactDescriptor[] depArtifacts = dds[i]
140: .getAllDependencyArtifacts();
141: if (depArtifacts.length > 0) {
142: out.println(">");
143: }
144: printDependencyArtefacts(md, out, depArtifacts);
145:
146: IncludeRule[] includes = dds[i].getAllIncludeRules();
147: if (includes.length > 0 && depArtifacts.length == 0) {
148: out.println(">");
149: }
150: printDependencyIncludeRules(md, out, includes);
151:
152: ExcludeRule[] excludes = dds[i].getAllExcludeRules();
153: if (excludes.length > 0 && includes.length == 0
154: && depArtifacts.length == 0) {
155: out.println(">");
156: }
157: printDependencyExcludeRules(md, out, excludes);
158: if (includes.length + excludes.length
159: + depArtifacts.length == 0) {
160: out.println("/>");
161: } else {
162: out.println("\t\t</dependency>");
163: }
164: }
165: printAllExcludes(md, out);
166: }
167: }
168:
169: private static void printAllExcludes(ModuleDescriptor md,
170: PrintWriter out) {
171: ExcludeRule[] excludes = md.getAllExcludeRules();
172: if (excludes.length > 0) {
173: for (int j = 0; j < excludes.length; j++) {
174: out.print("\t\t<exclude");
175: out.print(" org=\""
176: + XMLHelper.escape(excludes[j].getId()
177: .getModuleId().getOrganisation())
178: + "\"");
179: out.print(" module=\""
180: + XMLHelper.escape(excludes[j].getId()
181: .getModuleId().getName()) + "\"");
182: out.print(" artifact=\""
183: + XMLHelper.escape(excludes[j].getId()
184: .getName()) + "\"");
185: out.print(" type=\""
186: + XMLHelper.escape(excludes[j].getId()
187: .getType()) + "\"");
188: out.print(" ext=\""
189: + XMLHelper
190: .escape(excludes[j].getId().getExt())
191: + "\"");
192: String[] ruleConfs = excludes[j].getConfigurations();
193: if (!Arrays.asList(ruleConfs).equals(
194: Arrays.asList(md.getConfigurationsNames()))) {
195: out.print(" conf=\"");
196: for (int k = 0; k < ruleConfs.length; k++) {
197: out.print(XMLHelper.escape(ruleConfs[k]));
198: if (k + 1 < ruleConfs.length) {
199: out.print(",");
200: }
201: }
202: out.print("\"");
203: }
204: out.print(" matcher=\""
205: + XMLHelper.escape(excludes[j].getMatcher()
206: .getName()) + "\"");
207: out.println("/>");
208: }
209: }
210: out.println("\t</dependencies>");
211: }
212:
213: private static void printDependencyExcludeRules(
214: ModuleDescriptor md, PrintWriter out, ExcludeRule[] excludes) {
215: if (excludes.length > 0) {
216: for (int j = 0; j < excludes.length; j++) {
217: out.print("\t\t\t<exclude");
218: out.print(" org=\""
219: + XMLHelper.escape(excludes[j].getId()
220: .getModuleId().getOrganisation())
221: + "\"");
222: out.print(" module=\""
223: + XMLHelper.escape(excludes[j].getId()
224: .getModuleId().getName()) + "\"");
225: out.print(" name=\""
226: + XMLHelper.escape(excludes[j].getId()
227: .getName()) + "\"");
228: out.print(" type=\""
229: + XMLHelper.escape(excludes[j].getId()
230: .getType()) + "\"");
231: out.print(" ext=\""
232: + XMLHelper
233: .escape(excludes[j].getId().getExt())
234: + "\"");
235: String[] ruleConfs = excludes[j].getConfigurations();
236: if (!Arrays.asList(ruleConfs).equals(
237: Arrays.asList(md.getConfigurationsNames()))) {
238: out.print(" conf=\"");
239: for (int k = 0; k < ruleConfs.length; k++) {
240: out.print(XMLHelper.escape(ruleConfs[k]));
241: if (k + 1 < ruleConfs.length) {
242: out.print(",");
243: }
244: }
245: out.print("\"");
246: }
247: out.print(" matcher=\""
248: + XMLHelper.escape(excludes[j].getMatcher()
249: .getName()) + "\"");
250: out.println("/>");
251: }
252: }
253: }
254:
255: private static void printDependencyIncludeRules(
256: ModuleDescriptor md, PrintWriter out, IncludeRule[] includes) {
257: if (includes.length > 0) {
258: for (int j = 0; j < includes.length; j++) {
259: out.print("\t\t\t<include");
260: out.print(" name=\""
261: + XMLHelper.escape(includes[j].getId()
262: .getName()) + "\"");
263: out.print(" type=\""
264: + XMLHelper.escape(includes[j].getId()
265: .getType()) + "\"");
266: out.print(" ext=\""
267: + XMLHelper
268: .escape(includes[j].getId().getExt())
269: + "\"");
270: String[] ruleConfs = includes[j].getConfigurations();
271: if (!Arrays.asList(ruleConfs).equals(
272: Arrays.asList(md.getConfigurationsNames()))) {
273: out.print(" conf=\"");
274: for (int k = 0; k < ruleConfs.length; k++) {
275: out.print(XMLHelper.escape(ruleConfs[k]));
276: if (k + 1 < ruleConfs.length) {
277: out.print(",");
278: }
279: }
280: out.print("\"");
281: }
282: out.print(" matcher=\""
283: + XMLHelper.escape(includes[j].getMatcher()
284: .getName()) + "\"");
285: out.println("/>");
286: }
287: }
288: }
289:
290: private static void printDependencyArtefacts(ModuleDescriptor md,
291: PrintWriter out, DependencyArtifactDescriptor[] depArtifacts) {
292: if (depArtifacts.length > 0) {
293: for (int j = 0; j < depArtifacts.length; j++) {
294: out.print("\t\t\t<artifact");
295: out.print(" name=\""
296: + XMLHelper.escape(depArtifacts[j].getName())
297: + "\"");
298: out.print(" type=\""
299: + XMLHelper.escape(depArtifacts[j].getType())
300: + "\"");
301: out.print(" ext=\""
302: + XMLHelper.escape(depArtifacts[j].getExt())
303: + "\"");
304: String[] dadconfs = depArtifacts[j].getConfigurations();
305: if (!Arrays.asList(dadconfs).equals(
306: Arrays.asList(md.getConfigurationsNames()))) {
307: out.print(" conf=\"");
308: for (int k = 0; k < dadconfs.length; k++) {
309: out.print(XMLHelper.escape(dadconfs[k]));
310: if (k + 1 < dadconfs.length) {
311: out.print(",");
312: }
313: }
314: out.print("\"");
315: }
316: printExtraAttributes(depArtifacts[j], out, " ");
317: out.println("/>");
318: }
319: }
320: }
321:
322: /**
323: * Writes the extra attributes of the given {@link ExtendableItem} to the
324: * given <tt>PrintWriter</tt>.
325: *
326: * @param item the {@link ExtendableItem}, cannot be <tt>null</tt>
327: * @param out the writer to use
328: * @param prefix the string to write before writing the attributes (if any)
329: */
330: private static void printExtraAttributes(ExtendableItem item,
331: PrintWriter out, String prefix) {
332: printExtraAttributes(item.getQualifiedExtraAttributes(), out,
333: prefix);
334: }
335:
336: /**
337: * Writes the specified <tt>Map</tt> containing the extra attributes to the
338: * given <tt>PrintWriter</tt>.
339: *
340: * @param extra the extra attributes, can be <tt>null</tt>
341: * @param out the writer to use
342: * @param prefix the string to write before writing the attributes (if any)
343: */
344: private static void printExtraAttributes(Map extra,
345: PrintWriter out, String prefix) {
346: if (extra == null) {
347: return;
348: }
349:
350: String delim = prefix;
351: for (Iterator iter = extra.entrySet().iterator(); iter
352: .hasNext();) {
353: Map.Entry entry = (Map.Entry) iter.next();
354: out.print(delim + entry.getKey() + "=\""
355: + XMLHelper.escape(entry.getValue().toString())
356: + "\"");
357: delim = " ";
358: }
359: }
360:
361: private static void printPublications(ModuleDescriptor md,
362: PrintWriter out) {
363: out.println("\t<publications>");
364: Artifact[] artifacts = md.getAllArtifacts();
365: for (int i = 0; i < artifacts.length; i++) {
366: out.print("\t\t<artifact");
367: out.print(" name=\""
368: + XMLHelper.escape(artifacts[i].getName()) + "\"");
369: out.print(" type=\""
370: + XMLHelper.escape(artifacts[i].getType()) + "\"");
371: out.print(" ext=\""
372: + XMLHelper.escape(artifacts[i].getExt()) + "\"");
373: out.print(" conf=\""
374: + XMLHelper.escape(getConfs(md, artifacts[i]))
375: + "\"");
376: printExtraAttributes(artifacts[i], out, " ");
377: out.println("/>");
378: }
379: out.println("\t</publications>");
380: }
381:
382: private static void printConfigurations(ModuleDescriptor md,
383: PrintWriter out) {
384: Configuration[] confs = md.getConfigurations();
385: if (confs.length > 0) {
386: out.println("\t<configurations>");
387: for (int i = 0; i < confs.length; i++) {
388: out.print("\t\t<conf");
389: out.print(" name=\""
390: + XMLHelper.escape(confs[i].getName()) + "\"");
391: out.print(" visibility=\""
392: + XMLHelper.escape(confs[i].getVisibility()
393: .toString()) + "\"");
394: if (confs[i].getDescription() != null) {
395: out.print(" description=\""
396: + XMLHelper.escape(confs[i]
397: .getDescription()) + "\"");
398: }
399: String[] exts = confs[i].getExtends();
400: if (exts.length > 0) {
401: out.print(" extends=\"");
402: for (int j = 0; j < exts.length; j++) {
403: out.print(XMLHelper.escape(exts[j]));
404: if (j + 1 < exts.length) {
405: out.print(",");
406: }
407: }
408: out.print("\"");
409: }
410: if (confs[i].getDeprecated() != null) {
411: out.print(" deprecated=\""
412: + XMLHelper
413: .escape(confs[i].getDeprecated())
414: + "\"");
415: }
416: printExtraAttributes(confs[i], out, " ");
417: out.println("/>");
418: }
419: out.println("\t</configurations>");
420: }
421: }
422:
423: private static void printInfoTag(ModuleDescriptor md,
424: PrintWriter out) {
425: out.println("\t<info organisation=\""
426: + XMLHelper.escape(md.getModuleRevisionId()
427: .getOrganisation()) + "\"");
428: out.println("\t\tmodule=\""
429: + XMLHelper.escape(md.getModuleRevisionId().getName())
430: + "\"");
431: String branch = md.getResolvedModuleRevisionId().getBranch();
432: if (branch != null) {
433: out.println("\t\tbranch=\"" + XMLHelper.escape(branch)
434: + "\"");
435: }
436: String revision = md.getResolvedModuleRevisionId()
437: .getRevision();
438: if (revision != null) {
439: out.println("\t\trevision=\"" + XMLHelper.escape(revision)
440: + "\"");
441: }
442: out.println("\t\tstatus=\"" + XMLHelper.escape(md.getStatus())
443: + "\"");
444: out.println("\t\tpublication=\""
445: + Ivy.DATE_FORMAT.format(md
446: .getResolvedPublicationDate()) + "\"");
447: if (md.isDefault()) {
448: out.println("\t\tdefault=\"true\"");
449: }
450: if (md instanceof DefaultModuleDescriptor) {
451: DefaultModuleDescriptor dmd = (DefaultModuleDescriptor) md;
452: if (dmd.getNamespace() != null
453: && !dmd.getNamespace().getName().equals("system")) {
454: out.println("\t\tnamespace=\""
455: + XMLHelper
456: .escape(dmd.getNamespace().getName())
457: + "\"");
458: }
459: }
460: if (!md.getExtraAttributes().isEmpty()) {
461: printExtraAttributes(md, out, "\t\t");
462: out.println();
463: }
464: if (md.getExtraInfo().size() > 0) {
465: out.println("\t>");
466: for (Iterator it = md.getExtraInfo().entrySet().iterator(); it
467: .hasNext();) {
468: Map.Entry extraDescr = (Map.Entry) it.next();
469: if (extraDescr.getValue() == null
470: || ((String) extraDescr.getValue()).length() == 0) {
471: continue;
472: }
473: out.print("\t\t<");
474: out.print(extraDescr.getKey());
475: out.print(">");
476: out.print(XMLHelper.escape((String) extraDescr
477: .getValue()));
478: out.print("</");
479: out.print(extraDescr.getKey());
480: out.println(">");
481: }
482: out.println("\t</info>");
483: } else {
484: out.println("\t/>");
485: }
486:
487: }
488:
489: private static String getConfs(ModuleDescriptor md,
490: Artifact artifact) {
491: StringBuffer ret = new StringBuffer();
492:
493: String[] confs = md.getConfigurationsNames();
494: for (int i = 0; i < confs.length; i++) {
495: if (Arrays.asList(md.getArtifacts(confs[i])).contains(
496: artifact)) {
497: ret.append(confs[i]).append(",");
498: }
499: }
500: if (ret.length() > 0) {
501: ret.setLength(ret.length() - 1);
502: }
503: return ret.toString();
504: }
505: }
|