| 1 | ## Copyright 2005, 2006 Virginia Polytechnic Institute and State University |
|---|
| 2 | ## |
|---|
| 3 | ## This file is part of the OSSIE Waveform Developer. |
|---|
| 4 | ## |
|---|
| 5 | ## OSSIE Waveform Developer is free software; you can redistribute it and/or modify |
|---|
| 6 | ## it under the terms of the GNU General Public License as published by |
|---|
| 7 | ## the Free Software Foundation; either version 2 of the License, or |
|---|
| 8 | ## (at your option) any later version. |
|---|
| 9 | ## |
|---|
| 10 | ## OSSIE Waveform Developer is distributed in the hope that it will be useful, |
|---|
| 11 | ## but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 12 | ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 13 | ## GNU General Public License for more details. |
|---|
| 14 | ## |
|---|
| 15 | ## You should have received a copy of the GNU General Public License |
|---|
| 16 | ## along with OSSIE Waveform Developer; if not, write to the Free Software |
|---|
| 17 | ## Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 18 | |
|---|
| 19 | import os, sys |
|---|
| 20 | import amara |
|---|
| 21 | from amara import binderytools |
|---|
| 22 | import ComponentClass as CC |
|---|
| 23 | from errorMsg import * |
|---|
| 24 | |
|---|
| 25 | availableTypes = ["boolean", "char", "double", "float", "short", "long", |
|---|
| 26 | "objref", "octet", "string", "ulong","ushort"] |
|---|
| 27 | availableKinds = ["allocation", "configure", "test", "execparam", "factoryparam"] |
|---|
| 28 | availableActions = ["eq", "ne", "gt", "lt", "ge", "le", "external"] |
|---|
| 29 | availableModes = ["readonly", "readwrite", "writeonly"] |
|---|
| 30 | |
|---|
| 31 | def getResource(path,Rname,parent): |
|---|
| 32 | |
|---|
| 33 | scdPath = findFile(path,Rname,".scd.xml") |
|---|
| 34 | if scdPath == None: |
|---|
| 35 | errorMsg(parent,"No scd file found for: " + Rname) |
|---|
| 36 | return |
|---|
| 37 | |
|---|
| 38 | spdPath = findFile(path,Rname,".spd.xml") |
|---|
| 39 | prfPath = findFile(path,Rname,".prf.xml") |
|---|
| 40 | |
|---|
| 41 | # |
|---|
| 42 | # Build the main component or device from the SCD file |
|---|
| 43 | # |
|---|
| 44 | doc_scd = amara.parse(stripDoctype(scdPath)) |
|---|
| 45 | #doc_scd = binderytools.bind_file(scdPath) |
|---|
| 46 | if not hasattr(doc_scd.softwarecomponent,'componenttype'): |
|---|
| 47 | errorMsg(parent,"Invalid file: " + scdPath) |
|---|
| 48 | return None |
|---|
| 49 | |
|---|
| 50 | #Instantiate a new component of the appropriate type |
|---|
| 51 | if doc_scd.softwarecomponent.componenttype == u'resource': |
|---|
| 52 | newComp = CC.Component(name=Rname,type='resource') |
|---|
| 53 | elif doc_scd.softwarecomponent.componenttype == u'executabledevice': |
|---|
| 54 | newComp = CC.Component(name=Rname,type='executabledevice') |
|---|
| 55 | elif doc_scd.softwarecomponent.componenttype == u'loadabledevice': |
|---|
| 56 | newComp = CC.Component(name=Rname,type='loadabledevice') |
|---|
| 57 | elif doc_scd.softwarecomponent.componenttype == u'device': |
|---|
| 58 | newComp = CC.Component(name=Rname,type='device') |
|---|
| 59 | else: |
|---|
| 60 | errorMsg(parent,"Can't identify resource type for: " + Rname) |
|---|
| 61 | return None |
|---|
| 62 | |
|---|
| 63 | # Get the Ports |
|---|
| 64 | if hasattr(doc_scd.softwarecomponent.componentfeatures,'ports'): |
|---|
| 65 | ports = doc_scd.softwarecomponent.componentfeatures.ports |
|---|
| 66 | if hasattr(ports,'provides'): |
|---|
| 67 | for p in ports.provides: |
|---|
| 68 | tmpName = p.providesname |
|---|
| 69 | tmpInt = getInterface(p.repid,tmpName) |
|---|
| 70 | if tmpInt == None: |
|---|
| 71 | return None |
|---|
| 72 | tmpType = p.porttype.type |
|---|
| 73 | newPort = CC.Port(tmpName,tmpInt,type='Provides',portType=tmpType) |
|---|
| 74 | newComp.ports.append(newPort) |
|---|
| 75 | |
|---|
| 76 | if hasattr(ports,'uses'): |
|---|
| 77 | for p in ports.uses: |
|---|
| 78 | tmpName = p.usesname |
|---|
| 79 | tmpInt = getInterface(p.repid,tmpName) |
|---|
| 80 | if tmpInt == None: |
|---|
| 81 | return None |
|---|
| 82 | tmpType = p.porttype.type |
|---|
| 83 | newPort = CC.Port(tmpName,tmpInt,type='Uses',portType=tmpType) |
|---|
| 84 | newComp.ports.append(newPort) |
|---|
| 85 | |
|---|
| 86 | # Make sure that xml and code are not generated for this resource |
|---|
| 87 | newComp.generate = False |
|---|
| 88 | |
|---|
| 89 | # Store the name of the file without the suffix (.scd.xml) |
|---|
| 90 | i = scdPath.rfind("/") |
|---|
| 91 | if i != -1: |
|---|
| 92 | newComp.xmlName = scdPath[i+1:-8] |
|---|
| 93 | else: |
|---|
| 94 | newComp.xmlName = scdPath[:-8] |
|---|
| 95 | |
|---|
| 96 | # |
|---|
| 97 | # Import the properties from the PRF file |
|---|
| 98 | # |
|---|
| 99 | # If there are no properties, just return the component as is |
|---|
| 100 | if prfPath == None: |
|---|
| 101 | return newComp |
|---|
| 102 | |
|---|
| 103 | doc_prf = amara.parse(stripDoctype(prfPath)) |
|---|
| 104 | #doc_prf = binderytools.bind_file(prfPath) |
|---|
| 105 | if not hasattr(doc_prf,'properties'): |
|---|
| 106 | errorMsg(parent,"Invalid file: " + prfPath) |
|---|
| 107 | return None |
|---|
| 108 | |
|---|
| 109 | if hasattr(doc_prf.properties,"simple"): |
|---|
| 110 | for s in doc_prf.properties.simple: |
|---|
| 111 | p = getSimpleProperty(s) |
|---|
| 112 | if p == None: |
|---|
| 113 | #errorMsg(parent,"Invalid file: " + prfPath) |
|---|
| 114 | continue |
|---|
| 115 | newComp.properties.append(p) |
|---|
| 116 | |
|---|
| 117 | if hasattr(doc_prf.properties,"simplesequence"): |
|---|
| 118 | for s in doc_prf.properties.simplesequence: |
|---|
| 119 | p = getSimpleSequenceProperty(s) |
|---|
| 120 | if p == None: |
|---|
| 121 | #errorMsg(parent,"Invalid file: " + prfPath) |
|---|
| 122 | continue |
|---|
| 123 | newComp.properties.append(p) |
|---|
| 124 | |
|---|
| 125 | return newComp |
|---|
| 126 | |
|---|
| 127 | def getInterface(repid,name): |
|---|
| 128 | try: |
|---|
| 129 | repid = repid.strip('IDL:') |
|---|
| 130 | repid = repid[:repid.rfind(':')] |
|---|
| 131 | tmpNS = repid[:repid.find('/')] |
|---|
| 132 | tmpName = repid[repid.find('/')+1:] |
|---|
| 133 | newInt = CC.Interface(tmpName,nameSpace=tmpNS) |
|---|
| 134 | return newInt |
|---|
| 135 | |
|---|
| 136 | except: |
|---|
| 137 | errorMsg(parent,"Can't read the Interface information for port: " + name) |
|---|
| 138 | return None |
|---|
| 139 | |
|---|
| 140 | |
|---|
| 141 | def findFile(path,Rname,suf): |
|---|
| 142 | tmpf = None |
|---|
| 143 | if os.path.isfile(path + '/' + Rname +'Resource'+suf): |
|---|
| 144 | tmpf = path + '/' + Rname +'Resource' + suf |
|---|
| 145 | elif os.path.isfile(path + '/' + Rname + suf): |
|---|
| 146 | tmpf = path + '/' + Rname + suf |
|---|
| 147 | else: |
|---|
| 148 | tmpFiles = os.listdir(path) |
|---|
| 149 | for f in tmpFiles: |
|---|
| 150 | if len(f)>=8 and f[-8:] == suf: |
|---|
| 151 | tmpf = path + '/' + f |
|---|
| 152 | break |
|---|
| 153 | return tmpf |
|---|
| 154 | |
|---|
| 155 | def stripDoctype(xmlfile): |
|---|
| 156 | """Strips out the DOCTYPE checking because the dtd files are positioned |
|---|
| 157 | in a relative location to the SCA (OSSIE) filesystem, so when Amara |
|---|
| 158 | trys to validate against them, it bails out looking for the file. |
|---|
| 159 | Returns a string representation of the xml file without the DOCTYPE line.""" |
|---|
| 160 | |
|---|
| 161 | file = open(xmlfile, 'r') |
|---|
| 162 | xml = '' |
|---|
| 163 | line = file.readline() |
|---|
| 164 | while len(line) > 0: |
|---|
| 165 | if "DOCTYPE" in line: |
|---|
| 166 | break |
|---|
| 167 | xml += line |
|---|
| 168 | line = file.readline() |
|---|
| 169 | xml += file.read() |
|---|
| 170 | |
|---|
| 171 | return xml |
|---|
| 172 | |
|---|
| 173 | |
|---|
| 174 | def getSimpleProperty(s): |
|---|
| 175 | if not hasattr(s,"name"): |
|---|
| 176 | return None |
|---|
| 177 | tmpName = s.name |
|---|
| 178 | if not hasattr(s,"id"): |
|---|
| 179 | return None |
|---|
| 180 | tmpId = s.id |
|---|
| 181 | if not hasattr(s,"type"): |
|---|
| 182 | return None |
|---|
| 183 | tmpType = s.type |
|---|
| 184 | if not hasattr(s,"mode"): |
|---|
| 185 | return None |
|---|
| 186 | tmpMode = s.mode |
|---|
| 187 | if hasattr(s,"description"): |
|---|
| 188 | tmpDes = str(s.description) |
|---|
| 189 | else: |
|---|
| 190 | tmpDes = '' |
|---|
| 191 | |
|---|
| 192 | if tmpMode not in availableModes: |
|---|
| 193 | return None |
|---|
| 194 | if tmpType not in availableTypes: |
|---|
| 195 | return None |
|---|
| 196 | |
|---|
| 197 | newProp = CC.SimpleProperty(tmpName,tmpMode,tmpType,description=tmpDes) |
|---|
| 198 | |
|---|
| 199 | if hasattr(s,"value"): |
|---|
| 200 | newProp.value = newProp.defaultValue = str(s.value) |
|---|
| 201 | |
|---|
| 202 | if hasattr(s,"units"): |
|---|
| 203 | newProp.units = str(s.units) |
|---|
| 204 | |
|---|
| 205 | if hasattr(s,"range"): |
|---|
| 206 | newProp.range = (str(s.range.min),str(s.range.max)) |
|---|
| 207 | |
|---|
| 208 | if hasattr(s,"enum"): |
|---|
| 209 | newProp.enum = str(s.enum.label) |
|---|
| 210 | |
|---|
| 211 | if not hasattr(s, "kind"): |
|---|
| 212 | return None |
|---|
| 213 | newProp.kind = str(s.kind.kindtype) |
|---|
| 214 | |
|---|
| 215 | if hasattr(s,"action"): |
|---|
| 216 | newProp.action = str(s.action.type) |
|---|
| 217 | |
|---|
| 218 | return newProp |
|---|
| 219 | |
|---|
| 220 | def getSimpleSequenceProperty(s): |
|---|
| 221 | if not hasattr(s,"name"): |
|---|
| 222 | return None |
|---|
| 223 | tmpName = s.name |
|---|
| 224 | if not hasattr(s,"id"): |
|---|
| 225 | return None |
|---|
| 226 | tmpId = s.id |
|---|
| 227 | if not hasattr(s,"type"): |
|---|
| 228 | return None |
|---|
| 229 | tmpType = s.type |
|---|
| 230 | if not hasattr(s,"mode"): |
|---|
| 231 | return None |
|---|
| 232 | tmpMode = s.mode |
|---|
| 233 | if hasattr(s,"description"): |
|---|
| 234 | tmpDes = str(s.description) |
|---|
| 235 | else: |
|---|
| 236 | tmpDes = '' |
|---|
| 237 | |
|---|
| 238 | if tmpMode not in availableModes: |
|---|
| 239 | return None |
|---|
| 240 | if tmpType not in availableTypes: |
|---|
| 241 | return None |
|---|
| 242 | |
|---|
| 243 | newProp = CC.SimpleSequenceProperty(tmpName,tmpMode,tmpType,description=tmpDes) |
|---|
| 244 | |
|---|
| 245 | if hasattr(s,"id"): #UUID in the sad file will need to match the UUID in the prf (tmpID is from prf) |
|---|
| 246 | newProp.id = tmpId |
|---|
| 247 | |
|---|
| 248 | newProp.values = [] |
|---|
| 249 | newProp.defaultValues = [] |
|---|
| 250 | |
|---|
| 251 | if hasattr(s,"values"): |
|---|
| 252 | for tmpVal in s.values.value: |
|---|
| 253 | newProp.values.append(str(tmpVal)) |
|---|
| 254 | newProp.defaultValues.append(str(tmpVal)) |
|---|
| 255 | |
|---|
| 256 | if hasattr(s,"units"): |
|---|
| 257 | newProp.units = str(s.units) |
|---|
| 258 | |
|---|
| 259 | if hasattr(s,"range"): |
|---|
| 260 | newProp.range = (str(s.range.min),str(s.range.max)) |
|---|
| 261 | |
|---|
| 262 | if hasattr(s,"enum"): |
|---|
| 263 | newProp.enum = str(s.enum.label) |
|---|
| 264 | |
|---|
| 265 | if not hasattr(s, "kind"): |
|---|
| 266 | return None |
|---|
| 267 | newProp.kind = str(s.kind.kindtype) |
|---|
| 268 | |
|---|
| 269 | if hasattr(s,"action"): |
|---|
| 270 | newProp.action = str(s.action.type) |
|---|
| 271 | |
|---|
| 272 | return newProp |
|---|