• Login
  • Help/Guide
  • About Trac
  • Preferences
  • Wiki
  • Timeline
  • Roadmap
  • Browse Source
  • View Tickets
  • Search

Context Navigation

  • ← Previous Changeset
  • Next Changeset →

Changeset 168

Show
Ignore:
Timestamp:
04/11/08 13:59:39 (5 months ago)
Author:
callan
Message:

generateDS bug fixes:

  • Nested simpleType definitions now handled universally (booleans are insufficient)
  • New style classes throughout

xsd-fu additions:

  • Basic support for OME XML 2003 model (some hacks required)
  • Full support for OME XML 2008 model
  • XML Schema namespace definition support with "-n" command line argument
  • More configuration of certain overrides in xsd-fu mapping now available
Location:
Xml/xsd-fu/trunk
Files:
3 modified

  • fu.py (modified) (16 diffs)
  • generateDS/generateDS.py (modified) (8 diffs)
  • xsd-fu (modified) (6 diffs)

Legend:

Unmodified
Added
Removed
  • Xml/xsd-fu/trunk/fu.py

    r151 r168  
    11""" 
    22Object model and helper classes used in the generation of Java classes from 
    3 an OME XML (http://www.ome.xml.org) XSD document. 
     3an OME XML (http://www.ome-xml.org) XSD document. 
    44""" 
    55 
    … …  
    5151#                    format='%(asctime)s %(levelname)s %(message)s') 
    5252 
    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. 
     57JAVA_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. 
     62JAVA_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. 
     68EXPLICIT_DEFINE_OVERRIDE = ('Dichroic', 'Experimenter', 'FilterSet') 
     69 
     70def 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        } 
    72101 
    73102# The list of properties not to process. 
    74103DO_NOT_PROCESS = ["ID"] 
    75104 
     105# Default root XML Schema namespace 
     106DEFAULT_NAMESPACE = "xsd:" 
     107 
    76108# The default Java base class for OME XML model objects. 
    77109DEFAULT_BASE_CLASS = "OMEXMLNode" 
    78110 
    79111# The default Java package for OME XML model objects. 
    80 DEFAULT_PACKAGE = "org.openmicroscopy.xml2007" 
     112DEFAULT_PACKAGE = "ome.xml.r2008" 
    81113 
    82114# The default template for class processing. 
    … …  
    93125        A "virtual" property delegate to be used with "reference"  
    94126        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"). 
    96129        """ 
    97130        def __init__(self, dataType): 
    … …  
    99132                self.dataType = dataType 
    100133                # 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. 
    102135                self.values = None 
    103136         
    … …  
    116149class OMEModelProperty(object): 
    117150        """ 
    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. 
    121156        """ 
    122157         
    … …  
    131166                        return self.delegate.getData_type() 
    132167                return self.delegate.getType() 
    133                  
    134168        type = property(_get_type, doc="""The property's XML Schema data type.""") 
    135169                         
    … …  
    138172                        return 1 
    139173                return self.delegate.getMaxOccurs() 
    140                  
    141174        maxOccurs = property(_get_maxOccurs, 
    142175                doc="""The maximum number of occurances for this property.""") 
    … …  
    148181                        return 1 
    149182                return self.delegate.getMinOccurs() 
    150                  
    151183        minOccurs = property(_get_minOccurs, 
    152184                doc="""The minimum number of occurances for this property.""") 
    … …  
    154186        def _get_name(self): 
    155187                return self.delegate.getName() 
    156                  
    157188        name = property(_get_name, doc="""The property's name.""") 
    158189         
    … …  
    190221                        raise ModelProcessingError, \ 
    191222                                "Unable to find Java type for %s" % self.type 
    192                  
    193223        javaType = property(_get_javaType, doc="""The property's Java type.""") 
    194224         
    … …  
    198228                i = m.start() 
    199229                return self.name[:i].lower() + self.name[i:] 
    200          
    201230        javaArgumentName = property(_get_javaArgumentName, 
    202231                doc="""The property's Java argument name (camelCase).""") 
    … …  
    271300        def _get_javaBase(self): 
    272301                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'] 
    273306                if base is None: 
    274307                        return DEFAULT_BASE_CLASS 
    275308                return base + "Node" 
    276  
    277309        javaBase = property(_get_javaBase,  
    278310                doc="""The model object's Java base class.""") 
    … …  
    282314                        return self.properties["ID"].javaType 
    283315                return None 
    284                  
    285316        refNodeName = property(_get_refNodeName, 
    286317                doc="""The name of this node's reference node; None otherwise.""") 
    … …  
    346377                Process an element (a leaf). 
    347378                """ 
    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)) 
    350383                        return 
    351                 if element.getMixedExtensionError(): 
    352                         logging.error("Element %s.%s extension chain contains mixed and non-mixed content, skipping." % (parent, element)) 
     384                if e.getMixedExtensionError(): 
     385                        logging.error("Element %s.%s extension chain contains mixed and non-mixed content, skipping." % (parent, e)) 
    353386                        return 
    354                 obj = OMEModelObject(element, self) 
    355                 self.addObject(element, obj) 
    356                 self.processAttributes(element) 
     387                obj = OMEModelObject(e, self) 
     388                self.addObject(e, obj) 
     389                self.processAttributes(e) 
    357390 
    358391        def processTree(self, elements, parent=None): 
    … …  
    427460                self.DO_NOT_PROCESS = DO_NOT_PROCESS 
    428461 
    429 def parseXmlSchema(filename): 
     462def parseXmlSchema(filename, namespace=DEFAULT_NAMESPACE): 
    430463        """ 
    431464        Entry point for XML Schema parsing into an OME Model. 
    432465        """ 
    433466        # 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) 
    436469        set_type_constants(namespace) 
     470        updateTypeMaps(namespace) 
     471        logging.debug("Java type map: %s" % JAVA_TYPE_MAP) 
    437472 
    438473        parser = sax.make_parser() 
    … …  
    441476        parser.parse(filename) 
    442477 
    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() 
    444483        return OMEModel.process(ch) 
  • Xml/xsd-fu/trunk/generateDS/generateDS.py

    r112 r168  
    204204 
    205205 
    206 class XschemaElementBase: 
     206class XschemaElementBase(object): 
    207207    def __init__(self): 
    208208        pass 
    … …  
    667667 
    668668 
    669 class XschemaAttributeGroup: 
     669class XschemaAttributeGroup(object): 
    670670    def __init__(self, name='', group=None): 
    671671        self.name = name 
    … …  
    695695# end class XschemaAttributeGroup 
    696696 
    697 class XschemaAttribute: 
     697class XschemaAttribute(object): 
    698698    def __init__(self, name, data_type='xs:string', use='optional'): 
    699699        self.name = name 
    … …  
    871871            SimpleTypeDict[stName] = element 
    872872            self.stack.append(element) 
    873             self.inSimpleType = 1 
     873            self.inSimpleType += 1 
    874874        elif name == RestrictionType: 
    875875            # If we are in a simpleType, capture the name of 
    876876            #   the restriction base. 
    877             if self.inSimpleType and 'base' in attrs.keys(): 
     877            if self.inSimpleType > 0 and 'base' in attrs.keys(): 
    878878                self.stack[-1].setBase(attrs['base']) 
    879879            self.inRestrictionType = 1 
    … …  
    890890                # find the last element. 
    891891                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: 
    893896                    if type(entry) == XschemaElement: 
    894897                        element = entry 
    895898                if element is None: 
    896899                    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']) 
    899902                    sys.exit(-1) 
    900903                element.values.append(attrs['value']) 
    901             elif self.inSimpleType and attrs.has_key('value'): 
     904            elif self.inSimpleType > 0 and attrs.has_key('value'): 
    902905                # We've been defined as a simpleType on our own. 
    903906                self.stack[-1].values.append(attrs['value']) 
    … …  
    920923    def endElement(self, name): 
    921924        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 = 0 
     925        logging.debug("End element stack length: %d" % (len(self.stack))) 
     926        if name == SimpleTypeType and self.inSimpleType > 0: 
     927            self.inSimpleType -= 1 
    925928            # If the simpleType is directly off the root, it may be used to  
    926929            # qualify the type of many elements and/or attributes so we  
    … …  
    935938            self.inNonanonymousComplexType = 0 
    936939            element = self.stack.pop() 
     940            logging.debug("Adding %s as child of %s" % (element, self.stack[-1])) 
    937941            self.stack[-1].addChild(element) 
    938942        elif name == ComplexTypeType: 
    … …  
    975979            pass 
    976980        elif name == ListType: 
    977             # List types are only used with a parent simpleType and can have a 
    978             # simpleType child. So, if we're in a list type we have to be 
    979             # careful to reset the inSimpleType flag otherwise the handler's 
    980             # internal stack will not be unrolled correctly. 
    981             self.inSimpleType = 1 
    982981            self.inListType = 0 
    983982 
  • Xml/xsd-fu/trunk/xsd-fu

    r151 r168  
    4646        cmd = sys.argv[0] 
    4747        print """%s 
    48 Usage: %s [-p package] -o <output_dir> <path/to/ome.xsd> 
     48Usage: %s [-n xsd_namespace] [-p package] -o <output_dir> <path/to/ome.xsd> 
    4949Generates Java classes from an OME XML Schema definition. 
    5050 
     51Default package: "%s" 
     52Default namespace: "%s" 
     53 
    5154Examples: 
    52   %s -p ome.xml -o ome/xml schemas/ome.xsd 
     55  %s -n 'xs:' -p ome.xml -o ome/xml schemas/ome.xsd 
    5356 
    54 Report bugs to Chris Allan <callan@blackcat.ca>""" % (error, cmd, cmd) 
     57Report bugs to Chris Allan <callan@blackcat.ca>""" % \ 
     58        (error, cmd, DEFAULT_PACKAGE, NAMESPACE, cmd) 
    5559        sys.exit(2) 
    5660 
    … …  
    6165        """ 
    6266        try: 
    63                 options, args = getopt(sys.argv[1:], "o:p:") 
     67                options, args = getopt(sys.argv[1:], "o:p:n:") 
    6468        except GetoptError, (msg, opt): 
    6569                usage(msg) 
    … …  
    7074        outputDirectory = None 
    7175        package = DEFAULT_PACKAGE 
     76        namespace = DEFAULT_NAMESPACE 
    7277        for option, argument in options: 
    7378                if option == "-o": 
    … …  
    7580                if option == "-p": 
    7681                        package = argument 
     82                if option == "-n": 
     83                        namespace = argument 
    7784        if outputDirectory is None: 
    7885                usage("Output directory must be specified!") 
    … …  
    8188                sys.exit(1) 
    8289 
    83         model = parseXmlSchema(args[0]) 
     90        model = parseXmlSchema(args[0], namespace) 
    8491        fu = TemplateInfo(outputDirectory, package) 
    8592        template = NewTextTemplate(open(CLASS_TEMPLATE).read()) 
    … …  
    97104        outputDirectory = None 
    98105        package = DEFAULT_PACKAGE 
     106        namespace = "xs:" 
    99107 
    100         model = parseXmlSchema("tmp/ome.xsd") 
     108        model = parseXmlSchema("tmp/schemas/2003/ome.xsd", namespace) 
    101109        fu = TemplateInfo(outputDirectory, package) 
    102110        template = NewTextTemplate(open(CLASS_TEMPLATE).read()) 
    103111        for obj in model.objects.values(): 
    104                 if obj.name == "Laser": 
     112                if obj.name == "Image": 
    105113                        print " +-- %s(%s)" % (obj.name, obj.base) 
    106114                        for prop in obj.properties.values(): 

Download in other formats:

  • Unified Diff
  • Zip Archive

Trac Powered

Powered by Trac 0.11
By Edgewall Software.

Visit the Trac open source project at
http://trac.edgewall.org/