// // see http://www.sparxsystems.com/enterprise_architect_user_guide/12.0/automation_and_scripting/reference.html // // $Id$ // $HeadURL$ // $Author$ // // -> tabs to spaces // sed -i "s/\t/ /g" ea_export_script.txt // -> remove trailing spaces // sed -i "s/[ ]*$//g" ea_export_script.txt // !INC Local Scripts.EAConstants-JScript !INC EAScriptLib.JScript-Database !INC EAScriptLib.JScript-XML !INC EAScriptLib.JScript-TaggedValue function warnOut( msg ) { Session.Output( "WARN: " + msg ); } function infoOut( msg ) { Session.Output( "INFO: " + msg ); } function TVGetElementTaggedValueEx( theElement /* : EA.Element */, taggedValueName /* : String */, defaultValue /* : String */ ) /* : variant */ { var result = defaultValue; if ( theElement != null && taggedValueName.length > 0 ) { for ( var j = 0; j < theElement.TaggedValuesEx.Count; j++ ) { var taggedValue as EA.TaggedValue; taggedValue = theElement.TaggedValuesEx.GetAt(j); if (taggedValue.Name == taggedValueName) { result = taggedValue.Value; break; } } } return result; } function getFrameworkPackage( element_ ) { if ( element_ == null ) return null; var element as EA.Element; element = element_; if ( element.Stereotype == "framework" ) return element; var elementId = element.PackageID; if ( element.ObjectType == otPackage ) { var package as EA.Package; package = element; var packageElement as EA.Element; packageElement = package.Element; if ( packageElement == null ) return null; if ( packageElement.Stereotype == "framework" ) return package; elementId = element.ParentID; } //Session.Output( "Name: " + element.Name + " PackageID: " + elementId ); element = Repository.GetPackageByID( elementId ); return getFrameworkPackage( element ) } function getFrameworkElement( element_ ) { var element as EA.Element; element = element_; if ( element.Stereotype == "framework" ) return element; var package as EA.Package; package = getFrameworkPackage( element_ ); if ( package == null ) return null; return package.Element; } function getConnectorFromElement( _element, connectorType ) { var element as EA.Element; element = _element; if ( element == null ) return null; for( var j = 0; j < element.Connectors.Count; j++ ) { var connector as EA.Connector; connector = element.Connectors.GetAt( j ); if( connector == null ) continue; if( connector.ClientID != element.ElementID ) continue; if( connector.Type != connectorType ) continue; return connector; } return null; } function getMethodFromElement( _element, methodString ) { var element as EA.Element; element = _element; if( element == null || methodString == null ) return null; var methods as EA.Collection; methods = element.MethodsEx; return getCollectionAttribute(methods, methodString); } function getCollectionAttribute(_collections, methodName) { var collections as EA.Collection; //Session.Output( "Find methodName:" + methodName ); collections = _collections; // method.GetByName() does not work on non-existing attributes for( var i = 0; i < collections.Count; ++i ) { var method as EA.Method; method = collections.GetAt( i ); //Session.Output( "MethodName: " + method.Name ); if( method && method.Name == methodName ) return method; } return null; } function getKeyColumnFromMethod( element, methodString ) { var method as EA.Method; method = getMethodFromElement( element, methodString ); if( method == null ) { Session.Output( "Can not find PK/FK '" + methodString + "' in Table " + element.Name ); return null; } if( method.Parameters.Count != 1 ) return null; return method.Parameters.GetAt(0).Name; } function getTaggedValueGroup( element, groupName ) { var groupsTaggedValue = TVGetElementTaggedValue( element, groupName ); if ( groupsTaggedValue != null ) { tmp1 = DBGetFieldValueString( "Notes", "t_propertytypes", "Property = \'" + groupName + "\' " ); var startIndex = tmp1.lastIndexOf( "=" ) + 1; var endIndex = tmp1.length - 1; var groupNames = tmp1.substring(startIndex, endIndex).split( "," ); var groupVals = groupsTaggedValue.split( "," ); var validGroups = ""; for ( var i = 0; i < groupVals.length; i++ ) { if ( groupVals[i] == 1 ) { if ( validGroups.length > 0 ) { validGroups += ","; } validGroups += groupNames[i]; } } if ( validGroups.length > 0 ) { return validGroups; } } return null; } function exportTaggedValueGroup( xml, xmlAttribName, element, groupName ) { var validGroups = getTaggedValueGroup( element, groupName ); if ( validGroups != null ) { //Session.Output('valid groups: ' + validGroups ); xml.setAttribute( xmlAttribName, validGroups ); } } function exportFunctionDeclaration( xmlDoc, xmlParent, _method ) { var method as EA.Method; method = _method; var methodXml = xmlDoc.createNode( 1, method.Stereotype, '' ); xmlParent.appendChild( methodXml ); methodXml.setAttribute( 'name', method.Name ); methodXml.setAttribute( 'returns', method.ReturnType ); if (method.IsConst) methodXml.setAttribute( 'isConst', 1 ); for( var k = 0; k < method.Parameters.Count; k++ ) { var param as EA.Parameter; param = method.Parameters.GetAt( k ); var paramXml = xmlDoc.createNode( 1, 'parameter', '' ); paramXml.setAttribute( 'pos', k + 1 ); paramXml.setAttribute( 'name', param.Name ); paramXml.setAttribute( 'type', param.Type ); if (param.Default != "") paramXml.setAttribute( 'default', param.Default ); methodXml.appendChild( paramXml ); } return methodXml; } function exportDbStructBase( xmlDoc, dbStructsXml, dbStructXml, connector, exportedTopicTypes ) { // only inheritance if( connector.Type != "Generalization" ) return; var base as EA.Element; base = GetElementByID( connector.SupplierID ); if( base == null ) { Session.Output( "got unknown element id " + connector.SupplierID ); return; } // now generate the base='foo' - part for inheritance dbStructXml.setAttribute( 'base', base.Name ); // check if the base struct is already exported for( var i = 0; i < exportedTopicTypes.length; ++i ) { if( exportedTopicTypes[i] == connector.SupplierID ) return; } exportedTopicTypes.push( connector.SupplierID ); // not yet exported -> export var dbStructXml = xmlDoc.createNode( 1, 'table', '' ); dbStructsXml.appendChild( dbStructXml ); dbStructXml.setAttribute( 'name', base.Name ); var baseConnectors as EA.Collection; baseConnectors = base.Connectors; for( var j = 0; j < baseConnectors.Count; j++ ) { var connector as EA.Connector; baseConnector = baseConnectors.GetAt( j ); if( baseConnector == null ) continue; if( baseConnector.ClientID != base.ElementID ) continue; // check if base of base is already exported exportDbStructBase( xmlDoc, dbStructsXml, dbStructXml, baseConnector, exportedTopicTypes ); } } function exportDDSBase( xmlDoc, topicTypesXml, topicTypeXml, connector, exportedTopicTypes ) { // only inheritance if( connector == null || connector.Type != "Generalization" ) return; var supplier as EA.Element; supplier = GetElementByID( connector.SupplierID ); if( supplier == null ) { Session.Output( "got unknown element id " + connector.SupplierID ); return; } var supplierPackage as EA.Package; var clientPackage as EA.Package; supplierPackage = getFrameworkElement( supplier ); clientPackage = getFrameworkElement( GetElementByID( connector.ClientID ) ); // now generate the base='foo' - part for inheritance if ( supplierPackage.Name != clientPackage.Name ) { topicTypeXml.setAttribute( 'baseValueType', supplierPackage.Name + "::" + supplier.Name ); } else { topicTypeXml.setAttribute( 'baseValueType', supplier.Name ); } if ( supplier.Attributes.Count == 0 ) { // special case - an empty idl struct - modelled for consistency, // but rtiddsgen does not like it and it's also useless in codebase var grandparentConnector = getConnectorFromElement( supplier, "Generalization" ) exportDDSBase( xmlDoc, topicTypesXml, topicTypeXml, grandparentConnector, exportedTopicTypes ) } exportedTopicTypes.push( connector.SupplierID ); } function getDBServiceStructs( _package, xmlDoc, xmlRootNode ) { var dbServiceStructsXml = xmlDoc.createNode( 1, 'dbServiceStructs', '' ); xmlRootNode.appendChild( dbServiceStructsXml ); var package as EA.Package; package = _package; var elements as EA.Collection; elements = package.Elements; var dbstructs = [] if( elements.Count == 0 ) { infoOut("'Database Service Structs' is empty."); } for( var i = 0; i < elements.Count; i++ ) { var element as EA.Element; element = elements.GetAt( i ); if( element.Stereotype == "implementationClass" ) { var dbClassXml = xmlDoc.createNode( 1, 'serviceStruct', '' ); dbServiceStructsXml.appendChild( dbClassXml ); dbClassXml.setAttribute( 'name', element.Name ); var connectors as EA.Collection; connectors = element.Connectors; var correspondingTableFound = false; for( var j = 0; j < connectors.Count; j++ ) { var connector as EA.Connector; connector = connectors.GetAt( j ); if( connector == null ) continue; if( connector.Type != "Dependency" && connector.Type != "InformationFlow" ) continue; var sourceId = (( connector.Type == "Dependency") ? connector.ClientID : connector.SupplierID ); var destId = (( connector.Type == "Dependency") ? connector.SupplierID : connector.ClientID ); if( sourceId != element.ElementID ) continue; var supplier as EA.Element; supplier = GetElementByID( destId ); if( supplier == null ) { Session.Output( "got unknown element id " + destId ); continue; } dbClassXml.setAttribute( 'table', supplier.Name ); correspondingTableFound = true; dbstructs.push( destId ); if( connector.Type == "InformationFlow" ) { dbClassXml.setAttribute( 'static', 1 ); } } if ( !correspondingTableFound ) { warnOut( "Found no corresponding table for Database Service Struct '" + element.Name + "'" ); } var methods as EA.Collection; methods = element.MethodsEx; for( var j = 0; j < methods.Count; j++ ) { var method as EA.Method; method = methods.GetAt( j ); if( method == null ) continue; if( method.Stereotype == 'function' || method.Stereotype == 'notification' ) { var methodXml = exportFunctionDeclaration( xmlDoc, dbClassXml, method ); if( method.Stereotype == 'notification' ) { exportTaggedValueGroup( methodXml, 'notificationTypes', method, 'Legatus::DatabaseNotificationType' ); } } } } } var exportedTopicTypes = []; for( var i = 0; i < dbstructs.length; i++ ) { var element as EA.Element; element = GetElementByID( dbstructs[i] ); if( element == null ) continue; var dbStructXml = xmlDoc.createNode( 1, 'table', '' ); dbServiceStructsXml.appendChild( dbStructXml ); dbStructXml.setAttribute( 'name', element.Name ); exportedTopicTypes.push( element.ElementID ); var connectors as EA.Collection; connectors = element.Connectors; for( var j = 0; j < connectors.Count; j++ ) { var connector as EA.Connector; connector = connectors.GetAt( j ); if( connector == null ) continue; if( connector.ClientID != element.ElementID ) continue; exportDbStructBase( xmlDoc, dbServiceStructsXml, dbStructXml, connector, exportedTopicTypes ); } } } function exportReferentialIntegrity( _methods, srcFk, xmlOut) { var methods as EA.Collection; methods = _methods; var method as EA.Method; method = null; for (m = 0; m < methods.Count(); ++m) { method = methods.GetAt(m); if (method.Name == srcFk) break; method = null; } if (method == null) return; for (var t = 0; t < method.TaggedValues.Count(); ++t) { var methodTag as EA.MethodTag; methodTag = method.TaggedValues.GetAt(t); if (methodTag.Name != 'property') continue; if (methodTag.Value == 'Delete Set Null=1;') xmlOut.setAttribute( 'referential_integrity', 'DeleteSetNull') else if (methodTag.Value == 'Delete Restrict=1;') xmlOut.setAttribute( 'referential_integrity', 'DeleteRestrict') else if (methodTag.Value == 'Delete Cascade=1;') xmlOut.setAttribute( 'referential_integrity', 'DeleteCascade') else if (methodTag.Value == 'Delete No Action=1;') xmlOut.setAttribute( 'referential_integrity', 'DeleteNoAction') else if (methodTag.Value == 'Delete Set Default=1;') xmlOut.setAttribute( 'referential_integrity', 'DeleteSetDefault') break; } } function getDBModel( _package, xmlDoc, xmlRootNode ) { var tablesXml = xmlDoc.createNode( 1, 'tables', '' ); xmlRootNode.appendChild( tablesXml ); var package as EA.Package; package = _package; var elements as EA.Collection; elements = package.Elements; if( elements.Count == 0 ) { infoOut("'Database Model' is empty."); } for( var i = 0; i < elements.Count; i++ ) { var element as EA.Element; element = elements.GetAt( i ); if( element.Stereotype == "table" ) { var tableXml = xmlDoc.createNode( 1, 'table', '' ); tablesXml.appendChild( tableXml ); tableXml.setAttribute( 'name', element.Name ); if( element.Notes != "" ) { tableXml.setAttribute( 'comment', element.Notes ); } exportTaggedValueGroup( tableXml, 'exerciseDependency', element, 'Legatus::ExerciseDependency' ); var attributes as EA.Collection; attributes = element.Attributes; for( var j = 0; j < attributes.Count; j++ ) { var attribute as EA.Attribute; attribute = attributes.GetAt( j ); if( attribute == null ) continue; var columnXml = xmlDoc.createNode( 1, 'column', '' ); tableXml.appendChild( columnXml ); columnXml.setAttribute( 'name', attribute.Name ); columnXml.setAttribute( 'datatype', attribute.Type ); if( attribute.Default != "" ) if (attribute.Default == "Optional" | attribute.Default == "optional") columnXml.setAttribute( 'isOptional', 1 ); else columnXml.setAttribute( 'default', attribute.Default ); if( attribute.IsOrdered ) columnXml.setAttribute( 'isPrimaryKey', 1 ); if( attribute.IsCollection ) columnXml.setAttribute( 'isForeignKey', 1 ); var attrTag as EA.AttributeTag; attrTag = attribute.TaggedValues.GetByName( "AutoNum" ); if( attrTag != null && attrTag.Value == "True" ) { var sequenceXml = xmlDoc.createNode( 1, 'sequence', '' ); columnXml.appendChild( sequenceXml ); attrTag = attribute.TaggedValues.GetByName( "StartNum" ); sequenceXml.setAttribute( 'start', (( attrTag == null ) ? "1" : attrTag.Value ) ); attrTag = attribute.TaggedValues.GetByName( "Increment" ); sequenceXml.setAttribute( 'increment', (( attrTag == null ) ? "1" : attrTag.Value ) ); } if ( attrTag == null && attribute.IsOrdered ) { warnOut( 'Column ' + element.Name + '.' + attribute.Name + ' is a primary key, but has no sequence (AutoNum) value set!') } if( attribute.Notes != "" ) { columnXml.setAttribute( 'comment', attribute.Notes ); } } var methods as EA.Collection; methods = element.MethodsEx; for( var j = 0; j < methods.Count; j++ ) { var method as EA.Method; method = methods.GetAt( j ); if( method == null ) continue; if( method.Stereotype == 'index' || method.Stereotype == 'unique' ) { var methodXml = xmlDoc.createNode( 1, 'constraint', '' ); tableXml.appendChild( methodXml ); methodXml.setAttribute( 'name', method.Name ); methodXml.setAttribute( 'type', method.Stereotype ); for( var k = 0; k < method.Parameters.Count; k++ ) { var param as EA.Parameter; param = method.Parameters.GetAt( k ); var paramXml = xmlDoc.createNode( 1, 'column', '' ); paramXml.setAttribute( 'name', param.Name ); methodXml.appendChild( paramXml ); } } } var connectors as EA.Collection; connectors = element.Connectors; for( var j = 0; j < connectors.Count; j++ ) { var connector as EA.Connector; connector = connectors.GetAt( j ); if( connector == null ) continue; if( connector.ClientID != element.ElementID ) continue; if( connector.Direction != "Source -> Destination" ) continue; if( connector.Type != "Association" ) continue; var supplier as EA.Element; supplier = GetElementByID( connector.SupplierID ); if( supplier == null ) { Session.Output( "got unknown element id " + connector.SupplierID ); continue; } // FKINFO=SRC=FK_pdm_equipment_system_event_filter_pdm_hgr_mine_search_filter_type:DST=PK_pdm_hgr_mine_search_filter_type:; s = connector.StyleEx; srcFk = s.split( "SRC=" )[1].split(":")[0]; dstFk = s.split( "DST=" )[1].split(":")[0]; // Session.Output("srcFk: " + srcFk); // Session.Output("dstFk: " + dstFk); var foreignKeyXml = xmlDoc.createNode( 1, 'foreignKey', '' ); tableXml.appendChild( foreignKeyXml ); foreignKeyXml.setAttribute( 'name', srcFk ) // Default: onDeleteCascade = true exportReferentialIntegrity(methods, srcFk, foreignKeyXml); var sourceInfo = xmlDoc.createNode( 1, 'source', '' ) //Session.Output( "Source: " + sourceInfo ); foreignKeyXml.appendChild( sourceInfo ); sourceInfo.setAttribute( 'table', element.Name ) //Session.Output( "table: " + element.Name ); sourceInfo.setAttribute( 'column', getKeyColumnFromMethod(element, srcFk) ) var destInfo = xmlDoc.createNode( 1, 'destination', '' ) foreignKeyXml.appendChild( destInfo ); exportExternalFk(xmlDoc, destInfo, element, supplier); destInfo.setAttribute( 'table', supplier.Name ) destInfo.setAttribute( 'column', getKeyColumnFromMethod(supplier, dstFk) ) //Session.Output( "Destination: " + destInfo ); //Session.Output( "table: " + supplier.Name ); } } } } function getDBViews( _package, xmlDoc, xmlRootNode ) { var viewsXml = xmlDoc.createNode( 1, 'views', '' ); xmlRootNode.appendChild( viewsXml ); var package as EA.Package; package = _package; var elements as EA.Collection; elements = package.Elements; for( var i = 0; i < elements.Count; i++ ) { var element as EA.Element; element = elements.GetAt( i ); if( element.Stereotype == "view" ) { var viewXml = xmlDoc.createNode( 1, 'view', '' ); viewsXml.appendChild( viewXml ); viewXml.setAttribute( 'name', element.Name ); if( element.Notes != "" ) { viewXml.setAttribute( 'comment', element.Notes ); } exportTaggedValueGroup( viewXml, 'exerciseDependency', element, 'Legatus::ExerciseDependency' ); var attributes as EA.Collection; attributes = element.Attributes; for( var j = 0; j < attributes.Count; j++ ) { var attribute as EA.Attribute; attribute = attributes.GetAt( j ); if( attribute == null ) continue; if( attribute.Stereotype != "filter") continue; viewXml.setAttribute( "filter", attribute.Name ) } var connectors as EA.Collection; connectors = element.Connectors; for( var j = 0; j < connectors.Count; j++ ) { var connector as EA.Connector; connector = connectors.GetAt( j ); if( connector == null ) continue; if( connector.ClientID != element.ElementID ) continue; if( connector.Direction != "Source -> Destination" ) continue; if( connector.Type != "Dependency" ) continue; var supplier as EA.Element; supplier = GetElementByID( connector.SupplierID ); if( supplier == null ) { Session.Output( "got unknown element id " + connector.SupplierID ); continue; } viewXml.setAttribute( "base", supplier.Name ) } } } } function getEnumerations( _package, xmlDoc, xmlRootNode ) { var rootXml = xmlDoc.createNode( 1, 'enumerations', '' ); xmlRootNode.appendChild( rootXml ); var package as EA.Package; package = _package; var elements as EA.Collection; elements = package.Elements; if( elements.Count == 0 ) { warnOut("'Enumerations' is empty. At least one placeholder enum is needed for generating C++ code."); } for( var i = 0; i < elements.Count; i++ ) { var element as EA.Element; element = elements.GetAt( i ); //Session.Output("Enum element: " + element.Name); if( element.Stereotype == "enumeration" ) { var elementXml = xmlDoc.createNode( 1, 'enumeration', '' ); rootXml.appendChild( elementXml ); elementXml.setAttribute( 'name', element.Name ); var attributes as EA.Collection; attributes = element.AttributesEx; for( var j = 0; j < attributes.Count; j++ ) { var attribute as EA.Attribute; attribute = attributes.GetAt( j ); if( attribute == null ) continue; var attr = xmlDoc.createNode( 1, 'attribute', '' ); elementXml.appendChild( attr ); attr.setAttribute( 'key', attribute.Name ); attr.setAttribute( 'value', attribute.Default ); } var tableCount = 0; var connectors as EA.Collection; connectors = element.Connectors; for( var j = 0; j < connectors.Count; j++ ) { var connector as EA.Connector; connector = connectors.GetAt( j ); if( connector == null ) continue; if( connector.ClientID != element.ElementID ) continue; if( connector.Direction != "Source -> Destination" ) continue; if( connector.Type != "Dependency" ) continue; var supplier as EA.Element; supplier = GetElementByID( connector.SupplierID ); if( supplier == null ) { Session.Output( "got unknown element id " + connector.SupplierID ); continue; } if( supplier.Stereotype != "table" ) continue; elementXml.setAttribute( 'table', supplier.Name ); tableCount += 1; } if ( tableCount < 1 ) { Session.Output( "Got no information about associated database table for enumeration " + element.Name + " - not creating database entries for this enum" ); } else if ( tableCount > 1 ) { Session.Output( "Got more than one associated database table for enumeration " + element.Name + "!" ); } } } } function exportDtcCustomFunctions( xmlDoc, xmlParent, _element ) { var element as EA.Element; element = _element; var dtcFunctionsXml = xmlDoc.createNode( 1, 'customDtcFunctions', '' ); xmlParent.appendChild( dtcFunctionsXml ); var dtcFunctionXml = xmlDoc.createNode( 1, 'customDtcFunction', '' ); dtcFunctionsXml.appendChild( dtcFunctionXml ); var methods as EA.Collection; methods = element.MethodsEx; for( var j = 0; j < methods.Count; j++ ) { var method as EA.Method; method = methods.GetAt( j ); if( method == null ) continue; if( method.Stereotype == 'function' ) { // export DTC functions exportFunctionDeclaration( xmlDoc, dtcFunctionXml, method ); } else { warnOut('Found method ' + method.Name + ' with unhandled Sterotype "' + method.Stereotype + '"'); } } } function exportIdlFunctionTopic( xmlDoc, functionTopicsXml, _element ) { var element as EA.Element; element = _element; // we need two connectors: // - Reply ( FunctionTopic -> idlStruct ) // - Request ( idlStruct -> FunctionTopic ) var replyConnector as EA.Connector; var requestConnector as EA.Connector; var replyElement as EA.Element; var requestElement as EA.Element; for( var j = 0; j < element.Connectors.Count; j++ ) { var connector as EA.Connector; connector = element.Connectors.GetAt( j ); if( connector == null ) continue; if( connector.Type != "Dependency" ) continue; // Reply ( FunctionTopic -> idlStruct ) if( connector.ClientID == element.ElementID ) { replyConnector = connector; replyElement = GetElementByID( connector.SupplierID ) } else if( connector.SupplierID == element.ElementID ) { requestConnector = connector; requestElement = GetElementByID( connector.ClientID ) } } if ( requestElement == null ) { Session.Output( "Could not find request TopicType for FunctionTopic " + element.Name ); return; } if ( requestElement == null ) { Session.Output( "Could not find reply TopicType for FunctionTopic " + element.Name ); return; } // Session.Output( "RequestTopicType: " + requestElement.Name + ", ReplyTopicType: " + replyElement.Name ); var functionTopicXml = xmlDoc.createNode( 1, 'functionTopic', '' ); functionTopicsXml.appendChild( functionTopicXml ); functionTopicXml.setAttribute( 'name', element.Name ); functionTopicXml.setAttribute( 'requestTopicType', requestElement.Name ); functionTopicXml.setAttribute( 'replyTopicType', replyElement.Name ); functionTopicXml.setAttribute( 'requestTopicName', element.Name + "Request" ); functionTopicXml.setAttribute( 'replyTopicName', element.Name + "Reply" ); // def value = False var routeInReplay = TVGetElementTaggedValue(element, "Legatus::RouteTopicInReplay"); functionTopicXml.setAttribute( 'routeInReplay', routeInReplay == 'true' ? 1 : 0 ); var replyPackage as EA.Package; var requestPackage as EA.Package; var clientPackage as EA.Package; requestPackage = getFrameworkElement( GetElementByID( requestConnector.ClientID ) ); replyPackage = getFrameworkElement( GetElementByID( replyConnector.SupplierID ) ); currentPackage = getFrameworkElement( element ); if ( requestPackage.Name != currentPackage.Name ) { functionTopicXml.setAttribute( 'requestTopicType', requestPackage.Name + "::" + requestElement.Name ); } if ( replyPackage.Name != currentPackage.Name ) { functionTopicXml.setAttribute( 'replyTopicType', replyPackage.Name + "::" + replyElement.Name ); } } function exportExternalFk( xmlDoc, fkXml, source, target ) { var sourcePackage as EA.Package; sourcePackage = getFrameworkElement( source ); var targetPackage as EA.Package; targetPackage = getFrameworkElement( target ); if (targetPackage.Name != sourcePackage.Name) { fkXml.setAttribute( 'service', targetPackage.Name ); fkXml.setAttribute( 'serviceAbbr', targetPackage.Alias.toLowerCase() ); } //Session.Output("sourcePackage: " + sourcePackage.Alias); //Session.Output("targetPackage: " + targetPackage.Alias); // try to get out the exercise/global dependency state var edTgtTable = getTaggedValueGroup( target, "Legatus::ExerciseDependency" ); var edSrcTable = getTaggedValueGroup( source, "Legatus::ExerciseDependency" ); var edTgtPackage = getTaggedValueGroup( targetPackage, "Legatus::ExerciseDependency" ); var edSrcPackage = getTaggedValueGroup( sourcePackage, "Legatus::ExerciseDependency" ); // the four properties above can be inconsistent - we assume the best ... var tgtFqnName = targetPackage.Name + '.' + target.Name; var srcFqnName = sourcePackage.Name + '.' + source.Name; // table always wins, if availble if (edTgtTable && edTgtTable != '') edTgtPackage = edTgtTable; if (edSrcTable && edSrcTable != '') edSrcPackage = edSrcTable; var isTgtExerciseDependent = (edTgtPackage.indexOf('Exercise') >= 0); var isTgtGlobal = (edTgtPackage.indexOf('Global') >= 0); var isSrcExerciseDependent = (edSrcPackage.indexOf('Exercise') >= 0); var isSrcGlobal = (edSrcPackage.indexOf('Global') >= 0); // since global and exercise can both be active we can get into trouble here... if ( !isTgtExerciseDependent && !isTgtGlobal) { warnOut('Legatus::ExerciseDependency property for ' + tgtFqnName + ' is neither set for Framework nor Table - this is not allowed!'); return; } if ( !isSrcExerciseDependent && !isSrcGlobal) { warnOut('Legatus::ExerciseDependency property for ' + srcFqnName + ' is neither set for Framework nor Table - this is not allowed!'); return; } //Session.Output('Src: ' + srcFqnName + ' Global: ' + isSrcGlobal + ', Exercise: ' + isSrcExerciseDependent); //Session.Output('Tgt: ' + tgtFqnName + ' Global: ' + isTgtGlobal + ', Exercise: ' + isTgtExerciseDependent); // both are exercise dependent - do not export schema (so sqlgenerator generates fk to local table) if (isTgtExerciseDependent && isSrcExerciseDependent) return; // both are global - do not export schema (so sqlgenerator generates fk to local table) // but source must not be exerciseDependent because then we need the fqn // when src is exercise and tgt is global if (isTgtGlobal && isSrcGlobal && !isSrcExerciseDependent) { if (targetPackage.Name != sourcePackage.Name) fkXml.setAttribute( 'schema', targetPackage.Alias.toLowerCase() ); return; } if (isSrcGlobal && isTgtExerciseDependent) { warnOut('Legatus::ExerciseDependency property for ' + srcFqnName + ' is global but destination (' + tgtFqnName + ' is exercise dependent - this is not allowed / impossible'); return; } fkXml.setAttribute( 'schema', targetPackage.Alias.toLowerCase() ); } function getDDSModel( _package, xmlDoc, xmlRootNode ) { var topicTypesXml = xmlDoc.createNode( 1, 'topicTypes', '' ); xmlRootNode.appendChild( topicTypesXml ); var functionTopicsXml = xmlDoc.createNode( 1, 'functionTopics', '' ); xmlRootNode.appendChild( functionTopicsXml ); var package as EA.Package; package = _package; var basePackage as EA.Package; basePackage = getFrameworkElement( package ); var exportedTopicTypes = []; if( package.Elements.Count == 0 && package.Packages.Count == 0 ) { infoOut("'DDS Model' is empty."); } exportedTopicTypes = exportDDSModelPackage(package, basePackage, xmlDoc, xmlRootNode, topicTypesXml, functionTopicsXml, exportedTopicTypes ); } function exportDDSModelPackage( _package, basePackage, xmlDoc, xmlRootNode, topicTypesXml, functionTopicsXml, exportedTopicTypes ) { var package as EA.Package; package = _package; // export all elements in this package var elements as EA.Collection; elements = package.Elements; for( var i = 0; i < elements.Count; i++ ) { var element as EA.Element; element = elements.GetAt( i ); //Session.Output("element.Stereotype = " + element.Stereotype + " Name = " + element.Name ); if ( element.Stereotype == 'implementationClass' && element.Name == 'DTC') { exportDtcCustomFunctions( xmlDoc, xmlRootNode, element ); } else if ( element.Stereotype == 'FunctionTopic' ) { exportIdlFunctionTopic( xmlDoc, functionTopicsXml, element ); } else if ( element.Stereotype == 'idlStruct' || element.Stereotype == 'valueType' ) { // do not export empty structs (see exportDDSBase() ) if ( element.Attributes.Count == 0 ) { infoOut('Not exporting dds struct ' + element.Name + ' - no attributes (not allowed by rtiddsgen)'); continue; } if (element.Stereotype == 'valueType') { warnOut('Stereotype "valueType" is deprecated, please replace with "idlStruct" in struct ' + element.Name); } var topicTypeXml = xmlDoc.createNode( 1, 'topicType', '' ); topicTypesXml.appendChild( topicTypeXml ); topicTypeXml.setAttribute( 'name', element.Name ); var ddsExtensibility = TVGetElementTaggedValue(element, "IDL::Extensibility"); if ( ddsExtensibility ) topicTypeXml.setAttribute( 'extensibility', ddsExtensibility); var ddsIsDataObject = TVGetElementTaggedValueEx(element, "IDL::IsDataObject") == 'true'; if ( ddsIsDataObject ) { topicTypeXml.setAttribute( 'isDataObject', 1 ); // def value = True var autosubscribe = TVGetElementTaggedValueEx(element, "Legatus::AutoSubscribe"); topicTypeXml.setAttribute( 'autosubscribe', autosubscribe == 'false' ? 0 : 1 ); // def value = True var routeToClient = TVGetElementTaggedValueEx(element, "Legatus::RouteTopicToClient"); topicTypeXml.setAttribute( 'routeToClient', routeToClient == 'false' ? 0 : 1 ); // def value = False var routeToServer = TVGetElementTaggedValueEx(element, "Legatus::RouteTopicToServer"); topicTypeXml.setAttribute( 'routeToServer', routeToServer == 'true' ? 1 : 0 ); // def value = False var routeInReplay = TVGetElementTaggedValueEx(element, "Legatus::RouteTopicInReplay"); topicTypeXml.setAttribute( 'routeInReplay', routeInReplay == 'true' ? 1 : 0 ); } var dtsAutogen = TVGetElementTaggedValue(element, "Legatus::AutogenDTS"); if ( dtsAutogen == 'false' || dtsAutogen == 0 ) topicTypeXml.setAttribute( 'autogenDTS', 0 ); var dtcAutogen = TVGetElementTaggedValue(element, "Legatus::AutogenDTC"); if ( dtcAutogen == 'false' || dtcAutogen == 0 ) topicTypeXml.setAttribute( 'autogenDTC', 0 ); // Attributes var attributes as EA.Collection; attributes = element.AttributesEx; // we need to investigate all, but only export our own for( var j = 0; j < attributes.Count; j++ ) { var attribute as EA.Attribute; attribute = attributes.GetAt( j ); if( attribute == null ) continue; if( ddsIsDataObject && attribute.Name == 'sampleTime' && attribute.Notes != 'no_record' ) topicTypeXml.setAttribute( 'recordTopic', 1 ); // only export our own attributes - isDerived does not work as expected if( attribute.ParentID != element.ElementID ) continue; var columnXml = xmlDoc.createNode( 1, 'column', '' ); topicTypeXml.appendChild( columnXml ); columnXml.setAttribute( 'name', attribute.Name ); columnXml.setAttribute( 'idlType', attribute.Type ); //infoOut("attribute.Name: " + element.Name + ":" + attribute.Name); if ( attribute.ClassifierID != 0 ) { var attributeTypePackage as EA.Package; attributeTypePackage = getFrameworkElement( GetElementByID( attribute.ClassifierID ) ); if ( attributeTypePackage != null && attributeTypePackage.Name != basePackage.Name ) { columnXml.setAttribute( 'idlType', attributeTypePackage.Name + "::" + attribute.Type ); } } //Session.Output("StereoType:" + attribute.Stereotype); if( attribute.Stereotype == "key" ) columnXml.setAttribute( 'isKey', 1 ); if( attribute.Stereotype == "Optional" | attribute.Stereotype == "optional" ) columnXml.setAttribute( 'isOptional', 1 ); if ( attribute.Stereotype == "translatable" ) columnXml.setAttribute( 'isTranslatable', 1); if( attribute.Notes != "" ) columnXml.setAttribute( 'comment', attribute.Notes ); } var supplierCon = getConnectorFromElement( element, "Generalization" ) exportDDSBase( xmlDoc, topicTypesXml, topicTypeXml, supplierCon, exportedTopicTypes ); } } // now handle subpackages var packages as EA.Collection; packages = package.Packages; for( var i = 0; i < packages.Count; ++i ) { exportedTopicTypes = exportDDSModelPackage(packages.GetAt(i), basePackage, xmlDoc, xmlRootNode, topicTypesXml, functionTopicsXml, exportedTopicTypes ); } return exportedTopicTypes } function ExportServiceInformation( _package, xmlDoc, xmlRootNode ) { var servicePackage as EA.Package; var serviceCollection as EA.Collection; var hasDbServiceStructs = false; var hasDataBaseModel = false; var hasEnumerations = false; var hasDdsModel = false; servicePackage = _package; serviceCollection = servicePackage.Packages; for( var i = 0; i < serviceCollection.Count; i++ ) { var obj = serviceCollection.GetAt( i ); if( obj.ObjectType == otPackage ) { var package as EA.Package package = obj if( package.Name == "Database Service Structs") { infoOut('Handling Database Service Structs ...'); getDBServiceStructs( package, xmlDoc, xmlRootNode ) hasDbServiceStructs = true; infoOut('... ready'); } else if( package.Name == "Database Model") { infoOut('Handling Database Model ...'); getDBModel( package, xmlDoc, xmlRootNode ) getDBViews( package, xmlDoc, xmlRootNode ) hasDataBaseModel = true; infoOut('... ready'); } else if( package.Name == "Enumerations") { infoOut('Handling Enumerations ...'); getEnumerations( package, xmlDoc, xmlRootNode ) hasEnumerations = true; infoOut('... ready'); } else if( package.Name == "DDS Model") { infoOut('Handling DDS Model ...'); getDDSModel( package, xmlDoc, xmlRootNode) hasDdsModel = true; infoOut('... ready'); } } } if( !hasDbServiceStructs) { warnOut("'Database Service Structs' not found!"); } if( !hasDataBaseModel) { warnOut("'Database Model' not found!"); } if( !hasEnumerations) { warnOut("'Enumerations' not found!"); } if( !hasDdsModel) { warnOut("'DDS Model' not found!"); } } function ExportOperatorRights( _frameworkElement, _package, xmlDoc, xmlRootNode ) { infoOut('Handling Operator Rights ...'); var frameworkElement as EA.Element; frameworkElement = _frameworkElement; var package as EA.Package; // 'Plugin' package = _package; var svcRightsOfs = TVGetElementTaggedValue( frameworkElement, "Legatus::OperatorRightsServiceOffset" ); if( svcRightsOfs == null || svcRightsOfs == "" ) { warnOut( 'Legatus::OperatorRightsServiceOffset is not defined for framework ' + frameworkElement.Name ); return; } var rightsRootNode = xmlDoc.createNode( 1, 'operatorRights', '' ); xmlRootNode.appendChild( rightsRootNode ); rightsRootNode.setAttribute( 'offset', svcRightsOfs); if (!package) return; var pluginPackages as EA.Collection; pluginPackages = package.Packages; for( var i = 0; i < pluginPackages.Count; i++ ) { var pluginPackage as EA.Package; pluginPackage = pluginPackages.GetAt( i ); var plgRightsOfs = TVGetElementTaggedValue( pluginPackage.Element, "Legatus::OperatorRightsGuiPluginOffset" ); if( plgRightsOfs == null || plgRightsOfs == "" ) { warnOut( 'Legatus::OperatorRightsGuiPluginOffset is not defined for Gui Plugin1 ' + pluginPackage.Name ); continue; } var pluginRightsNode = xmlDoc.createNode( 1, 'guiPlugin', '' ); rightsRootNode.appendChild( pluginRightsNode ); pluginRightsNode.setAttribute( 'name', pluginPackage.Name ); pluginRightsNode.setAttribute( 'offset', plgRightsOfs ); //warnOut('name: ' + pluginPackage.Name) var elements = pluginPackage.Elements; for (var j = 0; j < elements.Count; j++) { var element as EA.Element; var element = elements.GetAt( j ); if (element.Stereotype != 'enumeration') continue; var attributes as EA.Collection; attributes = element.Attributes; if (attributes.Count == 0) continue; var group = xmlDoc.createNode( 1, 'operatorRightGroup', '' ); pluginRightsNode.appendChild( group ); group.setAttribute( 'name', element.Name ) if( element.Notes != "" ) group.setAttribute( 'description', element.Notes ) for (var k = 0; k < attributes.Count; k++) { var attribute as EA.Attribute; attribute = attributes.GetAt( k ); var attributeNode = xmlDoc.createNode( 1, 'operatorRight', '' ); group.appendChild( attributeNode ); attributeNode.setAttribute( 'right', attribute.Name ); attributeNode.setAttribute( 'value', attribute.Default ); if( attribute.Notes != "" ) attributeNode.setAttribute( 'description', attribute.Notes ); } } } } function DoSomething() { // Show the script output window Repository.EnsureOutputVisible( "Script" ); // Get the set of selected items as a collection var selPkg = Repository.GetTreeSelectedPackage(); var frameworkPackage as EA.Package; frameworkPackage = getFrameworkPackage( selPkg ); if( frameworkPackage != null ) { Session.Output( "Export Service information data for " + frameworkPackage.Name ); Session.Output( "===============================" ); var xmlDoc = new ActiveXObject( 'Msxml2.DOMDocument' ); var xmlRootNode = xmlDoc.createNode( 1, 'service', '' ); xmlDoc.appendChild( xmlRootNode ); var xmlSvnNode = xmlDoc.createNode( 1, 'rcs', '' ); xmlRootNode.appendChild( xmlSvnNode ); var xmlSvnNodeId = xmlDoc.createNode( 1, 'Id', '' ); xmlSvnNode.appendChild( xmlSvnNodeId ); xmlSvnNodeId.setAttribute( 'Id', '$Id$' ) var xmlSvnNodeUrl = xmlDoc.createNode( 1, 'HeadURL', '' ); xmlSvnNode.appendChild( xmlSvnNodeUrl ); xmlSvnNodeUrl.setAttribute( 'HeadURL', '$HeadURL$' ) var xmlSvnNodeAuthor = xmlDoc.createNode( 1, 'Author', '' ); xmlSvnNode.appendChild( xmlSvnNodeAuthor ); xmlSvnNodeAuthor.setAttribute( 'Author', '$Author$' ) var frameworkElement as EA.Element; frameworkElement = frameworkPackage.Element; var frameworkCollection as EA.Collection; frameworkCollection = frameworkPackage.Packages; // now search 'Service' Package inside frameworkCollection var opRightsExported = false; for( var i = 0; i < frameworkCollection.Count; i++ ) { var obj = frameworkCollection.GetAt( i ); if( obj.ObjectType == otPackage ) { var package as EA.Package; package = obj; if( package.Name == "Service" || package.Name == "Proxy" ) { ExportServiceInformation( package, xmlDoc, xmlRootNode ); } if( package.Name == "OperatorRights" ) { ExportOperatorRights( frameworkElement, package, xmlDoc, xmlRootNode ); opRightsExported = true; } } } if (!opRightsExported) { ExportOperatorRights( frameworkElement, null, xmlDoc, xmlRootNode ); } xmlRootNode.setAttribute( 'namespace', frameworkPackage.Name ); xmlRootNode.setAttribute( 'abbreviation', frameworkPackage.Alias.toUpperCase() ); var procNames = TVGetElementTaggedValue( frameworkElement, "Legatus::ProcNames" ); if( procNames == null || procNames == "" ) procNames = frameworkPackage.Name; xmlRootNode.setAttribute( 'procNames', procNames ); var customRecordReplay = TVGetElementTaggedValue( frameworkElement, "Legatus::CustomRecordReplayPlugin" ); if( customRecordReplay == 'true' ) xmlRootNode.setAttribute( 'customRecordReplay', 1 ); exportTaggedValueGroup( xmlRootNode, 'exerciseDependency', frameworkElement, 'Legatus::ExerciseDependency' ); exportTaggedValueGroup( xmlRootNode, 'groups', frameworkElement, 'Legatus::Groups' ); var writer = new ActiveXObject( "MSXML2.MXXMLWriter" ); writer.indent = true; writer.encoding = "UTF-8"; // for files only writer.omitXMLDeclaration = false; writer.standalone = true; var reader = new ActiveXObject( "MSXML2.SAXXMLReader" ); reader.contentHandler = writer; reader.parse(xmlDoc); var fso = new ActiveXObject("Scripting.FileSystemObject"); var outputFile = "C:\\TDS\\" + frameworkElement.Alias.toLowerCase() + "_service.xml"; Session.Output("OutputFile: " + outputFile ); var textStream = fso.CreateTextFile(outputFile, true); // Writer always uses utf-16 as output ecoding - whyever // also replace tab with 2 spaces textStream.Write(writer.output.replace("encoding=\"UTF-16\"", "encoding=\"UTF-8\"").replace(/\t/g, " ")); textStream.Write("\n"); textStream.Close(); //Session.Prompt( "Wrote framework '" + frameworkPackage.Name + "' to " + outputFile , promptOk ); } else { Session.Prompt( "This script requires the current context item to be a framework package.\n" + "Please select a framework package and try again.", promptOK ); } } DoSomething(); function getPackageByName( element_, requestedName ) { var element as EA.Element; element = element_; if ( element.Name == requestedName ) return element; var elementId = element.PackageID; if ( element.ObjectType == otPackage ) { var package as EA.Package; package = element; var packageElement as EA.Element; packageElement = package.Element; if ( packageElement == null ) return null; if ( packageElement.Name == requestedName ) return package; elementId = element.ParentID; } element = Repository.GetPackageByID( elementId ); return getPackageByName( element, requestedName ) } function isFrameworkPackage( element ) { if( element.ObjectType != otPackage ) return false; var package as EA.Package; package = element; return ( package.StereotypeEx == 'framework' ) } function getOperatorRightsEnum( element ) { var package as EA.Package; package = element; var elements = package.Elements; for (var i = 0; i < elements.Count; i++ ) { var element as EA.Element; var element = elements.GetAt( i ); if ( element.Stereotype == 'enumeration' && element.Name == 'OperatorRights' ) return element; } return null; } function ExportOperatorRightsTest() { // Show the script output window Repository.EnsureOutputVisible( "Script" ); Session.Output( "Export Operator Rights" ); Session.Output( "======================" ); // Get the set of selected items as a collection var selPkg = Repository.GetTreeSelectedPackage(); var scPackage as EA.Package; if( selPkg != null ) { scPackage = getPackageByName( selPkg, 'Software Components' ); } if ( scPackage == null ) { Session.Prompt( "This script requires the current context item to be inside the 'Software Components' package\n" + "Please select this package and try again.", promptOK ); return; } // now walk every leaf and search for an element named 'OperatorRights' // with the stereotype 'enumeration' // the path should be <> / Plugin / / <> OperatorRights var frameworkPackages as EA.Collection; frameworkPackages = scPackage.Packages; for( var i = 0; i < frameworkPackages.Count; i++ ) { var obj = frameworkPackages.GetAt( i ); if ( !isFrameworkPackage( obj ) ) continue; var package as EA.Package; package = obj; var subPackages = package.Packages; for( var j = 0; j < subPackages.Count; j++ ) { var subObj = subPackages.GetAt( j ); if ( subObj.Name != 'Plugin' ) continue; var subPackage as EA.Package; subPackage = subObj; var pluginPackages = subPackage.Packages; for ( var k = 0; k < pluginPackages.Count; k++ ) { var element as EA.Element; element = getOperatorRightsEnum( pluginPackages.GetAt( k ) ); if ( element == null ) continue; var attributes as EA.Collection; attributes = element.Attributes; for( var j = 0; j < attributes.Count; j++ ) { var attribute as EA.Attribute; attribute = attributes.GetAt( j ); Session.Output('found attribute: ' + attribute.Name + ' - ' + attribute.Default ); } } } } } //ExportOperatorRightsTest();