Changeset 168
- Timestamp:
- 04/11/08 13:59:39 (5 months ago)
- Location:
- Xml/xsd-fu/trunk
- Files:
-
- 3 modified
Legend:
- Unmodified
- Added
- Removed
-
Xml/xsd-fu/trunk/fu.py
r151 r168 1 1 """ 2 2 Object model and helper classes used in the generation of Java classes from 3 an OME XML (http://www.ome .xml.org) XSD document.3 an OME XML (http://www.ome-xml.org) XSD document. 4 4 """ 5 5 … … 51 51 # format='%(asctime)s %(levelname)s %(message)s') 52 52 53 # A global mapping from XSD Schema types and Java types 54 JAVA_TYPE_MAP = { 55 # Base types 56 'xsd:boolean': 'Boolean', 57 'xsd:dateTime': 'String', 58 'xsd:string': 'String', 59 'xsd:integer': 'Integer', 60 'xsd:positiveInteger': 'Integer', 61 'xsd:nonNegativeInteger': 'Integer', 62 'xsd:float': 'Float', 63 'xsd:anyURI': 'String', 64 # Hacks 65 'MIMEtype': 'String', 66 'RedChannel': 'ChannelSpecTypeNode', 67 'GreenChannel': 'ChannelSpecTypeNode', 68 'BlueChannel': 'ChannelSpecTypeNode', 69 'AcquiredPixelsRef': 'PixelsNode', 70 'Description': 'String', 71 } 53 # A global mapping from XSD Schema types and Java types that is used to 54 # inform and override type mappings for OME Model properties which are 55 # comprised of XML Schema attributes, elements and OME XML reference virtual 56 # types. 57 JAVA_TYPE_MAP = None 58 59 # A global type mapping from XSD Schema types to Java base classes that is 60 # used to override places in the model where we do not wish subclassing to 61 # take place. 62 JAVA_BASE_TYPE_MAP = None 63 64 # Types which have not been recognized as explicit defines (XML Schema 65 # definitions that warrant a the creation of a first class model object) that 66 # we wish to be treated otherwise. As part of the code generation process they 67 # will also be confirmed to be top-level types. 68 EXPLICIT_DEFINE_OVERRIDE = ('Dichroic', 'Experimenter', 'FilterSet') 69 70 def updateTypeMaps(namespace): 71 """ 72 Updates the type maps with a new namespace. **Must** be executed at least 73 once, **before** node class file generation. 74 """ 75 global JAVA_TYPE_MAP 76 JAVA_TYPE_MAP = { 77 # Base types 78 namespace + 'boolean': 'Boolean', 79 namespace + 'dateTime': 'String', 80 namespace + 'string': 'String', 81 namespace + 'integer': 'Integer', 82 namespace + 'positiveInteger': 'Integer', 83 namespace + 'nonNegativeInteger': 'Integer', 84 namespace + 'float': 'Float', 85 namespace + 'anyURI': 'String', 86 # Hacks 87 'PercentFraction': 'Float', 88 'MIMEtype': 'String', 89 'RedChannel': 'ChannelSpecTypeNode', 90 'GreenChannel': 'ChannelSpecTypeNode', 91 'BlueChannel': 'ChannelSpecTypeNode', 92 'AcquiredPixelsRef': 'PixelsNode', 93 'Description': 'String', 94 'Leader': 'ExperimenterRefNode', 95 } 96 97 global JAVA_BASE_TYPE_MAP 98 JAVA_BASE_TYPE_MAP = { 99 'UniversallyUniqueIdentifier': DEFAULT_BASE_CLASS 100 } 72 101 73 102 # The list of properties not to process. 74 103 DO_NOT_PROCESS = ["ID"] 75 104 105 # Default root XML Schema namespace 106 DEFAULT_NAMESPACE = "xsd:" 107 76 108 # The default Java base class for OME XML model objects. 77 109 DEFAULT_BASE_CLASS = "OMEXMLNode" 78 110 79 111 # The default Java package for OME XML model objects. 80 DEFAULT_PACKAGE = "o rg.openmicroscopy.xml2007"112 DEFAULT_PACKAGE = "ome.xml.r2008" 81 113 82 114 # The default template for class processing. … … 93 125 A "virtual" property delegate to be used with "reference" 94 126 OMEModelProperty instances. This delegate conforms loosely to the same 95 interface as a delegate coming from generateDS. 127 interface as a delegate coming from generateDS (ie. an "attribute" or 128 an "element"). 96 129 """ 97 130 def __init__(self, dataType): … … 99 132 self.dataType = dataType 100 133 # Ensures property code which is looking for elements or attributes 101 # which conform to an enumeration can function.134 # which conform to an enumeration can still function. 102 135 self.values = None 103 136 … … 116 149 class OMEModelProperty(object): 117 150 """ 118 An aggregate type representing either an OME XML Schema element or 119 attribute. This class equates conceptually to an instance variable which 120 may be of a singular type or a collection. 151 An aggregate type representing either an OME XML Schema element, 152 attribute or our OME XML Schema "Reference" meta element (handled by the 153 ReferenceDelegate class). This class equates conceptually to an object 154 oriented language instance variable which may be of a singular type or a 155 collection. 121 156 """ 122 157 … … 131 166 return self.delegate.getData_type() 132 167 return self.delegate.getType() 133 134 168 type = property(_get_type, doc="""The property's XML Schema data type.""") 135 169 … … 138 172 return 1 139 173 return self.delegate.getMaxOccurs() 140 141 174 maxOccurs = property(_get_maxOccurs, 142 175 doc="""The maximum number of occurances for this property.""") … … 148 181 return 1 149 182 return self.delegate.getMinOccurs() 150 151 183 minOccurs = property(_get_minOccurs, 152 184 doc="""The minimum number of occurances for this property.""") … … 154 186 def _get_name(self): 155 187 return self.delegate.getName() 156 157 188 name = property(_get_name, doc="""The property's name.""") 158 189 … … 190 221 raise ModelProcessingError, \ 191 222 "Unable to find Java type for %s" % self.type 192 193 223 javaType = property(_get_javaType, doc="""The property's Java type.""") 194 224 … … 198 228 i = m.start() 199 229 return self.name[:i].lower() + self.name[i:] 200 201 230 javaArgumentName = property(_get_javaArgumentName, 202 231 doc="""The property's Java argument name (camelCase).""") … … 271 300 def _get_javaBase(self): 272 301 base = self.element.getBase() 302 if base in JAVA_BASE_TYPE_MAP: 303 return JAVA_BASE_TYPE_MAP[base] 304 if base is None and self.element.attrs['type'] != self.name: 305 base = self.element.attrs['type'] 273 306 if base is None: 274 307 return DEFAULT_BASE_CLASS 275 308 return base + "Node" 276 277 309 javaBase = property(_get_javaBase, 278 310 doc="""The model object's Java base class.""") … … 282 314 return self.properties["ID"].javaType 283 315 return None 284 285 316 refNodeName = property(_get_refNodeName, 286 317 doc="""The name of this node's reference node; None otherwise.""") … … 346 377 Process an element (a leaf). 347 378 """ 348 if not element.isExplicitDefine(): 349 logging.info("Element %s.%s not an explicit define, skipping." % (parent, element)) 379 e = element 380 if not e.isExplicitDefine() \ 381 and (e.name not in EXPLICIT_DEFINE_OVERRIDE or not e.topLevel): 382 logging.info("Element %s.%s not an explicit define, skipping." % (parent, e)) 350 383 return 351 if e lement.getMixedExtensionError():352 logging.error("Element %s.%s extension chain contains mixed and non-mixed content, skipping." % (parent, e lement))384 if e.getMixedExtensionError(): 385 logging.error("Element %s.%s extension chain contains mixed and non-mixed content, skipping." % (parent, e)) 353 386 return 354 obj = OMEModelObject(e lement, self)355 self.addObject(e lement, obj)356 self.processAttributes(e lement)387 obj = OMEModelObject(e, self) 388 self.addObject(e, obj) 389 self.processAttributes(e) 357 390 358 391 def processTree(self, elements, parent=None): … … 427 460 self.DO_NOT_PROCESS = DO_NOT_PROCESS 428 461 429 def parseXmlSchema(filename ):462 def parseXmlSchema(filename, namespace=DEFAULT_NAMESPACE): 430 463 """ 431 464 Entry point for XML Schema parsing into an OME Model. 432 465 """ 433 466 # The following two statements are required to "prime" the generateDS 434 # code .435 namespace = 'xsd:'467 # code and ensure we have reasonable namespace support. 468 logging.debug("Namespace: %s" % namespace) 436 469 set_type_constants(namespace) 470 updateTypeMaps(namespace) 471 logging.debug("Java type map: %s" % JAVA_TYPE_MAP) 437 472 438 473 parser = sax.make_parser() … … 441 476 parser.parse(filename) 442 477 443 ch.getRoot().annotate() 478 root = ch.getRoot() 479 if root is None: 480 raise ModelProcessingError( 481 "No model objects found, have you set the correct namespace?") 482 root.annotate() 444 483 return OMEModel.process(ch) -
Xml/xsd-fu/trunk/generateDS/generateDS.py
r112 r168 204 204 205 205 206 class XschemaElementBase :206 class XschemaElementBase(object): 207 207 def __init__(self): 208 208 pass … … 667 667 668 668 669 class XschemaAttributeGroup :669 class XschemaAttributeGroup(object): 670 670 def __init__(self, name='', group=None): 671 671 self.name = name … … 695 695 # end class XschemaAttributeGroup 696 696 697 class XschemaAttribute :697 class XschemaAttribute(object): 698 698 def __init__(self, name, data_type='xs:string', use='optional'): 699 699 self.name = name … … 871 871 SimpleTypeDict[stName] = element 872 872 self.stack.append(element) 873 self.inSimpleType = 1873 self.inSimpleType += 1 874 874 elif name == RestrictionType: 875 875 # If we are in a simpleType, capture the name of 876 876 # the restriction base. 877 if self.inSimpleType and 'base' in attrs.keys():877 if self.inSimpleType > 0 and 'base' in attrs.keys(): 878 878 self.stack[-1].setBase(attrs['base']) 879 879 self.inRestrictionType = 1 … … 890 890 # find the last element. 891 891 element = None 892 for entry in list(stack).reverse(): 892 reverse = list(self.stack) 893 reverse.reverse() 894 logging.debug("Found enum, reverse stack: %s" % reverse) 895 for entry in reverse: 893 896 if type(entry) == XschemaElement: 894 897 element = entry 895 898 if element is None: 896 899 sys.stderr.write( 897 'Cannot find element to attach enumeration: %s ' % \898 value)900 'Cannot find element to attach enumeration: %s\n' % \ 901 attrs['value']) 899 902 sys.exit(-1) 900 903 element.values.append(attrs['value']) 901 elif self.inSimpleType and attrs.has_key('value'):904 elif self.inSimpleType > 0 and attrs.has_key('value'): 902 905 # We've been defined as a simpleType on our own. 903 906 self.stack[-1].values.append(attrs['value']) … … 920 923 def endElement(self, name): 921 924 logging.debug("End element: %s" % (name)) 922 logging.debug("End element stack : %d" % (len(self.stack)))923 if name == SimpleTypeType and self.inSimpleType :924 self.inSimpleType = 0925 logging.debug("End element stack length: %d" % (len(self.stack))) 926 if name == SimpleTypeType and self.inSimpleType > 0: 927 self.inSimpleType -= 1 925 928 # If the simpleType is directly off the root, it may be used to 926 929 # qualify the type of many elements and/or attributes so we … … 935 938 self.inNonanonymousComplexType = 0 936 939 element = self.stack.pop() 940 logging.debug("Adding %s as child of %s" % (element, self.stack[-1])) 937 941 self.stack[-1].addChild(element) 938 942 elif name == ComplexTypeType: … … 975 979 pass 976 980 elif name == ListType: 977 # List types are only used with a parent simpleType and can have a978 # simpleType child. So, if we're in a list type we have to be979 # careful to reset the inSimpleType flag otherwise the handler's980 # internal stack will not be unrolled correctly.981 self.inSimpleType = 1982 981 self.inListType = 0 983 982 -
Xml/xsd-fu/trunk/xsd-fu
r151 r168 46 46 cmd = sys.argv[0] 47 47 print """%s 48 Usage: %s [- p package] -o <output_dir> <path/to/ome.xsd>48 Usage: %s [-n xsd_namespace] [-p package] -o <output_dir> <path/to/ome.xsd> 49 49 Generates Java classes from an OME XML Schema definition. 50 50 51 Default package: "%s" 52 Default namespace: "%s" 53 51 54 Examples: 52 %s - p ome.xml -o ome/xml schemas/ome.xsd55 %s -n 'xs:' -p ome.xml -o ome/xml schemas/ome.xsd 53 56 54 Report bugs to Chris Allan <callan@blackcat.ca>""" % (error, cmd, cmd) 57 Report bugs to Chris Allan <callan@blackcat.ca>""" % \ 58 (error, cmd, DEFAULT_PACKAGE, NAMESPACE, cmd) 55 59 sys.exit(2) 56 60 … … 61 65 """ 62 66 try: 63 options, args = getopt(sys.argv[1:], "o:p: ")67 options, args = getopt(sys.argv[1:], "o:p:n:") 64 68 except GetoptError, (msg, opt): 65 69 usage(msg) … … 70 74 outputDirectory = None 71 75 package = DEFAULT_PACKAGE 76 namespace = DEFAULT_NAMESPACE 72 77 for option, argument in options: 73 78 if option == "-o": … … 75 80 if option == "-p": 76 81 package = argument 82 if option == "-n": 83 namespace = argument 77 84 if outputDirectory is None: 78 85 usage("Output directory must be specified!") … … 81 88 sys.exit(1) 82 89 83 model = parseXmlSchema(args[0] )90 model = parseXmlSchema(args[0], namespace) 84 91 fu = TemplateInfo(outputDirectory, package) 85 92 template = NewTextTemplate(open(CLASS_TEMPLATE).read()) … … 97 104 outputDirectory = None 98 105 package = DEFAULT_PACKAGE 106 namespace = "xs:" 99 107 100 model = parseXmlSchema("tmp/ ome.xsd")108 model = parseXmlSchema("tmp/schemas/2003/ome.xsd", namespace) 101 109 fu = TemplateInfo(outputDirectory, package) 102 110 template = NewTextTemplate(open(CLASS_TEMPLATE).read()) 103 111 for obj in model.objects.values(): 104 if obj.name == " Laser":112 if obj.name == "Image": 105 113 print " +-- %s(%s)" % (obj.name, obj.base) 106 114 for prop in obj.properties.values():
