Examples: invoking EDMmapMethod
EDMmapMethods are executable EDMmethods written in EDMexpressX and wrapped in an EDMmapSchema that may be compiled by the EDMexpressXcompiler. EDMmapMethods are executed by the EDMvirtualMachine.
EDMmapMethods are implemented as SCHEMA_MAP in EDMmapSchemas. Unlike EDMruleMethods and EDMqueryMethods, only one EDMmapMethod may be implemented in each EDMmapSchema. The EDMmapSchema below shows how the EDMmapMethod "CheckPropertySet" is implemented in an EDMmapSchema.
CheckPropertySet
SCHEMA_MAP CheckPropertySet; -- --------------------------------------------------------------- -- Method: CheckPropertySet -- --------------------------------------------------------------- GLOBAL DECLARE src INSTANCE OF SOURCE_SCHEMA IFC2X3; DECLARE trg INSTANCE OF TARGET_SCHEMA IFC2X3; retVal : INTEGER := 0; -- Global for holding return value. END_GLOBAL; STATEMENTS IdentifyMethod; -- Report to the methods stdout. xpxPrintf('Method: CheckPropertySet Started.\n'); END_STATEMENTS; STATEMENTS ExecuteMethod; LOCAL found : BOOLEAN := FALSE; str : STRING := ''; resultFileId : INTEGER := 0; entityId : GENERIC; ifcObjId : GENERIC; isSubtype : BOOLEAN; nPar : INTEGER := 0; parType : GENERIC; par : GENERIC; entityName : STRING := ''; -- Parameter #1 pSetName : STRING := ''; -- Parameter #2 fileMapping : BOOLEAN := FALSE; -- Parameter #3 END_LOCAL; -- ------------------------------------------------ -- Uncomment this line to have the method terminate -- with a value -999 returned as UserDefinedStatus. -- ------------------------------------------------- -- xpxTerminate(-999); -- ------------------------------------------------ -- EXCEPTION HANDLER -- ------------------------------------------------ ON_ERROR_DO str := xpfStringPrintf('\nERROR -> %s threw exception at line %d:', xpxExceptionId.functionName, xpxExceptionId.lineNumber); str += xpfStringPrintf('\n EDMI Error: %d - %s', xpxExceptionId.errCode, xpxExceptionId.errMessage); str += xpfStringPrintf('\n User Error: %d - %s', xpxExceptionId.userCode, xpxExceptionId.userMessage); -- Write a detailed exception report to the methods -- stdout. May be picked up on the client side as -- the user output file. xpxPrintf(str); -- Close the mapped result file if open IF (resultFileId > 0) THEN xpxCloseFile(resultFileId); END_IF; -- Send the error code to the calling client to inform -- that an exception was thrown within the method. -- The string goes to the exception log file. xpxTerminate(xpxExceptionId.errCode, str); END_ON_ERROR_DO; -- Check number of parameters (Accepts either three or none) npar := xpxGetNumberOfUserParameters(); IF (NOT(nPar = 0)) THEN -- Check number of parameters IF (NOT(nPar = 3)) THEN xpxExceptionId.errCode := xpxE_ACTUAL_FORMAL_ARGS; str := 'Wrong number of parameters. Expected 3, '; str += xpfStringPrintf('Actual %d', nPar); xpxExceptionId.userMessage := str; xpxThrow; END_IF; -- Check Parameter #1 xpxGetUserParameter(1,par); xpxGetDataType(par,parType); IF (parType <> xpxSTRING) THEN xpxExceptionId.errCode := xpxE_ARG2_DATATYPE; str := 'Wrong type of Par #1, entityName. Expected STRING'; xpxExceptionId.userMessage := str; xpxThrow; ELSE entityName := par; END_IF; -- Check Parameter #2 xpxGetUserParameter(2,par); xpxGetDataType(par,parType); IF (parType <> xpxSTRING) THEN xpxExceptionId.errCode := xpxE_ACTUAL_FORMAL_ARGS; str := 'Wrong type of Par #2, propertySet. Expected STRING'; xpxExceptionId.userMessage := str; xpxThrow; ELSE pSetName := par; END_IF; -- Check Parameter #3 xpxGetUserParameter(3,par); xpxGetDataType(par,parType); IF (parType <> xpxBOOLEAN) THEN xpxExceptionId.errCode := xpxE_ACTUAL_FORMAL_ARGS; str := 'Wrong type of Par #3, propertySet. Expected BOOLEAN'; xpxExceptionId.userMessage := str; xpxThrow; ELSE fileMapping := par; IF (fileMapping = TRUE) THEN resultFileId := xpfOpenFile('result', 'wt'); END_IF; END_IF; -- Check if the Entity is a subtype of ifcObject in IFC2x3 entityId := xpfGetEntityInSchema(xpxSOURCESCHEMAID, entityName); ifcObjId := xpfGetEntityInSchema(xpxSOURCESCHEMAID, 'ifcObject'); xpxIsSubtypeOf(entityId , ifcObjId, isSubtype); IF (NOT(isSubtype)) THEN xpxExceptionId.errCode := xpxE_ARG1_DATATYPE; str := xpfStringPrintf('The entity %s', entityName); str += 'is not a subtype of ifcObject'; xpxExceptionId.userMessage := str; xpxThrow; END_IF; -- Loop over all instances of entityName. FROM (SUBTYPE obj:src::ifcObject) WHEN(entityId :=: xpfGetInstanceType(obj)); BEGIN -- Loop over all ifcreldefines objects pointing at this ifcObject found := FALSE; REPEAT i := 1 TO SIZEOF(obj.IsDefinedBy); IF (obj.IsDefinedBy[i].relatingpropertydefinition.Name = pSetName) THEN found := TRUE; ESCAPE; END_IF; END_REPEAT; IF (NOT(found)) THEN retVal += 1; IF (resultFileId > 0) THEN str := xpfStringPrintf('\n%s,%s,%d', obj.GlobalId, entityName, obj); xpxWriteFile(resultFileId, str, 100); END_IF; END_IF; END; -- Close the resultFile if open. IF (resultFileId > 0) THEN xpxCloseFile(resultFileId); END_IF; ELSE -- No input parameters: Count property sets. FROM (SUBTYPE obj:src::ifcObject) WHEN(TRUE); BEGIN retVal += SIZEOF(obj.IsDefinedBy); END; END_IF; END_STATEMENTS; STATEMENTS TerminateAndReturnStatusToCaller; -- Report to the methods stdout. xpxPrintf(' * Returning with value %d\n', -retVal); xpxPrintf('Method: CheckPropertySet: Completed\n'); xpxTerminate(-retVal); END_STATEMENTS; END_SCHEMA_MAP;