1 /* 2 D-Bus Java Implementation 3 Copyright (c) 2005-2006 Matthew Johnson 4 5 This program is free software; you can redistribute it and/or modify it 6 under the terms of either the GNU Lesser General Public License Version 2 or the 7 Academic Free Licence Version 2.1. 8 9 Full licence texts are included in the COPYING file with this program. 10 */ 11 package org.freedesktop.dbus.bin; 12 13 import static org.freedesktop.dbus.Gettext._; 14 import static org.freedesktop.dbus.bin.IdentifierMangler.mangle; 15 16 import java.io.File; 17 import java.io.FileInputStream; 18 import java.io.FileNotFoundException; 19 import java.io.FileOutputStream; 20 import java.io.IOException; 21 import java.io.InputStreamReader; 22 import java.io.PrintStream; 23 import java.io.Reader; 24 import java.io.StringReader; 25 import java.text.MessageFormat; 26 import java.util.HashMap; 27 import java.util.Map; 28 import java.util.Set; 29 import java.util.TreeSet; 30 import java.util.Vector; 31 32 import java.lang.reflect.Field; 33 import java.lang.reflect.ParameterizedType; 34 import java.lang.reflect.Type; 35 36 import javax.xml.parsers.DocumentBuilder; 37 import javax.xml.parsers.DocumentBuilderFactory; 38 import javax.xml.parsers.ParserConfigurationException; 39 40 import org.freedesktop.DBus.Introspectable; 41 import org.freedesktop.dbus.DBusConnection; 42 import org.freedesktop.dbus.Marshalling; 43 import org.freedesktop.dbus.exceptions.DBusException; 44 import org.freedesktop.dbus.exceptions.DBusExecutionException; 45 import org.freedesktop.dbus.types.DBusStructType; 46 47 import org.w3c.dom.Document; 48 import org.w3c.dom.Element; 49 import org.w3c.dom.Node; 50 import org.xml.sax.InputSource; 51 import org.xml.sax.SAXException; 52 53 /** 54 * Converts a DBus XML file into Java interface definitions. 55 */ 56 public class CreateInterface 57 { 58 @SuppressWarnings("unchecked") collapseType(Type t, Set<String> imports, Map<StructStruct, Type[]> structs, boolean container, boolean fullnames)59 private static String collapseType(Type t, Set<String> imports, Map<StructStruct, Type[]> structs, boolean container, boolean fullnames) throws DBusException 60 { 61 if (t instanceof ParameterizedType) { 62 String s; 63 Class<? extends Object> c = (Class<? extends Object>) ((ParameterizedType) t).getRawType(); 64 if (null != structs && t instanceof DBusStructType) { 65 int num = 1; 66 String name = "Struct"; 67 while (null != structs.get(new StructStruct(name+num))) num++; 68 name = name+num; 69 structs.put(new StructStruct(name), ((ParameterizedType) t).getActualTypeArguments()); 70 return name; 71 } 72 if (null != imports) imports.add(c.getName()); 73 if (fullnames) return c.getName(); 74 else s = c.getSimpleName(); 75 s += '<'; 76 Type[] ts = ((ParameterizedType) t).getActualTypeArguments(); 77 for (Type st: ts) 78 s += collapseType(st, imports, structs, true, fullnames)+','; 79 s = s.replaceAll(",$", ">"); 80 return s; 81 } else if (t instanceof Class) { 82 Class<? extends Object> c = (Class<? extends Object>) t; 83 if (c.isArray()) { 84 return collapseType(c.getComponentType(), imports, structs, container, fullnames)+"[]"; 85 } else { 86 Package p = c.getPackage(); 87 if (null != imports && 88 !"java.lang".equals(p.getName())) imports.add(c.getName()); 89 if (container) { 90 if (fullnames) return c.getName(); 91 else return c.getSimpleName(); 92 } else { 93 try { 94 Field f = c.getField("TYPE"); 95 Class<? extends Object> d = (Class<? extends Object>) f.get(c); 96 return d.getSimpleName(); 97 } catch (Exception e) { 98 return c.getSimpleName(); 99 } 100 } 101 } 102 } else return ""; 103 } getJavaType(String dbus, Set<String> imports, Map<StructStruct,Type[]> structs, boolean container, boolean fullnames)104 private static String getJavaType(String dbus, Set<String> imports, Map<StructStruct,Type[]> structs, boolean container, boolean fullnames) throws DBusException 105 { 106 if (null == dbus || "".equals(dbus)) return ""; 107 Vector<Type> v = new Vector<Type>(); 108 int c = Marshalling.getJavaType(dbus, v, 1); 109 Type t = v.get(0); 110 return collapseType(t, imports, structs, container, fullnames); 111 } 112 public String comment = ""; 113 boolean builtin; 114 CreateInterface(PrintStreamFactory factory, boolean builtin)115 public CreateInterface(PrintStreamFactory factory, boolean builtin) 116 { 117 this.factory = factory; 118 this.builtin = builtin; 119 } 120 @SuppressWarnings("fallthrough") parseReturns(Vector<Element> out, Set<String> imports, Map<String,Integer> tuples, Map<StructStruct, Type[]> structs)121 String parseReturns(Vector<Element> out, Set<String> imports, Map<String,Integer> tuples, Map<StructStruct, Type[]> structs) throws DBusException 122 { 123 String[] names = new String[] { "Pair", "Triplet", "Quad", "Quintuple", "Sextuple", "Septuple" }; 124 String sig = ""; 125 String name = null; 126 switch (out.size()) { 127 case 0: 128 sig += "void "; 129 break; 130 case 1: 131 sig += getJavaType(out.get(0).getAttribute("type"), imports, structs, false, false)+" "; 132 break; 133 case 2: 134 case 3: 135 case 4: 136 case 5: 137 case 6: 138 case 7: 139 name = names[out.size() - 2]; 140 default: 141 if (null == name) 142 name = "NTuple"+out.size(); 143 144 tuples.put(name, out.size()); 145 sig += name + "<"; 146 for (Element arg: out) 147 sig += getJavaType(arg.getAttribute("type"), imports, structs, true, false)+", "; 148 sig = sig.replaceAll(", $","> "); 149 break; 150 } 151 return sig; 152 } parseMethod(Element meth, Set<String> imports, Map<String,Integer> tuples, Map<StructStruct, Type[]> structs, Set<String> exceptions, Set<String> anns)153 String parseMethod(Element meth, Set<String> imports, Map<String,Integer> tuples, Map<StructStruct, Type[]> structs, Set<String> exceptions, Set<String> anns) throws DBusException 154 { 155 Vector<Element> in = new Vector<Element>(); 156 Vector<Element> out = new Vector<Element>(); 157 if (null == meth.getAttribute("name") || 158 "".equals(meth.getAttribute("name"))) { 159 System.err.println(_("ERROR: Method name was blank, failed")); 160 System.exit(1); 161 } 162 String annotations = ""; 163 String throwses = null; 164 165 for (Node a: new IterableNodeList(meth.getChildNodes())) { 166 167 if (Node.ELEMENT_NODE != a.getNodeType()) continue; 168 169 checkNode(a, "arg", "annotation"); 170 171 if ("arg".equals(a.getNodeName())) { 172 Element arg = (Element) a; 173 174 // methods default to in 175 if ("out".equals(arg.getAttribute("direction"))) 176 out.add(arg); 177 else 178 in.add(arg); 179 } 180 else if ("annotation".equals(a.getNodeName())) { 181 Element e = (Element) a; 182 if (e.getAttribute("name").equals("org.freedesktop.DBus.Method.Error")) { 183 if (null == throwses) 184 throwses = e.getAttribute("value"); 185 else 186 throwses += ", " + e.getAttribute("value"); 187 exceptions.add(e.getAttribute("value")); 188 } else 189 annotations += parseAnnotation(e, imports, anns); 190 } 191 } 192 193 String sig = ""; 194 comment = ""; 195 sig += parseReturns(out, imports, tuples, structs); 196 197 sig += mangle(meth.getAttribute("name"))+"("; 198 199 char defaultname = 'a'; 200 String params = ""; 201 for (Element arg: in) { 202 String type = getJavaType(arg.getAttribute("type"), imports, structs, false, false); 203 String name = arg.getAttribute("name"); 204 if (null == name || "".equals(name)) name = ""+(defaultname++); 205 params += type+" "+mangle(name)+", "; 206 } 207 return ("".equals(comment) ? "" : " /**\n" + comment + " */\n") 208 + annotations + " public " + sig + 209 params.replaceAll("..$", "")+")"+ 210 (null == throwses? "": " throws "+throwses)+";"; 211 } parseSignal(Element signal, Set<String> imports, Map<StructStruct, Type[]> structs, Set<String> anns)212 String parseSignal(Element signal, Set<String> imports, Map<StructStruct, Type[]> structs, Set<String> anns) throws DBusException 213 { 214 Map<String, String> params = new HashMap<String, String>(); 215 Vector<String> porder = new Vector<String>(); 216 char defaultname = 'a'; 217 imports.add("org.freedesktop.dbus.DBusSignal"); 218 imports.add("org.freedesktop.dbus.exceptions.DBusException"); 219 String annotations = ""; 220 for (Node a: new IterableNodeList(signal.getChildNodes())) { 221 222 if (Node.ELEMENT_NODE != a.getNodeType()) continue; 223 224 checkNode(a, "arg", "annotation"); 225 226 if ("annotation".equals(a.getNodeName())) 227 annotations += parseAnnotation((Element) a, imports, anns); 228 else { 229 Element arg = (Element) a; 230 String type = getJavaType(arg.getAttribute("type"), imports, structs, false, false); 231 String name = arg.getAttribute("name"); 232 if (null == name || "".equals(name)) name = ""+(defaultname++); 233 params.put(mangle(name), type); 234 porder.add(mangle(name)); 235 } 236 } 237 238 String out = ""; 239 out += annotations; 240 out += " public static class "+signal.getAttribute("name"); 241 out += " extends DBusSignal\n {\n"; 242 for (String name: porder) 243 out += " public final "+params.get(name)+" "+name+";\n"; 244 out += " public "+signal.getAttribute("name")+"(String path"; 245 for (String name: porder) 246 out += ", "+params.get(name)+" "+name; 247 out += ") throws DBusException\n {\n super(path"; 248 for (String name: porder) 249 out += ", "+name; 250 out += ");\n"; 251 for (String name: porder) 252 out += " this."+name+" = "+name+";\n"; 253 out += " }\n"; 254 255 out += " }\n"; 256 return out; 257 } 258 parseAnnotation(Element ann, Set<String> imports, Set<String> annotations)259 String parseAnnotation(Element ann, Set<String> imports, Set<String> annotations) 260 { 261 String s = " @"+ann.getAttribute("name").replaceAll(".*\\.([^.]*)$","$1")+"("; 262 if (null != ann.getAttribute("value") 263 && !"".equals(ann.getAttribute("value"))) 264 s += '"'+ann.getAttribute("value")+'"'; 265 imports.add(ann.getAttribute("name")); 266 annotations.add(ann.getAttribute("name")); 267 return s += ")\n"; 268 } 269 parseInterface(Element iface, PrintStream out, Map<String,Integer> tuples, Map<StructStruct, Type[]> structs, Set<String> exceptions, Set<String> anns)270 void parseInterface(Element iface, PrintStream out, Map<String,Integer> tuples, Map<StructStruct, Type[]> structs, Set<String> exceptions, Set<String> anns) throws DBusException 271 { 272 if (null == iface.getAttribute("name") || 273 "".equals(iface.getAttribute("name"))) { 274 System.err.println(_("ERROR: Interface name was blank, failed")); 275 System.exit(1); 276 } 277 278 out.println("package "+iface.getAttribute("name").replaceAll("\\.[^.]*$","")+";"); 279 280 String methods = ""; 281 String signals = ""; 282 String annotations = ""; 283 Set<String> imports = new TreeSet<String>(); 284 imports.add("org.freedesktop.dbus.DBusInterface"); 285 for (Node meth: new IterableNodeList(iface.getChildNodes())) { 286 287 if (Node.ELEMENT_NODE != meth.getNodeType()) continue; 288 289 checkNode(meth, "method", "signal", "property", "annotation"); 290 291 if ("method".equals(meth.getNodeName())) 292 methods += parseMethod((Element) meth, imports, tuples, structs, exceptions, anns) + "\n"; 293 else if ("signal".equals(meth.getNodeName())) 294 signals += parseSignal((Element) meth, imports, structs, anns); 295 else if ("property".equals(meth.getNodeName())) 296 System.err.println("WARNING: Ignoring property"); 297 else if ("annotation".equals(meth.getNodeName())) 298 annotations += parseAnnotation((Element) meth, imports, anns); 299 } 300 301 if (imports.size() > 0) 302 for (String i: imports) 303 out.println("import "+i+";"); 304 305 out.print(annotations); 306 out.print("public interface "+iface.getAttribute("name").replaceAll("^.*\\.([^.]*)$","$1")); 307 out.println(" extends DBusInterface"); 308 out.println("{"); 309 out.println(signals); 310 out.println(methods); 311 out.println("}"); 312 } createException(String name, String pack, PrintStream out)313 void createException(String name, String pack, PrintStream out) throws DBusException 314 { 315 out.println("package "+pack+";"); 316 out.println("import org.freedesktop.dbus.DBusExecutionException;"); 317 out.print("public class "+name); 318 out.println(" extends DBusExecutionException"); 319 out.println("{"); 320 out.println(" public "+name+"(String message)"); 321 out.println(" {"); 322 out.println(" super(message);"); 323 out.println(" }"); 324 out.println("}"); 325 } createAnnotation(String name, String pack, PrintStream out)326 void createAnnotation(String name, String pack, PrintStream out) throws DBusException 327 { 328 out.println("package "+pack+";"); 329 out.println("import java.lang.annotation.Retention;"); 330 out.println("import java.lang.annotation.RetentionPolicy;"); 331 out.println("@Retention(RetentionPolicy.RUNTIME)"); 332 out.println("public @interface "+name); 333 out.println("{"); 334 out.println(" String value();"); 335 out.println("}"); 336 } createStruct(String name, Type[] type, String pack, PrintStream out, Map<StructStruct, Type[]> existing)337 void createStruct(String name, Type[] type, String pack, PrintStream out, Map<StructStruct, Type[]> existing) throws DBusException, IOException 338 { 339 out.println("package "+pack+";"); 340 341 Set<String> imports = new TreeSet<String>(); 342 imports.add("org.freedesktop.dbus.Position"); 343 imports.add("org.freedesktop.dbus.Struct"); 344 Map<StructStruct, Type[]> structs = new HashMap<StructStruct, Type[]>(existing); 345 String[] types = new String[type.length]; 346 for (int i = 0; i < type.length; i++) 347 types[i] = collapseType(type[i], imports, structs, false, false); 348 349 for (String im: imports) out.println("import "+im+";"); 350 351 out.println("public final class "+name+" extends Struct"); 352 out.println("{"); 353 int i = 0; 354 char c = 'a'; 355 String params = ""; 356 for (String t: types) { 357 out.println(" @Position("+i++ +")"); 358 out.println(" public final "+t+" "+c+";"); 359 params += t+" "+c+", "; 360 c++; 361 } 362 out.println(" public "+name+"("+params.replaceAll("..$", "")+")"); 363 out.println(" {"); 364 for (char d = 'a'; d < c; d++) 365 out.println(" this."+d+" = "+d+";"); 366 367 out.println(" }"); 368 out.println("}"); 369 370 structs = StructStruct.fillPackages(structs, pack); 371 Map<StructStruct, Type[]> tocreate = new HashMap<StructStruct, Type[]>(structs); 372 for (StructStruct ss: existing.keySet()) tocreate.remove(ss); 373 createStructs(tocreate, structs); 374 } createTuple(String name, int num, String pack, PrintStream out)375 void createTuple(String name, int num, String pack, PrintStream out) throws DBusException 376 { 377 out.println("package "+pack+";"); 378 out.println("import org.freedesktop.dbus.Position;"); 379 out.println("import org.freedesktop.dbus.Tuple;"); 380 out.println("/** Just a typed container class */"); 381 out.print("public final class "+name); 382 String types = " <"; 383 for (char v = 'A'; v < 'A'+num; v++) 384 types += v + ","; 385 out.print(types.replaceAll(",$","> ")); 386 out.println("extends Tuple"); 387 out.println("{"); 388 389 char t = 'A'; 390 char n = 'a'; 391 for (int i = 0; i < num; i++,t++,n++) { 392 out.println(" @Position("+i+")"); 393 out.println(" public final "+t+" "+n+";"); 394 } 395 396 out.print(" public "+name+"("); 397 String sig = ""; 398 t = 'A'; 399 n = 'a'; 400 for (int i = 0; i < num; i++,t++,n++) 401 sig += t+" "+n+", "; 402 out.println(sig.replaceAll(", $", ")")); 403 out.println(" {"); 404 for (char v = 'a'; v < 'a'+num; v++) 405 out.println(" this."+v+" = "+v+";"); 406 out.println(" }"); 407 408 out.println("}"); 409 } parseRoot(Element root)410 void parseRoot(Element root) throws DBusException, IOException 411 { 412 Map<StructStruct, Type[]> structs = new HashMap<StructStruct, Type[]>(); 413 Set<String> exceptions = new TreeSet<String>(); 414 Set<String> annotations = new TreeSet<String>(); 415 416 for (Node iface: new IterableNodeList(root.getChildNodes())) { 417 418 if (Node.ELEMENT_NODE != iface.getNodeType()) continue; 419 420 checkNode(iface, "interface", "node"); 421 422 if ("interface".equals(iface.getNodeName())) { 423 424 Map<String, Integer> tuples = new HashMap<String, Integer>(); 425 String name = ((Element) iface).getAttribute("name"); 426 String file = name.replaceAll("\\.","/")+".java"; 427 String path = file.replaceAll("/[^/]*$", ""); 428 String pack = name.replaceAll("\\.[^.]*$",""); 429 430 // don't create interfaces in org.freedesktop.DBus by default 431 if (pack.startsWith("org.freedesktop.DBus") && !builtin) continue; 432 433 factory.init(file, path); 434 parseInterface((Element) iface, 435 factory.createPrintStream(file), tuples, structs, exceptions, annotations); 436 437 structs = StructStruct.fillPackages(structs, pack); 438 createTuples(tuples, pack); 439 } 440 else if ("node".equals(iface.getNodeName())) 441 parseRoot((Element) iface); 442 else { 443 System.err.println(_("ERROR: Unknown node: ")+iface.getNodeName()); 444 System.exit(1); 445 } 446 } 447 448 createStructs(structs, structs); 449 createExceptions(exceptions); 450 createAnnotations(annotations); 451 } createAnnotations(Set<String> annotations)452 private void createAnnotations(Set<String> annotations) throws DBusException, IOException 453 { 454 for (String fqn: annotations) { 455 String name = fqn.replaceAll("^.*\\.([^.]*)$", "$1"); 456 String pack = fqn.replaceAll("\\.[^.]*$",""); 457 // don't create things in org.freedesktop.DBus by default 458 if (pack.startsWith("org.freedesktop.DBus") && !builtin) 459 continue; 460 String path = pack.replaceAll("\\.", "/"); 461 String file = name.replaceAll("\\.","/")+".java"; 462 factory.init(file, path); 463 createAnnotation(name, pack, 464 factory.createPrintStream(path, name)); 465 } 466 } createExceptions(Set<String> exceptions)467 private void createExceptions(Set<String> exceptions) throws DBusException, IOException 468 { 469 for (String fqn: exceptions) { 470 String name = fqn.replaceAll("^.*\\.([^.]*)$", "$1"); 471 String pack = fqn.replaceAll("\\.[^.]*$",""); 472 // don't create things in org.freedesktop.DBus by default 473 if (pack.startsWith("org.freedesktop.DBus") && !builtin) 474 continue; 475 String path = pack.replaceAll("\\.", "/"); 476 String file = name.replaceAll("\\.","/")+".java"; 477 factory.init(file, path); 478 createException(name, pack, 479 factory.createPrintStream(path, name)); 480 } 481 } createStructs(Map<StructStruct, Type[]> structs, Map<StructStruct, Type[]> existing)482 private void createStructs(Map<StructStruct, Type[]> structs, Map<StructStruct, Type[]> existing) throws DBusException, IOException 483 { 484 for (StructStruct ss: structs.keySet()) { 485 String file = ss.name.replaceAll("\\.","/")+".java"; 486 String path = ss.pack.replaceAll("\\.", "/"); 487 factory.init(file, path); 488 createStruct(ss.name, structs.get(ss), ss.pack, 489 factory.createPrintStream(path, ss.name), existing); 490 } 491 } 492 createTuples(Map<String, Integer> typeMap, String pack)493 private void createTuples(Map<String, Integer> typeMap, String pack) throws DBusException, IOException 494 { 495 for (String tname: typeMap.keySet()) 496 createTuple(tname, typeMap.get(tname), pack, 497 factory.createPrintStream(pack.replaceAll("\\.","/"), tname)); 498 } 499 500 public static abstract class PrintStreamFactory 501 { 502 init(String file, String path)503 public abstract void init(String file, String path); 504 505 /** 506 * @param path 507 * @param tname 508 * @return PrintStream 509 * @throws IOException 510 */ createPrintStream(String path, String tname)511 public PrintStream createPrintStream(String path, String tname) throws IOException 512 { 513 final String file = path+"/"+tname+".java"; 514 return createPrintStream(file); 515 } 516 517 /** 518 * @param file 519 * @return PrintStream 520 * @throws IOException 521 */ createPrintStream(final String file)522 public abstract PrintStream createPrintStream(final String file) throws IOException; 523 524 } 525 static class ConsoleStreamFactory extends PrintStreamFactory 526 { 527 528 @Override 529 public init(String file, String path)530 void init(String file, String path) 531 { 532 } 533 534 @Override 535 public createPrintStream(String file)536 PrintStream createPrintStream(String file) throws IOException 537 { 538 System.out.println("/* File: "+file+" */"); 539 return System.out; 540 } 541 createPrintStream(String path, String tname)542 public PrintStream createPrintStream(String path, String tname) throws IOException 543 { 544 return super.createPrintStream(path, tname); 545 } 546 547 } 548 549 static class FileStreamFactory extends PrintStreamFactory 550 { init(String file, String path)551 public void init(String file, String path) 552 { 553 new File(path).mkdirs(); 554 } 555 556 557 /** 558 * @param file 559 * @return 560 * @throws IOException 561 */ createPrintStream(final String file)562 public PrintStream createPrintStream(final String file) throws IOException 563 { 564 return new PrintStream(new FileOutputStream(file)); 565 } 566 567 } 568 checkNode(Node n, String... names)569 static void checkNode(Node n, String... names) 570 { 571 String expected = ""; 572 for (String name: names) { 573 if (name.equals(n.getNodeName())) return; 574 expected += name + " or "; 575 } 576 System.err.println(MessageFormat.format(_("ERROR: Expected {0}, got {1}, failed."), new Object[] { expected.replaceAll("....$", ""), n.getNodeName() })); 577 System.exit(1); 578 } 579 580 private final PrintStreamFactory factory; 581 582 static class Config 583 { 584 int bus = DBusConnection.SESSION; 585 String busname = null; 586 String object = null; 587 File datafile = null; 588 boolean printtree = false; 589 boolean fileout = false; 590 boolean builtin = false; 591 } 592 printSyntax()593 static void printSyntax() 594 { 595 printSyntax(System.err); 596 } printSyntax(PrintStream o)597 static void printSyntax(PrintStream o) 598 { 599 o.println("Syntax: CreateInterface <options> [file | busname object]"); 600 o.println(" Options: --no-ignore-builtin --system -y --session -s --create-files -f --help -h --version -v"); 601 } version()602 public static void version() 603 { 604 System.out.println("Java D-Bus Version "+System.getProperty("Version")); 605 System.exit(1); 606 } 607 parseParams(String[] args)608 static Config parseParams(String[] args) 609 { 610 Config config = new Config(); 611 for (String p: args) { 612 if ("--system".equals(p) || "-y".equals(p)) 613 config.bus = DBusConnection.SYSTEM; 614 else if ("--session".equals(p) || "-s".equals(p)) 615 config.bus = DBusConnection.SESSION; 616 else if ("--no-ignore-builtin".equals(p)) 617 config.builtin = true; 618 else if ("--create-files".equals(p) || "-f".equals(p)) 619 config.fileout = true; 620 else if ("--print-tree".equals(p) || "-p".equals(p)) 621 config.printtree = true; 622 else if ("--help".equals(p) || "-h".equals(p)) { 623 printSyntax(System.out); 624 System.exit(0); 625 } else if ("--version".equals(p) || "-v".equals(p)) { 626 version(); 627 System.exit(0); 628 } else if (p.startsWith("-")) { 629 System.err.println(_("ERROR: Unknown option: ")+p); 630 printSyntax(); 631 System.exit(1); 632 } 633 else { 634 if (null == config.busname) config.busname = p; 635 else if (null == config.object) config.object = p; 636 else { 637 printSyntax(); 638 System.exit(1); 639 } 640 } 641 } 642 if (null == config.busname) { 643 printSyntax(); 644 System.exit(1); 645 } 646 else if (null == config.object) { 647 config.datafile = new File(config.busname); 648 config.busname = null; 649 } 650 return config; 651 } 652 main(String[] args)653 public static void main(String[] args) throws Exception 654 { 655 Config config = parseParams(args); 656 657 Reader introspectdata = null; 658 659 if (null != config.busname) try { 660 DBusConnection conn = DBusConnection.getConnection(config.bus); 661 Introspectable in = conn.getRemoteObject(config.busname, config.object, Introspectable.class); 662 String id = in.Introspect(); 663 if (null == id) { 664 System.err.println(_("ERROR: Failed to get introspection data")); 665 System.exit(1); 666 } 667 introspectdata = new StringReader(id); 668 conn.disconnect(); 669 } catch (DBusException DBe) { 670 System.err.println(_("ERROR: Failure in DBus Communications: ")+DBe.getMessage()); 671 System.exit(1); 672 } catch (DBusExecutionException DEe) { 673 System.err.println(_("ERROR: Failure in DBus Communications: ")+DEe.getMessage()); 674 System.exit(1); 675 676 } else if (null != config.datafile) try { 677 introspectdata = new InputStreamReader(new FileInputStream(config.datafile)); 678 } catch (FileNotFoundException FNFe) { 679 System.err.println(_("ERROR: Could not find introspection file: ")+FNFe.getMessage()); 680 System.exit(1); 681 } 682 try { 683 PrintStreamFactory factory = config.fileout ? new FileStreamFactory() : new ConsoleStreamFactory(); 684 CreateInterface createInterface = new CreateInterface(factory, config.builtin); 685 createInterface.createInterface(introspectdata); 686 } catch (DBusException DBe) { 687 System.err.println("ERROR: "+DBe.getMessage()); 688 System.exit(1); 689 } 690 } 691 /** Output the interface for the supplied xml reader 692 * @param introspectdata The introspect data reader 693 * @throws ParserConfigurationException If the xml parser could not be configured 694 * @throws SAXException If a problem occurs reading the xml data 695 * @throws IOException If an IO error occurs 696 * @throws DBusException If the dbus related error occurs 697 */ createInterface(Reader introspectdata)698 public void createInterface(Reader introspectdata) throws ParserConfigurationException, SAXException, IOException, DBusException 699 { 700 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 701 DocumentBuilder builder = factory.newDocumentBuilder(); 702 Document document = builder.parse(new InputSource(introspectdata)); 703 704 Element root = document.getDocumentElement(); 705 checkNode(root, "node"); 706 parseRoot(root); 707 708 } 709 } 710 711 712