From 9d9a1e8e8d927186a139850a911bfe6378dacdc9 Mon Sep 17 00:00:00 2001 From: "Achim D. Brucker" Date: Mon, 26 Dec 2016 14:51:39 +0000 Subject: [PATCH] Initial import. --- .gitignore | 4 + build.xml | 226 ++ local.properties.in | 1 + .../DialectMetamodelSelectedListener.java | 14 + .../infsec/secureumlgui/ModuleController.java | 386 ++++ .../secureumlgui/ResourceFilesManager.java | 125 ++ .../infsec/secureumlgui/SecureUmlModule.java | 319 +++ .../infsec/secureumlgui/TabSecureUml.java | 308 +++ src/ch/ethz/infsec/secureumlgui/Util.java | 426 ++++ .../secureumlgui/WriteXmiActionListener.java | 60 + .../gui/AbstractPermissionsTableModel.java | 257 +++ .../gui/AbstractSecureUmlComponent.java | 83 + .../gui/ActionNameTableCellRenderer.java | 151 ++ .../ActionNameTableCellRendererComponent.java | 126 ++ .../gui/ActionPermissionTableCellEditor.java | 26 + .../ActionPermissionTableCellListener.java | 83 + .../ActionPermissionTableCellRenderer.java | 174 ++ ...nPermissionTableCellSelectionListener.java | 37 + ...PermissionsTableCellRendererComponent.java | 335 +++ .../GenericResourcePermissionsTableModel.java | 227 ++ .../secureumlgui/gui/JTristateCheckBox.java | 227 ++ .../secureumlgui/gui/MultiLineToolTip.java | 63 + .../secureumlgui/gui/MultiLineToolTipUI.java | 101 + .../gui/PermissionAttributesTableModel.java | 218 ++ .../gui/PermissionIconTableCellRenderer.java | 37 + ...missionIconTableCellRendererComponent.java | 89 + .../secureumlgui/gui/PolicyLevelCreator.java | 9 + .../gui/RolePermissionsTableModel.java | 452 ++++ .../secureumlgui/gui/SecureUmlComponent.java | 422 ++++ .../gui/SecureUmlExcpPermissionComponent.java | 65 + .../gui/SecureUmlPermissionComponent.java | 366 ++++ .../gui/SecureUmlRoleComponent.java | 161 ++ .../infsec/secureumlgui/gui/TableSorter.java | 486 +++++ .../ethz/infsec/secureumlgui/gui/package.html | 10 + .../secureumlgui/icons/combined_icon.png | Bin 0 -> 570 bytes .../icons/composite_full_icon.png | Bin 0 -> 230 bytes .../secureumlgui/icons/constrained_icon.png | Bin 0 -> 222 bytes .../secureumlgui/icons/createRoleIcon.png | Bin 0 -> 686 bytes .../icons/implicit_by_composite.png | Bin 0 -> 204 bytes .../secureumlgui/icons/implicit_icon.png | Bin 0 -> 235 bytes .../secureumlgui/icons/inherited_icon.png | Bin 0 -> 686 bytes .../icons/inherited_policy_icon.png | Bin 0 -> 570 bytes .../secureumlgui/logging/LoggerContext.java | 59 + .../logging/MultiContextLogger.java | 301 +++ .../secureumlgui/logging/SimpleLogger.java | 309 +++ .../logging/SimpleMessageSink.java | 7 + .../main/ClassLoaderProviderImpl.java | 44 + .../infsec/secureumlgui/main/FileLoader.java | 84 + .../secureumlgui/main/SecureUmlConstants.java | 193 ++ .../modelmanagement/ExtentInfo.java | 36 + .../modelmanagement/ModelConst.java | 68 + .../modelmanagement/OclModelInfo.java | 50 + .../modelmapping/GenericDialectHelper.java | 1829 +++++++++++++++++ .../GenericDialectModelMapper.java | 1398 +++++++++++++ .../modelmapping/ModelMapper.java | 70 + .../modelmapping/ModelWriter.java | 860 ++++++++ .../modelmapping/PathNameResolver.java | 129 ++ .../modelmapping/SecureUmlModelMapper.java | 606 ++++++ .../modelmapping/counters/Counter.java | 13 + .../counters/SecureUmlMappingCounter.java | 82 + .../secureumlgui/modelmapping/package.html | 9 + .../permissions/ActionPermissionSet.java | 165 ++ .../permissions/CompositePermission.java | 137 ++ .../HierarchicalPermissionsExplorer.java | 481 +++++ .../HierarchicalPolicyExplorer.java | 328 +++ .../permissions/PermissionSet.java | 78 + .../permissions/PermissionValue.java | 564 +++++ .../permissions/PolicyPermissionSet.java | 220 ++ .../permissions/ResourcePermissionsSet.java | 80 + .../modelmapping/permissions/package.html | 8 + .../modelmapping/strategies/MapSelf.java | 32 + .../MapSelfAndAssociatedResources.java | 567 +++++ .../strategies/MappingScopeStrategy.java | 36 + .../SecureUmlMappingScopeStrategy.java | 55 + .../modelmapping/strategies/package.html | 7 + .../securemodel/SecureModelPackage.java | 19 + .../dialects/metamodel/ActionKind.java | 22 + .../metamodel/ActionResourceAssociation.java | 58 + .../dialects/metamodel/ActionType.java | 48 + .../dialects/metamodel/AssociationEnd.java | 127 ++ .../dialects/metamodel/AtomicActionType.java | 12 + .../metamodel/CompositeActionType.java | 13 + .../metamodel/ContainmentAssociation.java | 73 + .../metamodel/DialectMetaModelInfo.java | 426 ++++ .../metamodel/InterResourceAssociation.java | 87 + .../metamodel/MetaModelAssociation.java | 19 + .../dialects/metamodel/MetaModelClass.java | 68 + .../metamodel/MetaModelClassAttribute.java | 91 + .../dialects/metamodel/MetaModelConst.java | 50 + .../dialects/metamodel/MetaModelEntity.java | 40 + .../dialects/metamodel/MetaModelFactory.java | 52 + .../dialects/metamodel/ResourceType.java | 109 + .../dialects/metamodel/TaggedValue.java | 44 + .../dialects/metamodel/package.html | 8 + .../parser/DialectMetaModelAnalyzer.java | 1587 ++++++++++++++ .../parser/DialectMetaModelParser.java | 233 +++ .../dialects/parser/DialectMetaModelUtil.java | 269 +++ .../oclexpressions/BooleanExpression.java | 27 + .../parser/oclexpressions/BooleanLiteral.java | 41 + .../ConjunctiveBooleanExpression.java | 41 + .../parser/oclexpressions/DecimalLiteral.java | 39 + .../DisjunctiveBooleanExpression.java | 41 + .../parser/oclexpressions/Equation.java | 83 + .../oclexpressions/ExpressionEvaluator.java | 16 + .../oclexpressions/ExpressionFactory.java | 71 + .../oclexpressions/ExpressionFragment.java | 12 + .../parser/oclexpressions/IntLiteral.java | 40 + .../parser/oclexpressions/Literal.java | 12 + .../oclexpressions/OclEvaluatorException.java | 19 + .../parser/oclexpressions/OclExpression.java | 60 + .../OclExpressionEvaluator.java | 445 ++++ .../oclexpressions/OclExpressionsParser.java | 686 +++++++ .../oclexpressions/OclParserException.java | 18 + .../OclUmlExpressionEvaluator.java | 527 +++++ .../parser/oclexpressions/OperationStep.java | 12 + .../dialects/parser/oclexpressions/Path.java | 39 + .../parser/oclexpressions/PathFactory.java | 71 + .../parser/oclexpressions/PathFragment.java | 12 + .../parser/oclexpressions/PathStep.java | 20 + .../oclexpressions/PropertyAccessStep.java | 67 + .../parser/oclexpressions/SelectionStep.java | 47 + .../dialects/parser/oclexpressions/Self.java | 19 + .../oclexpressions/SetOperationStep.java | 54 + .../parser/oclexpressions/StringLiteral.java | 40 + .../parser/oclexpressions/package.html | 11 + .../securemodel/dialects/parser/package.html | 7 + .../secureumlgui/securemodel/package.html | 8 + .../securemodel/secureuml/Action.java | 43 + .../securemodel/secureuml/ActionClass.java | 11 + .../secureuml/ActionHierarchy.java | 47 + .../secureuml/ActionResourceAssignment.java | 47 + .../securemodel/secureuml/AtomicAction.java | 11 + .../secureuml/AtomicActionClass.java | 23 + .../secureuml/AuthorizationConstraint.java | 38 + .../AuthorizationConstraintClass.java | 24 + .../secureuml/CompositeAction.java | 16 + .../secureuml/CompositeActionClass.java | 23 + .../secureuml/ConstraintAssignment.java | 48 + .../securemodel/secureuml/Group.java | 11 + .../securemodel/secureuml/GroupClass.java | 23 + .../securemodel/secureuml/Permission.java | 49 + .../secureuml/PermissionActionAssignment.java | 47 + .../secureuml/PermissionAssignment.java | 47 + .../secureuml/PermissionClass.java | 23 + .../securemodel/secureuml/Resource.java | 16 + .../securemodel/secureuml/ResourceClass.java | 11 + .../securemodel/secureuml/Role.java | 51 + .../securemodel/secureuml/RoleClass.java | 23 + .../securemodel/secureuml/RoleHierarchy.java | 47 + .../secureuml/SecureUmlPackage.java | 101 + .../securemodel/secureuml/Subject.java | 27 + .../secureuml/SubjectAssignment.java | 47 + .../securemodel/secureuml/SubjectClass.java | 11 + .../securemodel/secureuml/SubjectGroup.java | 47 + .../securemodel/secureuml/User.java | 11 + .../securemodel/secureuml/UserClass.java | 23 + .../securemodel/secureuml/package.html | 10 + .../securemodelimpl/SecureModelFactory.java | 307 +++ .../securemodelimpl/secureuml/package.html | 8 + .../transformation/MetaModelMap.java | 424 ++++ .../secureumlgui/transformation/ModelMap.java | 471 +++++ .../secureumlgui/transformation/package.html | 8 + .../usecasemapper/control/Controller.java | 90 + .../control/MenuActionListener.java | 28 + .../usecasemapper/control/package.html | 11 + .../secureumlgui/usecasemapper/gui/View.java | 57 + .../usecasemapper/gui/package.html | 10 + .../usecasemapper/mapping/ActorMapper.java | 207 ++ .../mapping/MapperException.java | 22 + .../usecasemapper/mapping/MapperHelper.java | 564 +++++ .../usecasemapper/mapping/MapperStrategy.java | 29 + .../usecasemapper/mapping/Permission.java | 807 ++++++++ .../mapping/PermissionMapper.java | 774 +++++++ .../usecasemapper/mapping/package.html | 15 + .../secureumlgui/usecasemapper/package.html | 11 + .../util/ExcpPermissionDummy.java | 22 + .../util/ExtensionFilenameFilter.java | 39 + .../util/NotImplementedException.java | 14 + .../secureumlgui/util/PermissionDummy.java | 138 ++ .../util/SelectMetamodelActionListener.java | 53 + .../infsec/secureumlgui/util/Various.java | 36 + .../infsec/secureumlgui/util/package.html | 8 + .../secureumlgui/wrapper/ActionWrapper.java | 195 ++ .../wrapper/AtomicActionWrapper.java | 20 + .../wrapper/AttributeWrapper.java | 32 + .../AuthorizationConstraintWrapper.java | 34 + .../wrapper/CompositeActionWrapper.java | 22 + .../wrapper/ExceptionPermissionWrapper.java | 25 + .../wrapper/ModelElementWrapper.java | 72 + .../secureumlgui/wrapper/MofClassWrapper.java | 51 + .../wrapper/MofPackageWrapper.java | 28 + .../wrapper/NamedModelElementWrapper.java | 61 + .../wrapper/PermissionWrapper.java | 241 +++ .../secureumlgui/wrapper/PolicyWrapper.java | 76 + .../wrapper/RefPackageWrapper.java | 102 + .../secureumlgui/wrapper/ResourceWrapper.java | 103 + .../secureumlgui/wrapper/RoleWrapper.java | 99 + .../infsec/secureumlgui/wrapper/package.html | 8 + src/manifest.mf | 12 + src/overview.html | 16 + .../mapping/ActorMapperTest.java | 220 ++ .../mapping/MapperHelperTest.java | 86 + .../mapping/MapperTestHelper.java | 229 +++ .../mapping/PermissionMapperTest.java | 65 + .../usecasemapper/mapping/package.html | 15 + 205 files changed, 27940 insertions(+) create mode 100644 build.xml create mode 100644 local.properties.in create mode 100644 src/ch/ethz/infsec/secureumlgui/DialectMetamodelSelectedListener.java create mode 100644 src/ch/ethz/infsec/secureumlgui/ModuleController.java create mode 100644 src/ch/ethz/infsec/secureumlgui/ResourceFilesManager.java create mode 100644 src/ch/ethz/infsec/secureumlgui/SecureUmlModule.java create mode 100644 src/ch/ethz/infsec/secureumlgui/TabSecureUml.java create mode 100644 src/ch/ethz/infsec/secureumlgui/Util.java create mode 100644 src/ch/ethz/infsec/secureumlgui/WriteXmiActionListener.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/AbstractPermissionsTableModel.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/AbstractSecureUmlComponent.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/ActionNameTableCellRenderer.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/ActionNameTableCellRendererComponent.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/ActionPermissionTableCellEditor.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/ActionPermissionTableCellListener.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/ActionPermissionTableCellRenderer.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/ActionPermissionTableCellSelectionListener.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/ActionPermissionsTableCellRendererComponent.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/GenericResourcePermissionsTableModel.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/JTristateCheckBox.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/MultiLineToolTip.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/MultiLineToolTipUI.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/PermissionAttributesTableModel.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/PermissionIconTableCellRenderer.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/PermissionIconTableCellRendererComponent.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/PolicyLevelCreator.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/RolePermissionsTableModel.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/SecureUmlComponent.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/SecureUmlExcpPermissionComponent.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/SecureUmlPermissionComponent.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/SecureUmlRoleComponent.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/TableSorter.java create mode 100644 src/ch/ethz/infsec/secureumlgui/gui/package.html create mode 100644 src/ch/ethz/infsec/secureumlgui/icons/combined_icon.png create mode 100644 src/ch/ethz/infsec/secureumlgui/icons/composite_full_icon.png create mode 100644 src/ch/ethz/infsec/secureumlgui/icons/constrained_icon.png create mode 100644 src/ch/ethz/infsec/secureumlgui/icons/createRoleIcon.png create mode 100644 src/ch/ethz/infsec/secureumlgui/icons/implicit_by_composite.png create mode 100644 src/ch/ethz/infsec/secureumlgui/icons/implicit_icon.png create mode 100644 src/ch/ethz/infsec/secureumlgui/icons/inherited_icon.png create mode 100644 src/ch/ethz/infsec/secureumlgui/icons/inherited_policy_icon.png create mode 100644 src/ch/ethz/infsec/secureumlgui/logging/LoggerContext.java create mode 100644 src/ch/ethz/infsec/secureumlgui/logging/MultiContextLogger.java create mode 100644 src/ch/ethz/infsec/secureumlgui/logging/SimpleLogger.java create mode 100644 src/ch/ethz/infsec/secureumlgui/logging/SimpleMessageSink.java create mode 100644 src/ch/ethz/infsec/secureumlgui/main/ClassLoaderProviderImpl.java create mode 100644 src/ch/ethz/infsec/secureumlgui/main/FileLoader.java create mode 100644 src/ch/ethz/infsec/secureumlgui/main/SecureUmlConstants.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmanagement/ExtentInfo.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmanagement/ModelConst.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmanagement/OclModelInfo.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/GenericDialectHelper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/GenericDialectModelMapper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/ModelMapper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/ModelWriter.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/PathNameResolver.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/SecureUmlModelMapper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/counters/Counter.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/counters/SecureUmlMappingCounter.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/package.html create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/ActionPermissionSet.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/CompositePermission.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/HierarchicalPermissionsExplorer.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/HierarchicalPolicyExplorer.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/PermissionSet.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/PermissionValue.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/PolicyPermissionSet.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/ResourcePermissionsSet.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/package.html create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/strategies/MapSelf.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/strategies/MapSelfAndAssociatedResources.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/strategies/MappingScopeStrategy.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/strategies/SecureUmlMappingScopeStrategy.java create mode 100644 src/ch/ethz/infsec/secureumlgui/modelmapping/strategies/package.html create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/SecureModelPackage.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/ActionKind.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/ActionResourceAssociation.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/ActionType.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/AssociationEnd.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/AtomicActionType.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/CompositeActionType.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/ContainmentAssociation.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/DialectMetaModelInfo.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/InterResourceAssociation.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelAssociation.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelClass.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelClassAttribute.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelConst.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelEntity.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelFactory.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/ResourceType.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/TaggedValue.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/package.html create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/DialectMetaModelAnalyzer.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/DialectMetaModelParser.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/DialectMetaModelUtil.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/BooleanExpression.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/BooleanLiteral.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/ConjunctiveBooleanExpression.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/DecimalLiteral.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/DisjunctiveBooleanExpression.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/Equation.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/ExpressionEvaluator.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/ExpressionFactory.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/ExpressionFragment.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/IntLiteral.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/Literal.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OclEvaluatorException.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OclExpression.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OclExpressionEvaluator.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OclExpressionsParser.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OclParserException.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OclUmlExpressionEvaluator.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OperationStep.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/Path.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/PathFactory.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/PathFragment.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/PathStep.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/PropertyAccessStep.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/SelectionStep.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/Self.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/SetOperationStep.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/StringLiteral.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/package.html create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/package.html create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/package.html create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Action.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/ActionClass.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/ActionHierarchy.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/ActionResourceAssignment.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/AtomicAction.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/AtomicActionClass.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/AuthorizationConstraint.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/AuthorizationConstraintClass.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/CompositeAction.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/CompositeActionClass.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/ConstraintAssignment.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Group.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/GroupClass.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Permission.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/PermissionActionAssignment.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/PermissionAssignment.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/PermissionClass.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Resource.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/ResourceClass.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Role.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/RoleClass.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/RoleHierarchy.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/SecureUmlPackage.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Subject.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/SubjectAssignment.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/SubjectClass.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/SubjectGroup.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/User.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/UserClass.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/package.html create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodelimpl/SecureModelFactory.java create mode 100644 src/ch/ethz/infsec/secureumlgui/securemodelimpl/secureuml/package.html create mode 100644 src/ch/ethz/infsec/secureumlgui/transformation/MetaModelMap.java create mode 100644 src/ch/ethz/infsec/secureumlgui/transformation/ModelMap.java create mode 100644 src/ch/ethz/infsec/secureumlgui/transformation/package.html create mode 100644 src/ch/ethz/infsec/secureumlgui/usecasemapper/control/Controller.java create mode 100644 src/ch/ethz/infsec/secureumlgui/usecasemapper/control/MenuActionListener.java create mode 100644 src/ch/ethz/infsec/secureumlgui/usecasemapper/control/package.html create mode 100644 src/ch/ethz/infsec/secureumlgui/usecasemapper/gui/View.java create mode 100644 src/ch/ethz/infsec/secureumlgui/usecasemapper/gui/package.html create mode 100644 src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/ActorMapper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/MapperException.java create mode 100644 src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/MapperHelper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/MapperStrategy.java create mode 100644 src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/Permission.java create mode 100644 src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/PermissionMapper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/package.html create mode 100644 src/ch/ethz/infsec/secureumlgui/usecasemapper/package.html create mode 100644 src/ch/ethz/infsec/secureumlgui/util/ExcpPermissionDummy.java create mode 100644 src/ch/ethz/infsec/secureumlgui/util/ExtensionFilenameFilter.java create mode 100644 src/ch/ethz/infsec/secureumlgui/util/NotImplementedException.java create mode 100644 src/ch/ethz/infsec/secureumlgui/util/PermissionDummy.java create mode 100644 src/ch/ethz/infsec/secureumlgui/util/SelectMetamodelActionListener.java create mode 100644 src/ch/ethz/infsec/secureumlgui/util/Various.java create mode 100644 src/ch/ethz/infsec/secureumlgui/util/package.html create mode 100644 src/ch/ethz/infsec/secureumlgui/wrapper/ActionWrapper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/wrapper/AtomicActionWrapper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/wrapper/AttributeWrapper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/wrapper/AuthorizationConstraintWrapper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/wrapper/CompositeActionWrapper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/wrapper/ExceptionPermissionWrapper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/wrapper/ModelElementWrapper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/wrapper/MofClassWrapper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/wrapper/MofPackageWrapper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/wrapper/NamedModelElementWrapper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/wrapper/PermissionWrapper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/wrapper/PolicyWrapper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/wrapper/RefPackageWrapper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/wrapper/ResourceWrapper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/wrapper/RoleWrapper.java create mode 100644 src/ch/ethz/infsec/secureumlgui/wrapper/package.html create mode 100644 src/manifest.mf create mode 100644 src/overview.html create mode 100644 test/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/ActorMapperTest.java create mode 100644 test/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/MapperHelperTest.java create mode 100644 test/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/MapperTestHelper.java create mode 100644 test/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/PermissionMapperTest.java create mode 100644 test/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/package.html diff --git a/.gitignore b/.gitignore index d0485ae..e9d80d2 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,7 @@ # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml hs_err_pid* +# local ignores +local.properties +build + diff --git a/build.xml b/build.xml new file mode 100644 index 0000000..0e22f37 --- /dev/null +++ b/build.xml @@ -0,0 +1,226 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ${Name} Build file + ------------------------------------------------------------- + + available targets are: + + usage --> Show this message (default). + compile --> Compiles the source code to the tree under '${module.build.src}'. + package --> Generates the '${module.jarfile.name}' file. + install --> Install module '${argo.module.name}'. + clean --> Removes compiled files. + javadoc --> Generates the JavaDoc in '${javadoc.dir}'. + checkstyle --> Check code style with CheckStyle + pmd --> Check the code sanity with PMD and write the report to '${pmd.report.file}'. + junit --> Run the JUnit test suites. + run --> Run argouml with the newest version of the secure uml module. + + Caution: + ========= + The build process assumes that ${argo.hom} points to + the ArgoUML installation, i.e., the directory that + contains the ArgoUML jar files. For example, this property + can be set on the command line as follows: + ant -Dargo.home.dir="/usr/local/argouml-0.24/" install + or you may adapt the property in the 'local.properties' file. + ------------------------------------------------------------- + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/local.properties.in b/local.properties.in new file mode 100644 index 0000000..71deb19 --- /dev/null +++ b/local.properties.in @@ -0,0 +1 @@ +argo.home.dir= diff --git a/src/ch/ethz/infsec/secureumlgui/DialectMetamodelSelectedListener.java b/src/ch/ethz/infsec/secureumlgui/DialectMetamodelSelectedListener.java new file mode 100644 index 0000000..e179606 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/DialectMetamodelSelectedListener.java @@ -0,0 +1,14 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui; + +import java.io.File; + +/** + * + */ +public interface DialectMetamodelSelectedListener +{ + public void dialectMetamodelSelected(File xmiFile); +} diff --git a/src/ch/ethz/infsec/secureumlgui/ModuleController.java b/src/ch/ethz/infsec/secureumlgui/ModuleController.java new file mode 100644 index 0000000..9ab9aa1 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/ModuleController.java @@ -0,0 +1,386 @@ +package ch.ethz.infsec.secureumlgui; + +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Set; + + +import org.apache.log4j.Logger; +import org.argouml.ui.targetmanager.TargetManager; +import org.omg.uml.foundation.core.AssociationClass; +import org.omg.uml.foundation.core.Namespace; +import org.omg.uml.foundation.core.Attribute; +import org.omg.uml.foundation.core.ModelElement; +import org.omg.uml.foundation.core.Operation; +import org.omg.uml.foundation.core.UmlClass; + +//import ch.ethz.infsec.secureumlgui.gui.SecureUmlComponentManager; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.modelmapping.GenericDialectHelper; +import ch.ethz.infsec.secureumlgui.modelmapping.GenericDialectModelMapper; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.DialectMetaModelInfo; +import ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role; +import ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PermissionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PolicyWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.ResourceWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.RoleWrapper; +import ch.ethz.infsec.secureumlgui.transformation.ModelMap; +import ch.ethz.infsec.secureumlgui.util.PermissionDummy; + +/** + * Central controller instance between the GUI (SecureUML property tab) + * and the modelmapper (ArgoUml model -> SecureUML entities). + * + * + */ +public class ModuleController +/* TODO: refactor: introduce abstract class for this class + * & use the abstract class in PropPanels + */ +{ + private static Logger aLog = Logger.getLogger(ModuleController.class); + + private ModuleController() + { + //TargetManager.getInstance(). + + modelMapper = GenericDialectModelMapper.getInstance(); + if(modelMapper == null) + logger.error("modelMapper = null"); + } + + private GenericDialectHelper helper = GenericDialectHelper.getInstance(); + + private static ModuleController moduleControllerInstance = null; + + public static ModuleController getInstance() + { + if(moduleControllerInstance == null) + moduleControllerInstance = new ModuleController(); + if(modelMapper==null) { + moduleControllerInstance = null; + return null; + } + return moduleControllerInstance; + + } + +// public static ModuleController getInstance() +// { +// if(moduleControllerInstance == null) +// moduleControllerInstance = new ModuleController(); +// if(modelMapper==null) +// return null; +// return moduleControllerInstance; +// +// } + + MultiContextLogger logger = MultiContextLogger.getDefault(); + + static GenericDialectModelMapper modelMapper = null; + + /** initialize ModelMapper: clear cached mapped elements + * + */ + public void initModelMapper() + { + //logger.info("initModelMapper"); + if(modelMapper == null) { + //logger.info("modelMapper = null"); + modelMapper = GenericDialectModelMapper.getInstance(); + } + if(modelMapper != null) + modelMapper.init(); + } + + public Object transform(ModelElement modelElement) + { + if(modelMapper == null) { + logger.error("transform without modelmapper"); + return null; + } + else + { + + modelMapper.transform(modelElement); + + return modelMapper.getModelMap().getElement(modelElement); + } + } + + + /** returns a PermissionDummy containing only the necessary + * information. + * + * associated ModelElements are mapped, but not used. In + * Addition, the Mapping permissionAssociationClass <-> + * PermissionDummy is put to the ModelMap. + * + */ + public PermissionDummy getSecureUmlPermission( + AssociationClass permissionAssociationClass) + { + + PermissionDummy permissionDummy = (PermissionDummy) + ModelMap.getDefault().getElement( + permissionAssociationClass); + + return permissionDummy; + } + + + /* DONE: rethink design (maybe move part of this to the modelmapper bzw. + * to a separate 'modelWriter' class + */ + public void addPermission(PermissionWrapper permission) + { + modelMapper.getModelWriter().addPermission(permission); + + // moved to proppanels (they update theirselves) + // reloadMappings(permission); + + refreshPropPanel(permission); + + } + + //XXX +// public void addPermission( +// ActionWrapper actionWrapper, +// RoleWrapper roleWrapper) +// { +// modelMapper.getModelWriter().addPermission( +// actionWrapper, roleWrapper); +// +// // moved to proppanels (they update theirselves) +// // reloadMappings(permission); +// +// refreshPropPanel(); +// +// } + + public void addPermission(ActionWrapper actionWrapper, + RoleWrapper roleWrapper, Set policies) + { + aLog.debug("add permission: action " + actionWrapper.getName() + " role " + roleWrapper.getName() + " policies " + policies.size()); + + modelMapper.getModelWriter().addPermission( + actionWrapper, roleWrapper, policies); + + + // moved to proppanels (they update theirselves) + // reloadMappings(permission); + + refreshPropPanel(); + + } + + +// public UmlClass addPolicy(String policyName, Namespace namespace) { +// return modelMapper.getModelWriter().createPolicy(policyName, namespace); +// //return new PolicyWrapper(modelMapper.getModelMap().getElement(policyClass)); +// } + + public UmlClass createPolicy(String policyName, Set refined_by, Namespace namespace) { + aLog.debug("write to modelwriter"); + UmlClass policyClass = modelMapper.getModelWriter().createPolicy(policyName, refined_by, namespace); + aLog.debug("received new UmlClass: " + policyClass + " .. " + policyClass.getClass().toString()); + + TargetManager.getInstance().setTarget(policyClass); + + //modelMapper.init(); + modelMapper.examineUmlClass(policyClass); + + Object policyObject = modelMapper.getModelMap().getElement(policyClass); +// aLog.debug("new policyObject: " + policyObject); +// logger.info("added Policy: class" + policyClass +" \nObject " + policyObject); +// return new PolicyWrapper(policyObject); + return policyClass; + } + + //hack + public ModelMap getModelMap() { + return modelMapper.getModelMap(); + } + + public void addRole(String roleName, ResourceWrapper resourceWrapper) + { + try + { + ModelElement modelElement = (ModelElement) + modelMapper.getModelMap().getUmlElement(resourceWrapper.getModelElement()); + + + Namespace namespace = getNamespace(modelElement); + + //Role role = new RoleImpl(roleName); + + + UmlClass newRole = modelMapper.getModelWriter(). + createRole(roleName, namespace); + + if(newRole != null) + TargetManager.getInstance().setTarget(newRole); + + logger.info("Added role: " + roleName); + } + catch (Exception e) + { + logger.logException(e); + } + + // PropPanelClassSecureUml.getInstance().onTargetSet(); + } + public Namespace getNamespace(ModelElement modelElement) + { + if(modelElement instanceof UmlClass) + { + return modelElement.getNamespace(); + } + else if(modelElement instanceof Attribute) + { + return ((Attribute)modelElement).getOwner().getNamespace(); + } + else if(modelElement instanceof Operation) + { + return ((Operation)modelElement).getOwner().getNamespace(); + } + return null; + } + + protected void refreshPropPanel() + { + logger.info(//logger.TARGET_EVENTS, + "Model changed - triggering update " ); + // + resource); + + SecureUmlModule.getTab().onTargetSet(); + + } + /** + * @param permission + */ + protected void refreshPropPanel(PermissionWrapper permission) + { + try + { + logger.info(//logger.TARGET_EVENTS, + "Model changed - triggering update " + + "of PropPanel with Resource: " ); + // + resource); + + + // TODO: refresh proppanels + SecureUmlModule.getTab().onTargetSet(); + + } + catch (Exception e) + { + logger.logException(e); + } + } + + public Role getSecureUmlRole(UmlClass roleClass) + { + if(roleClass == null) + return null; + return (Role) ModelMap.getDefault().getElement(roleClass); + } + + + public List/**/ getAllRoles(Object resource) + { + try + { + List roles = new LinkedList(); + for (Iterator iter = modelMapper.getRoleClasses().iterator(); iter.hasNext();) + { + UmlClass roleClass = (UmlClass) iter.next(); + + roles.add(modelMapper.getModelMap().getElement(roleClass)); + } + + return roles; + + } + catch (Exception ex) + { + logger.logException(ex); + return new LinkedList(); + } + } + + public List getAllPolicies() { + List policies = new LinkedList(); + + for ( UmlClass umlClass : modelMapper.getPolicyClasses() ) { + policies.add( modelMapper.getModelMap().getElement(umlClass)); + } + + return policies; + } + +// public List getAllRoles(Entity entity) +// { +// try +// { +// ModelElement modelElement = (ModelElement) ModelMap.getDefault().getUmlElement(entity); +// +// return getAllRoles((Namespace) modelElement.getNamespace()); +// } +// catch (Exception ex) +// { +// logger.logException(ex); +// return null; +// } +// } + + public List/**/ getAllRoles(Namespace namespace) + { + return null; + //return modelMapper.transformAllRoles(namespace); + } + + + public void deletePermission(PermissionWrapper permissionWrapper) + { + // TODO: take from da; + modelMapper.getModelWriter().deletePermission(permissionWrapper); + + refreshPropPanel(permissionWrapper); + } + + +// // unused +// public void setPermissionName(PermissionWrapper permission, String name) +// { +// modelMapper.getModelWriter(). +// setPermissionName(permission, name); +// } +// + public void setAuthorizationConstraint(PermissionDummy permissionDummy, String constraint) + { + // TODO: take from da; + modelMapper.getModelWriter(). + setAuthorizationConstraint(permissionDummy, constraint); + } + + + DialectMetaModelInfo dialectMetaModelInfo; + + public DialectMetaModelInfo getDialectMetaModelInfo() + { + return dialectMetaModelInfo; + } + + public void setDialectMetaModelInfo( + DialectMetaModelInfo dialectMetaModelInfo) + { + this.dialectMetaModelInfo = dialectMetaModelInfo; + } + + + + /* Event Handlers */ +} diff --git a/src/ch/ethz/infsec/secureumlgui/ResourceFilesManager.java b/src/ch/ethz/infsec/secureumlgui/ResourceFilesManager.java new file mode 100644 index 0000000..9703245 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/ResourceFilesManager.java @@ -0,0 +1,125 @@ +package ch.ethz.infsec.secureumlgui; + +import javax.swing.ImageIcon; + +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; + +/** + * Provides access to the different icons needed by the SecureUML GUI. + * The icons are loaded from the folder IMAGE_FOLDER in the jar file. + * Note this makes it necessary, this class resides at the same point + * in the directory hierarchy, as the IMAGE_FOLDER. + * + * @version 1.0 + */ +public class ResourceFilesManager +{ + public static final String IMAGE_FOLDER = "icons/"; + + MultiContextLogger logger = MultiContextLogger.getDefault(); + + private ImageIcon createRoleIcon; + private ImageIcon constrainedIcon; + private ImageIcon inheritedRoleIcon; + private ImageIcon inheritedPolicyIcon; + private ImageIcon implicitIcon; + private ImageIcon compositeFullIcon; + private ImageIcon implicitByCompositeIcon; + + public ResourceFilesManager() + { + initImageIcons(); + } + + /** + * Loads the icons from the jar file. If an icon cannot be loaded, + * the logger will report an error. + */ + private void initImageIcons() + { + try { + createRoleIcon = createImageIcon(IMAGE_FOLDER + "createRoleIcon.png","create Role"); + constrainedIcon = createImageIcon(IMAGE_FOLDER + "constrained_icon.png","constrained Permission"); + inheritedRoleIcon = createImageIcon(IMAGE_FOLDER + "inherited_icon.png","inherited Permission"); + inheritedPolicyIcon = createImageIcon(IMAGE_FOLDER + "inherited_policy_icon.png","inherited Permission"); + implicitIcon = createImageIcon(IMAGE_FOLDER + "implicit_icon.png","implicit Permission"); + compositeFullIcon = createImageIcon(IMAGE_FOLDER + "composite_full_icon.png","composite Permission"); + implicitByCompositeIcon = createImageIcon(IMAGE_FOLDER + "implicit_by_composite.png", "implicit by composite Permission"); + } + catch(Exception e) { + logger.error("Could not load image icons in folder: " + IMAGE_FOLDER); + } + + if (createRoleIcon == null || + constrainedIcon == null|| + inheritedRoleIcon == null || + implicitIcon == null || + compositeFullIcon == null || + implicitByCompositeIcon == null) { + logger.error("error creating icons"); + + } + + } + + /** Returns an ImageIcon, or null if the path was invalid. */ + private ImageIcon createImageIcon(String path, + String description) { + java.net.URL imgURL = getClass().getResource(path); + if (imgURL != null) { + return new ImageIcon(imgURL, description); + } else { + logger.error("Couldn't find file: " + path); + return null; + } + } + + /** + * @return the compositeFullIcon + */ + public ImageIcon getCompositeFullIcon() + { + return compositeFullIcon; + } + + /** + * @return the constrainedIcon + */ + public ImageIcon getConstrainedIcon() + { + return constrainedIcon; + } + + /** + * @return the implicitIcon + */ + public ImageIcon getImplicitIcon() + { + return implicitIcon; + } + + public ImageIcon getImplicitByInheritedIcon() { + return implicitByCompositeIcon; + } + + + /** + * @return the inheritedIcon + */ + public ImageIcon getInheritedRoleIcon() + { + return inheritedRoleIcon; + } + + public ImageIcon getInheritedPolicyIcon() { + return inheritedPolicyIcon; + } + + /** + * @return the createRoleIcon + */ + public ImageIcon getCreateRoleIcon() + { + return createRoleIcon; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/SecureUmlModule.java b/src/ch/ethz/infsec/secureumlgui/SecureUmlModule.java new file mode 100644 index 0000000..9d07236 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/SecureUmlModule.java @@ -0,0 +1,319 @@ +package ch.ethz.infsec.secureumlgui; + + +// $Id: ActionTestLoadableModule.java,v 1.5 2005/10/10 21:06:32 linus Exp $ +// Copyright (c) 2004-2005 The Regents of the University of California. All +// Rights Reserved. Permission to use, copy, modify, and distribute this +// software and its documentation without fee, and without a written +// agreement is hereby granted, provided that the above copyright notice +// and this paragraph appear in all copies. This software program and +// documentation are copyrighted by The Regents of the University of +// California. The software program and documentation are supplied "AS +// IS", without any accompanying services from The Regents. The Regents +// does not warrant that the operation of the program will be +// uninterrupted or error-free. The end-user understands that the program +// was developed for research purposes and is advised not to rely +// exclusively on the program for any reason. IN NO EVENT SHALL THE +// UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, +// SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, +// ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF +// THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF +// SUCH DAMAGE. THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE +// PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF +// CALIFORNIA HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, +// UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + +//package org.argouml.ui.test; + +//import java.awt.event.*; +import java.awt.event.KeyEvent; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FilenameFilter; +import java.io.IOException; +import java.util.List; +import java.util.Properties; + +import javax.swing.ButtonGroup; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JRadioButtonMenuItem; + +import java.lang.Thread; + +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.DialectMetaModelParser; +import ch.ethz.infsec.secureumlgui.usecasemapper.control.MenuActionListener; +import ch.ethz.infsec.secureumlgui.util.ExtensionFilenameFilter; +import ch.ethz.infsec.secureumlgui.util.SelectMetamodelActionListener; + +import ch.ethz.infsec.secureumlgui.main.ClassLoaderProviderImpl; + +import org.apache.log4j.Logger; +import org.apache.log4j.PropertyConfigurator; +import org.argouml.moduleloader.ModuleInterface; +import org.argouml.ui.ProjectBrowser; +import org.argouml.ui.cmd.GenericArgoMenuBar; +import org.argouml.ui.targetmanager.TargetManager; + +import org.netbeans.mdr.handlers.BaseObjectHandler; +//import org.netbeans.mdr.handlers.MDRClassLoader; + +/** + * SecureUmlModule: ArgoUml Module for editing and displaying SecureUML policies. + * + * Adds SecureUmlComponents to PropertyPanels of ModelElements + * representing SecureUml Entities with basic Functionalities like + * displaying, adding & removing Permissions for Entities, + * textually editing Authorization Constraints of Permissions. + * All Changes performed through the SecureUmlComponent are immediately + * written down to the underlying Uml ModelElements + * + */ +public final class SecureUmlModule implements + ModuleInterface + //, ActionListener, TargetListener +{ + + + private static boolean enabled=false; + // private static SecureUmlComponentManager suManager; + private boolean isPropPanelsInitialized = false; + + private static TabSecureUml tab; + private MultiContextLogger logger = new MultiContextLogger( + MultiContextLogger.STARTUP); + + DialectMetaModelParser dialectMetaModelParser = new DialectMetaModelParser(); + + private static Logger aLog = Logger.getLogger(SecureUmlModule.class); + /** + * This is creatable from the module loader. + */ + public SecureUmlModule() + { + Properties log4jProps = new Properties(); + try { + log4jProps.load(new BufferedInputStream(new FileInputStream(new File("ext/log4j.properties")))); + PropertyConfigurator.configure(log4jProps); + aLog.info("Loaded log4j configuration from \"ext/log4j.properties\""); + } catch (IOException e) { + logger.error("Could not load log4j configuration from \"ext/log4j.properties\" IOException: " + e.getMessage()); + } + aLog.info("SecureUML Module initialized"); + logger.info("SecureUML Module initialized"); + //unfortunately, this is too late. this should be done, before mdr is initialized... + BaseObjectHandler.setClassLoaderProvider(new ClassLoaderProviderImpl()); + // Thread.currentThread().setContextClassLoader(new MDRClassLoader(new ClassLoaderProviderImpl())); + } + + static public TabSecureUml getTab() { + return tab; + } + + static public String findSecureUMLDir () + { + List ext_dirs = + org.argouml.moduleloader.ModuleLoader2.getInstance().getExtensionLocations(); + for (String dir: ext_dirs) { + File su_ext = new File(dir+"/argo_secureuml_gui.jar"); + if(su_ext.exists()) return dir; + } + throw (new java.lang.RuntimeException("SecureUML GUI Plugin not found")); + } + + + + /** + * + */ + private void initializeMenu() + { + GenericArgoMenuBar menubar = (GenericArgoMenuBar) ProjectBrowser + .getInstance().getJMenuBar(); + + + JMenu secureUMLMenu = new JMenu("SecureUML"); + secureUMLMenu.setMnemonic(KeyEvent.VK_S); + + menubar.getTools().addSeparator(); + + secureUMLMenu.add(new JMenuItem("Selected Dialect Metamodel:")); + + File[] xmiFiles = findDialectMetamodelFiles(); + + ButtonGroup menuItemsGroup = new ButtonGroup(); + for (int i = 0; i < xmiFiles.length; i++) + { + File xmiFile = xmiFiles[i]; + + JRadioButtonMenuItem menuItem = + new JRadioButtonMenuItem(xmiFile.getName()); + + SelectMetamodelActionListener selectActionListener = + new SelectMetamodelActionListener( + xmiFile, dialectMetaModelParser); + + menuItem.addActionListener(selectActionListener); + menuItemsGroup.add(menuItem); + + secureUMLMenu.add(menuItem); + } + + secureUMLMenu.addSeparator(); + + JMenu useCaseMapperMenu = new JMenu("Use Case Mapper"); + JMenuItem mapUseCasesItem = new JMenuItem("Map Use Cases..."); + mapUseCasesItem.addActionListener(new MenuActionListener()); + useCaseMapperMenu.add(mapUseCasesItem); + + secureUMLMenu.add(useCaseMapperMenu); + + secureUMLMenu.addSeparator(); + + // (JD) show when it is finished: + JMenuItem writeXmiItem = new JMenuItem("Write XMI"); + writeXmiItem.addActionListener(new WriteXmiActionListener()); + writeXmiItem.setEnabled(true); + secureUMLMenu.add(writeXmiItem); + + menubar.add(secureUMLMenu); + + } + + boolean isEnabled = true; + + + + /** + * looks for .xmi files in the ArgoUML ext/ directory. + * + * @return an array containing the found files + */ + public File[] findDialectMetamodelFiles() + { + File extDirectory = new File(findSecureUMLDir()); + + if(!extDirectory.exists()) + { + logger.error("'ext' Directory not found - cannot load Dialect metamodels"); + return null; + } + else + { + FilenameFilter xmiFilenameFilter = new ExtensionFilenameFilter("xmi"); + + File[] xmiFiles = extDirectory.listFiles(xmiFilenameFilter); + + for (int i = 0; i < xmiFiles.length; i++) + { + File xmiFile = xmiFiles[i]; + + //logger.info("XMI File found: " + xmiFile.getName()); + } + + return xmiFiles; + } + + } + + + // Methods from the ModuleLoader interface + /** + * + * @see ModuleInterface#enable() + */ + public boolean enable() + { + + if(!enabled) { + enabled=true; + logger.info("SecureUML Module enabled"); + + initializeMenu(); + isEnabled = true; + + TabSecureUml tabSecureUml = new TabSecureUml(); + tab=tabSecureUml; + + TargetManager.getInstance().addTargetListener(tabSecureUml); + + Object target = TargetManager.getInstance().getTarget(); + TargetManager.getInstance().setTarget(null); + TargetManager.getInstance().setTarget(target); + + org.argouml.ui.DetailsPane detailsPane = (org.argouml.ui.DetailsPane)ProjectBrowser.getInstance().getDetailsPane(); + //dont just add, as otherwise probably confilcts with the way, the property tab + //is resolved by using the last non null tab + //DetailsPane.java 223 + tabSecureUml.setName("SecureUML Properties"); + detailsPane.addTab( tabSecureUml, true); + + //(JD) A hack. ArgoUML tries to translate the title, and fails... + int i = detailsPane.getTabs().indexOfComponent(tabSecureUml); + detailsPane.getTabs().setTitleAt(i,"SecureUML Properties"); + + tabSecureUml.setEnabled(false); + } + return true; + + } + + /** + * @see ModuleInterface#disable() + * + * This removes us from the Tools menu. If we were not registered there we + * don't care. + */ + public boolean disable() + { + isEnabled = false; + isPropPanelsInitialized = false; + + Object target = TargetManager.getInstance().getTarget(); + TargetManager.getInstance().setTarget(null); + TargetManager.getInstance().setTarget(target); + + return true; + } + + /** + * @see ModuleInterface#getName() + */ + public String getName() + { + return "SecureUMLGUI Module"; + } + + /** + * @see ModuleInterface#getInfo(int) + */ + public String getInfo(int type) + { + switch (type) + { + case DESCRIPTION: + return "This is the SecureUmlGui Module " + + "offering an alternative GUI to edit " + + "SecureUML-permissions "; +// break; + case AUTHOR: + return "Marcel Beer"; +// break; + case VERSION: + return "0.42"; +// break; + default: + return null; + } + } + + /** + * The version uid. + */ + private static final long serialVersionUID = -2570516012301142091L; + +} diff --git a/src/ch/ethz/infsec/secureumlgui/TabSecureUml.java b/src/ch/ethz/infsec/secureumlgui/TabSecureUml.java new file mode 100644 index 0000000..d1c169b --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/TabSecureUml.java @@ -0,0 +1,308 @@ +package ch.ethz.infsec.secureumlgui; + +import org.argouml.ui.*; +import org.omg.uml.foundation.core.ModelElement; +import org.argouml.model.Model; +import org.argouml.ui.targetmanager.TargetEvent; +import org.argouml.ui.TabModelTarget; + +import java.awt.Dimension; +import java.awt.event.ActionListener; +import java.awt.BorderLayout; +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.JScrollPane; +import javax.swing.JPanel; +import javax.swing.ListSelectionModel; + +import java.util.LinkedHashMap; +import java.util.Map; + +import ch.ethz.infsec.secureumlgui.gui.*; +import ch.ethz.infsec.secureumlgui.ModuleController; +import ch.ethz.infsec.secureumlgui.ResourceFilesManager; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ResourceType; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.MetaModelConst; +import ch.ethz.infsec.secureumlgui.wrapper.ResourceWrapper; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.ActionPermissionSet; +import ch.ethz.infsec.secureumlgui.modelmapping.GenericDialectHelper; +import ch.ethz.infsec.secureumlgui.modelmapping.GenericDialectModelMapper; +import ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.AtomicActionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.CompositeActionWrapper; +import ch.ethz.infsec.secureumlgui.transformation.ModelMap; +import ch.ethz.infsec.secureumlgui.main.SecureUmlConstants; + +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; + +// (JD) I'm trying to move only the needed parts from SecureUmlComponentContainer +// into this class. then probably only SecureUmlComponentManager has to be adjusted. + +/** + * Represents the SecureUML properties tab in the ArgoUML details pane. + * + * Also manages to select which SecureUML Component to show in the tab, + * i.e., one of {@link SecureUmlComponent}, {@link SecureUmlRoleComponent}, + * {@link SecureUmlPermissionComponent}, depending on the type of the selected element. + * + * @version 1.0 + */ +public class TabSecureUml + extends AbstractArgoJPanel + implements TabModelTarget + // extends AbstractArgoJPanel + //implements TabModelTarget, ActionListener, ListSelectionListener, ComponentListener +{ + + private Object target; + private boolean shouldBeEnabled = false; + + private boolean hack_init = false; + + public TabSecureUml() + { + this.setLayout(new BorderLayout()); + } + + + /** + * show the given component in the SecureUML properties tab. + * + * the previously shown component is hidden. + * @param comp the component to be shown. + */ + public void setComponent(AbstractSecureUmlComponent comp) { + this.removeAll(); + if(comp != null) { + this.add(comp,BorderLayout.CENTER); + } + this.validate(); + this.repaint(); + } + + public void setEnabled(boolean enabled) { + shouldBeEnabled = enabled; + } + + private Map secureUmlComponents + = new LinkedHashMap(); + + MultiContextLogger logger = new MultiContextLogger(MultiContextLogger.GUI); + + public AbstractSecureUmlComponent getSecureUMLComponent(String stereotype) + { + if(stereotype == null) + return null; + else + return secureUmlComponents.get(stereotype); + } + + public void registerSecureUmlComponent(ResourceType resourceType, + AbstractSecureUmlComponent suComponent) + { + if(resourceType == null) + { + logger.error("stereotype == null @ SecureUMLComponentContainer.registerSecureUMLComponent"); + } + else + secureUmlComponents.put(resourceType, suComponent); + } + + public void registerSecureUmlComponent(ResourceType resourceType) + // TODO: change s.t. modelElements which are Resources, + // but not directly stereotyped are supported, too + { + registerSecureUmlComponent(resourceType, null); + } + + + // // Target Events Handlers + + /** + * Display the proper panel component for this resourcetype. + * + * This method is only called, if the newTarget + * is a SecureUML Element + * + */ + public void onTargetSet(Object newTarget, ResourceType rt) + { + if (newTarget instanceof ModelElement) { + ModelElement me = (ModelElement) newTarget; + + + AbstractSecureUmlComponent suComponent = null; + if(me != null + && me.getName() != null + && me.getName().length()>0 + && rt != null) { + suComponent = secureUmlComponents.get(rt); + } + + if(suComponent != null) { + Object suElement = ModelMap.getDefault().getElement(me); + if(suElement != null) { + suComponent.setDisplayedSecureUmlElement(suElement, rt); + this.setComponent(suComponent); + } + } + else { + logger.info("no SecureUML Component found " + + "for ResourceType: " + rt); + this.setComponent(null); + } + } + else logger.error("new Target is not an ArgoUML ModelElement: " + + newTarget); + } + + + public Object getTarget() { + return target; + } + + public void refresh() { + setTarget(target); + } + + public void setTarget(Object target) { + if (!(Model.getFacade().isAModelElement(target))) { + this.target = null; + shouldBeEnabled = false; + return; + } + + this.target = target; + shouldBeEnabled = false; + + + } + + public boolean shouldBeEnabled() { + return shouldBeEnabled; + } + + public boolean shouldBeEnabled(Object target) { + boolean shouldBeEnabled=false; + if (target instanceof ModelElement) { + if (Model.getFacade().isAModelElement(target)) + shouldBeEnabled=isSecureUmlElement((ModelElement)target); + } + this.shouldBeEnabled=shouldBeEnabled; + return shouldBeEnabled; + } + + public void onTargetSet() + { + onTargetSet(target); + } + + /** + * Find out the type of the newTarget (Role, Permission, or Resource), and act accordingly. + * + * @param newTarget + */ + public void onTargetSet(Object newTarget) + { + // logger.info("executing SecureUmlComponentManager.onTargetSet()");// + newTarget + ")"); + + if(GenericDialectModelMapper.getInstance()==null) return; + target = newTarget; + + if(newTarget == null) + return; + + String newTargetClassName = newTarget.getClass().getSimpleName() + .split(MetaModelConst.MDR_IMPL_SUFFIX_REGEXP)[0]; + + + + if (newTarget instanceof ModelElement) { + ModelElement me = (ModelElement) newTarget; + + // don't handle unnamed Elements + if(me.getName() == null || me.getName().length() == 0) { + logger.info("unnamed model element"); + onTargetSet(newTarget, null); + } else { // if Element != null and named + logger.info("model element: " + me.getName()); + + try { + ResourceType targetResourceType = GenericDialectHelper.getInstance().getSecureUmlType(me); + if(targetResourceType != null ) { + logger.info("targetResourceType: " + targetResourceType.getName()); + ModuleController.getInstance().initModelMapper(); + Object secureUmlElement = ModuleController.getInstance().transform(me); + + if(secureUmlElement == null) { + logger.error("new target could not be mapped"); + return; + } + } else { + logger.info("Could not find ResourceType for " + me); + if ( ! hack_init && !me.getName().contains("untitled")) { //untitledModel + hack_init = true; + GenericDialectModelMapper.getInstance().transform(me); + } + + } + + onTargetSet(newTarget, targetResourceType); + } + + catch (Exception ex) { + //secureumlComponent.setErrorMessage(ex.getMessage()); + logger.logException(ex); + } + } + } + } + + + public boolean isSecureUmlElement(ModelElement me) { + return GenericDialectHelper.getInstance().isSecureUmlRole(me) + || GenericDialectHelper.getInstance().isSecureUmlPermission(me) + || GenericDialectHelper.getInstance().getResourceType(me) != null; + } + + public void targetSet(TargetEvent e) { + onTargetSet(e.getNewTarget()); + } + + public void targetAdded(TargetEvent e) + { + //logger.info("** target Added"); + + try + { + if(e != null && e.getAddedTargetCollection() != null + && e.getAddedTargetCollection().size()>0) + { + Object addedTarget = + e.getAddedTargetCollection().iterator().next(); + onTargetSet(addedTarget); + } + else + { + logger.error("added target = null"); + onTargetSet(null); + } + } + catch (Exception ex) + { + logger.error("** targetAdded: AddedTargetCollection is empty!"); + } + + + } + + + public void targetRemoved(TargetEvent e) + { + if(e != null) + { + Object newTarget = e.getNewTarget(); + //FIXME: and now? + } + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/Util.java b/src/ch/ethz/infsec/secureumlgui/Util.java new file mode 100644 index 0000000..e64f811 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/Util.java @@ -0,0 +1,426 @@ +package ch.ethz.infsec.secureumlgui; + +import java.io.File; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Iterator; + +import org.omg.uml.foundation.core.Stereotype; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.MetaModelConst; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; + +/** + * Misc. Utility methods. + * + * @version 1.0 + */ +public class Util +{ + /** + * Returns a capitalized string + * + * @param name the string to capitalize + * @return the capitalized String + */ + public static String capitalize(String name) + { + if(name != null && name.length() > 0) + return name.substring(0, 1).toUpperCase() + + name.substring(1, name.length()); + else + return name; + } + + /** + * @param type + * @param methodName + * @return the first Method of Type 'type' with name equals 'methodName' + */ + public static Method findMethodByName(Class type, String methodName) + { + if(type != null && methodName != null) + { + Method[] methods = type.getMethods(); + + for (int i = 0; i < methods.length; i++) + { + Method m = methods[i]; + + if(methodName.equals(m.getName())) + return m; + } + } + + return null; + } + + public static boolean isInstanceof(Class c, String parentClassName) + { + if(c == null + || parentClassName == null + || parentClassName.length()==0) + { + return false; + } + String className = c.getSimpleName(); + + if(className.equals(parentClassName)) + return true; + else + { + return isInstanceof(c.getSuperclass(), parentClassName); + } + } + + public static boolean hasType(Object modelElement, String className) + { + className += MetaModelConst.MDR_IMPL_SUFFIX; + + if (modelElement != null && className != null) + return modelElement.getClass().getSimpleName().startsWith(className); + else + return false; + } + + public static boolean hasStereotype( + org.omg.uml.foundation.core.ModelElement element, String stereotype) + { + if (element == null || stereotype == null || stereotype.length() == 0) + return false; + + Collection stereotypes = element.getStereotype(); + int nofStereotypes = stereotypes.size(); + + if (stereotypes == null || stereotypes.size() == 0) + return false; + + for (Iterator it = stereotypes.iterator(); it.hasNext();) + { + Stereotype s = (Stereotype) it.next(); + if (s.getName().equals(stereotype)) + { + return true; + } + } + return false; + } + + public static Object invokeParameterlessMethod(Object object, String methodName) + { + try + { + java.lang.reflect.Method getter = + object.getClass().getMethod( + methodName, new Class[0]); + + return getter.invoke(object, new Object[0]); + } + catch (Exception e) + { + logger.info("Problem invoking method '" + + methodName + "' on: " + object); + Util.printInterfaces(object.getClass()); + + logger.logException(e); + } + return null; + } + + public static Object getProperty(Object object, String propertyName) + { + // exception is only logged if both trys fail + Exception ex; + if (object==null) + logger.error("trying to get property "+propertyName+" from null object"); + try + { + //logger.info("trying get"+capitalize(propertyName)); + java.lang.reflect.Method getter = object.getClass().getMethod( + "get" + capitalize(propertyName), new Class[0]); + + return getter.invoke(object, new Object[0]); + } + catch (Exception e) + { + ex = e; + } + // boolean case + try + { + //logger.info("trying is"+capitalize(propertyName)); + java.lang.reflect.Method getter = object.getClass().getMethod( + "is" + capitalize(propertyName), new Class[0]); + + return getter.invoke(object, new Object[0]); + } + catch (Exception e) + { + logger.info("Problem getting property '" + + propertyName + "' from: " + object); + Util.printInterfaces(object.getClass()); + + logger.logException(ex); + logger.logException(e); + } + return null; + } + + public static Object tryGetProperty(Object object, String propertyName) + { + try + { + java.lang.reflect.Method getter = object.getClass().getMethod( + "get" + capitalize(propertyName), new Class[0]); + + return getter.invoke(object, new Object[0]); + } + catch (Exception e) + { + //logger.logException(e); + + // case for boolean properties + try + { + java.lang.reflect.Method getter = object.getClass().getMethod( + "is" + capitalize(propertyName), new Class[0]); + + return getter.invoke(object, new Object[0]); + } + catch (Exception ex) + { + // logger.logException(e); + } + } + return null; + } + + /** + * @param object + * @param value + * @param propertyName + */ + public static void setProperty(Object object, String propertyName, Object value) + { + try + { + java.lang.reflect.Method getter = null; + try + { + getter = object.getClass().getMethod( + "get" + capitalize(propertyName), new Class[0]); + } + catch (Exception e) + { + } + if(getter == null) + { + try + { + getter = object.getClass().getMethod( + "is" + capitalize(propertyName), new Class[0]); + } + catch (Exception e) + { + logger.logException(e); + } + } + + if(getter.getReturnType() == Collection.class + && getter.getParameterTypes().length == 0) + { + Collection collectionValue = (Collection) + getter.invoke(object, new Object[0]); + + if(collectionValue != null) + { + collectionValue.add(value); + } + } + else + { + Class[] setterArgTypes = { getter.getReturnType() }; + + java.lang.reflect.Method setter = object.getClass().getMethod( + "set" + capitalize(propertyName), setterArgTypes); + + Object[] setterArgs = { value }; + setter.invoke(object, setterArgs); + } + } + catch(NoSuchMethodException e) + { + logger.error("Setter Method for Property '" + + propertyName + + "' not found: \n" + + "Available Methods: \n"); + Util.printInterfaces(object.getClass()); + + } + catch (Exception e) + { + logger.logException(e); + } + } + + static MultiContextLogger logger = MultiContextLogger.getDefault(); + + /** + * checks whether a file name exists and the file can be read. + * + * Aborts the program, if not. + * @param filename the file name to check for + * @return the File object of the given file name + */ + public static File checkAndGetFile(String filename) + { + if(filename == null || filename.length() == 0) + { + logger.error("empty filename given for required file!" + + " ...exiting"); + } + else + { + File file = + new File(filename); + if(file.exists() && file.canRead()) + { + return file; + } + } + + System.exit(1); + + // unreachable, but needed to compile + return null; + } + + public static void printInterfaces(Class cl) + { + if (cl != null) + { + + Class[] interfaces = cl.getInterfaces(); + System.out + .println(" - Interfaces of class '" + cl.getName() + " :"); + for (int i = 0; i < interfaces.length; i++) + { + System.out.println("i: " + interfaces[i].getName()); + + for (int j = 0; j < interfaces[i].getMethods().length; j++) + { + Method method = interfaces[i].getMethods()[j]; + + System.out.println(" m: " + method.toString()); + } + // + } + } + } + + + + public static void printJmiNamespace(javax.jmi.model.Namespace namespace, String prefix) + { + Collection packages = namespace.getContents(); + for (Iterator iter = packages.iterator(); iter.hasNext();) + { + javax.jmi.model.ModelElement element = (javax.jmi.model.ModelElement) iter.next(); + + logger.info(prefix + element.getName()); + + + + if (element instanceof javax.jmi.model.Namespace) + { + prefix = " " + prefix; + + javax.jmi.model.Namespace n = (javax.jmi.model.Namespace) element; + printJmiNamespace(n, prefix); + } + } + } + public static void printJmiNamespace(javax.jmi.model.Namespace namespace) + { + printJmiNamespace(namespace, ""); + } + + + /** + * Adds all elements from the Collection addables to the Collection c - and + * performs each add-operation in a seperate try-catch-statement + * + * + * @param c + * a Collection + * @param addables + * collection of Elements which are to be added to c + */ + public static void addAllSave(Collection c, Collection addables) + { + if (c == null || addables == null) + return; + + for (Iterator iter = addables.iterator(); iter.hasNext();) + { + try + { + Object o = (Object) iter.next(); + + c.add(o); + } + catch (Exception e) + { + logger.logException(e); + } + } + } + + +// public static Stereotype findStereotypeByName(Collection availableStereotypes, String name, boolean loggingOn) +// { +// String stereotypeMessge = "searching Stereotype: " + name + " among: \n"; +// +// Stereotype result = null; +// +// for (Iterator iter = availableStereotypes.iterator(); iter.hasNext();) +// { +// Stereotype stereotype = (Stereotype) iter.next(); +// +// if( stereotype.getName().equals(name)) +// { +// stereotypeMessge += ">" + stereotype.getName() + "\n"; +// +// result = stereotype; +// } +// stereotypeMessge += stereotype.getName() + "\n"; +// } +// if(loggingOn) +// logger.info(logger.MODELWRITER,stereotypeMessge); +// +// return result; +// } + +// private static String permissionNamePrefix = "Permission"; +// private static String permissionNameSuffix = "Permission"; + private static int permissionNumber = 42; + + /* returns a number for a permission that is being created + * (currenty strategy is to number'em ascending from 42) + */ + public static int getNewPermissionNumber() + { + return permissionNumber++; + } + + private static int roleNumber = 42; + + /* returns a number for a permission that is being created + * (currenty strategy is to number'em ascending from 42) + */ + public static int getNewRoleNumber() + { + + return roleNumber++; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/WriteXmiActionListener.java b/src/ch/ethz/infsec/secureumlgui/WriteXmiActionListener.java new file mode 100644 index 0000000..93103ef --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/WriteXmiActionListener.java @@ -0,0 +1,60 @@ +package ch.ethz.infsec.secureumlgui; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +import ch.ethz.infsec.secureumlgui.modelmapping.GenericDialectModelMapper; + +import java.io.File; +import javax.jmi.reflect.RefPackage; +import javax.swing.JFileChooser; + +import org.netbeans.api.xmi.XMIWriter; +import org.netbeans.api.xmi.XMIWriterFactory; + +import java.io.FileOutputStream; + +/** + * ActionListener for the Write Xmi Menu item (FIXME: move to proper + * place). This is a hack at the moment. We just write the current + * contents of the repository. We should be more careful here to make + * sure that really everything gets mapped. I.e., transform with a + * "MapAll" strategie into a separate extent, and write from there. + + * @version 1.0 + */ +// FIXME (JD): this can be made an inner class of SecureUmlModule? +public class WriteXmiActionListener implements ActionListener { + + + JFileChooser fc; + + WriteXmiActionListener() { + fc = new JFileChooser(); + } + + /** + * Responds to the ActionEvents from the module menu. + * + * @param event the ActionEvent to be handled. + */ + public final void actionPerformed(final ActionEvent event) { + int val = fc.showSaveDialog(null); + + if (val == JFileChooser.APPROVE_OPTION) { + File file = fc.getSelectedFile(); + + RefPackage model = (RefPackage) GenericDialectModelMapper.getInstance().dialectMetaModelInfo.getDialectExtent(); + //System.out.print(mof); + + XMIWriter writer = XMIWriterFactory.getDefault().createXMIWriter(); + try { + FileOutputStream out = new FileOutputStream(file); + writer.write(out, model, null); + } catch (Exception e) { + System.out.println("Fatal error writing XMI."); + e.printStackTrace(); + } + } + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/AbstractPermissionsTableModel.java b/src/ch/ethz/infsec/secureumlgui/gui/AbstractPermissionsTableModel.java new file mode 100644 index 0000000..af204b7 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/AbstractPermissionsTableModel.java @@ -0,0 +1,257 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.gui; + +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import javax.swing.event.TableModelEvent; +import javax.swing.table.AbstractTableModel; +import javax.swing.table.JTableHeader; + +import org.argouml.ui.targetmanager.TargetManager; +import org.omg.uml.foundation.core.UmlClass; + +import ch.ethz.infsec.secureumlgui.ModuleController; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.main.SecureUmlConstants; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.ActionPermissionSet; +//import ch.ethz.infsec.secureumlgui.securemodel.secureuml.Permission; +//import ch.ethz.infsec.secureumlgui.securemodel.secureuml.Resource; +//import ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role; + +import ch.ethz.infsec.secureumlgui.wrapper.PermissionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.RoleWrapper; +import ch.ethz.infsec.secureumlgui.securemodelimpl.SecureModelFactory; +import ch.ethz.infsec.secureumlgui.transformation.ModelMap; + + +/** + * + */ +public abstract class AbstractPermissionsTableModel + extends AbstractTableModel + implements MouseListener +{ + /** + * + */ + public AbstractPermissionsTableModel(Object resource) + { + super(); + + //setResource(resource); + } + + /** + * @param resource + */ + protected void setResource(Object resource) + { + roleWrappers.clear(); + + for (Object role : ModuleController.getInstance().getAllRoles(resource)) { + RoleWrapper rw = new RoleWrapper(role); + roleWrappers.add(rw); + } + } + + + protected String newPermissionSuffix = SecureUmlConstants.NEW_PERMISSION_SUFFIX; + + /** + * @return the newPermissionSuffix + */ + protected String getNewPermissionSuffix() + { + return newPermissionSuffix;// + newPermissionNumber++; + } + + /** + * @param newPermissionSuffix the newPermissionSuffix to set + */ + protected void setNewPermissionSuffix(String newPermissionSuffix) + { + this.newPermissionSuffix = newPermissionSuffix; + } + + protected List roleWrappers = + new ArrayList(); + + + + protected MultiContextLogger logger = new MultiContextLogger( + MultiContextLogger.GUI); + + + public int getColumnCount() + { + /* TODO: constant in first Version + * (could do via reflection later) + * + * // old, swapped layout + * + * // 4 = 1 (for the role name) + * // + 3 (for the attribute Actions -read, change, full access) + */ + + return roleWrappers.size() + 1; + } + + @Override + public Class getColumnClass(int columnIndex) + { +// if(columnIndex == 0) +// return String.class; + //else + if(columnIndex >= 1) + // return Boolean.class; + return ActionPermissionSet.class; + else + return super.getColumnClass(columnIndex); + } + + @Override + public String getColumnName(int column) + { + //logger.info(logger.GUI, "requesting Column Name " + column); + + if(column == 0) + return "ACTION"; + else + { + try + { + RoleWrapper roleWrapper = roleWrappers.get(column-1); + return roleWrapper.getName(); + } + catch (Exception e) + { + + e.printStackTrace(); + return super.getColumnName(column); + } + } + } + + + public boolean isCellEditable(int row, int col) + { + //Note that the data/cell address is constant, + //no matter where the cell appears onscreen. + if (col == 0) + { + return false; + } + else + { + return true; + } + } + + + public void fireManually() + { + fireTableStructureChanged(); + fireTableDataChanged(); + fireTableChanged(new TableModelEvent(this)); + } + +// helper methods + + + /* creates a new Permission object connects it + * to the role given as argument + */ + protected PermissionWrapper createPermission( + RoleWrapper/*Role*/ roleWrapper) + { + /*Permission*/ Object o = + SecureModelFactory.getInstance(). + createPermission(); + + PermissionWrapper p = new PermissionWrapper(o); + p.setRoleWrapper(roleWrapper); + + + return p; + } + + /* (non-Javadoc) + * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent) + */ + public void mouseClicked(MouseEvent e) + { +// logger.info("Table Header Mouse Clicked" +// + "\n source: " + e.getSource() +// + "\n component: " + e.getComponent() +// + "\n point:" + e.getPoint()); + + if(e.getClickCount() == 2) + { + try + { + JTableHeader header = (JTableHeader) e.getSource(); + int clickedColumnIndex = + header.getColumnModel().getColumnIndexAtX(e.getX()); + + Object clickedSuRole = + roleWrappers.get(clickedColumnIndex-1). + getModelElement(); + + Object roleUml = + ModelMap.getDefault().getUmlElement(clickedSuRole); + if (roleUml instanceof UmlClass) + { + UmlClass roleUmlClass = (UmlClass) roleUml; + TargetManager.getInstance().setTarget(roleUmlClass); + } + } + catch (Exception ex) + { + logger.logException(ex); + } + } + } + + /* (non-Javadoc) + * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent) + */ + public void mouseEntered(MouseEvent e) + { + + } + + /* (non-Javadoc) + * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent) + */ + public void mouseExited(MouseEvent e) + { + + } + + /* (non-Javadoc) + * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent) + */ + public void mousePressed(MouseEvent e) + { + + } + + /* (non-Javadoc) + * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent) + */ + public void mouseReleased(MouseEvent e) + { + + } + + + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/AbstractSecureUmlComponent.java b/src/ch/ethz/infsec/secureumlgui/gui/AbstractSecureUmlComponent.java new file mode 100644 index 0000000..dffb2dc --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/AbstractSecureUmlComponent.java @@ -0,0 +1,83 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.gui; + +import java.awt.Color; +import java.awt.BorderLayout; +import java.awt.LayoutManager; + +import javax.swing.JPanel; +import javax.swing.border.Border; +import javax.swing.border.CompoundBorder; +import javax.swing.border.EmptyBorder; +import javax.swing.border.LineBorder; +import javax.swing.border.TitledBorder; + +import org.openide.util.datatransfer.ExTransferable.Multi; + +import ch.ethz.infsec.secureumlgui.Util; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.MetaModelEntity; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ResourceType; +import ch.ethz.infsec.secureumlgui.wrapper.PermissionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.ResourceWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.RoleWrapper; + + +/** + * Abstract base class for all SecureUML properties components to be + * displayed in the Details Pane. + * + * Holds stuff that is common to all SecureUml components, but + * independent of the type of the resource that is displayed. + * + * {@link ch.ethz.infsec.secureumlgui.TabSecureUml} displays instances + * of this class based on the selected model element. + * + * + */ +public abstract class AbstractSecureUmlComponent + extends JPanel +{ + /** + * + */ + public AbstractSecureUmlComponent() + { + this.setLayout(new BorderLayout()); + } + + public void setDisplayedSecureUmlElement( + Object suElement, ResourceType rt) + { + + } + + /** + * + */ + private void initLayout() + { + } + + // public AbstractSecureUmlComponent(String titl) + // { + // initLayout(); + // //initBorder(); + // //setTitle(title); + // } + + + MultiContextLogger logger = new MultiContextLogger( + MultiContextLogger.GUI); + + + LayoutManager defaultLayout; + + // public LayoutManager getDefaultLayout() + // { + // return defaultLayout; + // } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/ActionNameTableCellRenderer.java b/src/ch/ethz/infsec/secureumlgui/gui/ActionNameTableCellRenderer.java new file mode 100644 index 0000000..3197020 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/ActionNameTableCellRenderer.java @@ -0,0 +1,151 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.gui; + +import java.awt.Component; +import java.util.Collection; +import java.util.EventObject; +import java.util.Iterator; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.JToolTip; +import javax.swing.event.CellEditorListener; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableCellRenderer; + +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.modelmapping.GenericDialectHelper; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ActionType; +import ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper; + +/** + * + */ +public class ActionNameTableCellRenderer extends Object + implements TableCellRenderer, TableCellEditor +{ + /** + * + */ + public ActionNameTableCellRenderer() + { + + } + + MultiContextLogger logger = MultiContextLogger.getDefault(); + + + /* (non-Javadoc) + * @see javax.swing.table.TableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int) + */ + public Component getTableCellRendererComponent( + JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) + { +// logger.info("executing " + +// "ActionNameTableCellRenderer.getTableCellRendererComponent(" +// + value + ")"); + + if (value instanceof ActionWrapper) + { + ActionWrapper actionWrapper = (ActionWrapper) value; + + ActionNameTableCellRendererComponent container = + new ActionNameTableCellRendererComponent( + actionWrapper); + + return container; + } + else + return new JTextField("error"); + + } + + /* (non-Javadoc) + * @see javax.swing.CellEditor#isCellEditable(java.util.EventObject) + */ + public boolean isCellEditable(EventObject anEvent) + { + return false; + } + + /* (non-Javadoc) + * @see javax.swing.CellEditor#addCellEditorListener(javax.swing.event.CellEditorListener) + */ + public void addCellEditorListener(CellEditorListener l) + { + // TODO Auto-generated method stub + + + } + + /* (non-Javadoc) + * @see javax.swing.CellEditor#cancelCellEditing() + */ + public void cancelCellEditing() + { + // TODO Auto-generated method stub + + + } + + /* (non-Javadoc) + * @see javax.swing.CellEditor#getCellEditorValue() + */ + public Object getCellEditorValue() + { + // TODO Auto-generated method stub + return null; + + + } + + /* (non-Javadoc) + * @see javax.swing.table.TableCellEditor#getTableCellEditorComponent(javax.swing.JTable, java.lang.Object, boolean, int, int) + */ + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) + { + return getTableCellRendererComponent( + table, value, isSelected, false, row, column); + + } + + /* (non-Javadoc) + * @see javax.swing.CellEditor#removeCellEditorListener(javax.swing.event.CellEditorListener) + */ + public void removeCellEditorListener(CellEditorListener l) + { + // TODO Auto-generated method stub + + + } + + /* (non-Javadoc) + * @see javax.swing.CellEditor#shouldSelectCell(java.util.EventObject) + */ + public boolean shouldSelectCell(EventObject anEvent) + { + // TODO Auto-generated method stub + return false; + + + } + + /* (non-Javadoc) + * @see javax.swing.CellEditor#stopCellEditing() + */ + public boolean stopCellEditing() + { + // TODO Auto-generated method stub + return false; + + + } + + + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/ActionNameTableCellRendererComponent.java b/src/ch/ethz/infsec/secureumlgui/gui/ActionNameTableCellRendererComponent.java new file mode 100644 index 0000000..10014cf --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/ActionNameTableCellRendererComponent.java @@ -0,0 +1,126 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.gui; + +import java.util.Collection; +import java.util.Iterator; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JToolTip; + +import ch.ethz.infsec.secureumlgui.modelmapping.GenericDialectHelper; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ActionType; +import ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper; + +/** + * + */ +public class ActionNameTableCellRendererComponent extends JPanel +{ + /** + * + */ + public ActionNameTableCellRendererComponent(ActionWrapper actionWrapper) + { + + + JLabel lbActionName = + new JLabel(actionWrapper.getName()); + add(lbActionName); + + String tooltip = ""; + //txActionName.setToolTipText();//"Action Composition Info..." + + ActionType at = GenericDialectHelper.getInstance(). + getActionType(actionWrapper.getModelElement()); + + if(at == null) + { + tooltip = "couldn't determine actiontype"; + } + else if(at.getSubactionsDefinition() == null + || at.getSubactionsDefinition().length() == 0) + { + tooltip = "Atomic Action"; + } + else + { + tooltip = "Composite Action";// (" + // + at.getSubactionsDefinition() + ")"; + + Collection subactions = + actionWrapper.getSubActionWrappers(); + + if(subactions.size() == 0) + { + //tooltip += "with no Subactions"; + } + else + { + if(subactions.size() == 1) + tooltip += "\n - Subaction ("; + else + tooltip += "\n - Subactions ("; + + for (Iterator iter = subactions.iterator(); iter.hasNext();) + { + ActionWrapper aw = (ActionWrapper) iter.next(); + + tooltip += //"\n" + + aw.getResourceWrapper().getResourcePath() + + "." +aw.getName(); + + if(iter.hasNext()) + tooltip += ", "; + } + tooltip += ")"; + } + } + + Collection superactions = + actionWrapper.getSuperActionWrappers(); + + if(superactions.size() == 0) + { + //tooltip += "with no Superactions"; + } + else + { + if(superactions.size() == 1) + tooltip += "\n - Superaction ("; + else + tooltip += "\n - Superactions ("; + + for (Iterator iter = superactions.iterator(); iter.hasNext();) + { + ActionWrapper aw = (ActionWrapper) iter.next(); + + tooltip += //"\n" + + aw.getResourceWrapper().getResourcePath() + + "." +aw.getName(); + + if(iter.hasNext()) + tooltip += ", "; + } + tooltip += ")"; + } + + +// logger.info("set action tooltip: " + tooltip); +// + setToolTipText(tooltip); + + //return txActionName; + + } + + @Override + public JToolTip createToolTip() { + MultiLineToolTip tip = new MultiLineToolTip(); + + tip.setComponent(this); + return tip; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/ActionPermissionTableCellEditor.java b/src/ch/ethz/infsec/secureumlgui/gui/ActionPermissionTableCellEditor.java new file mode 100644 index 0000000..a53e038 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/ActionPermissionTableCellEditor.java @@ -0,0 +1,26 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.gui; + +import javax.swing.DefaultCellEditor; +import javax.swing.JCheckBox; +import javax.swing.table.TableCellEditor; + +/** + * + */ +public class ActionPermissionTableCellEditor + //extends DefaultCellEditor + //implements TableCellEditor +{ + /** + * + */ + public ActionPermissionTableCellEditor() + { + + } + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/ActionPermissionTableCellListener.java b/src/ch/ethz/infsec/secureumlgui/gui/ActionPermissionTableCellListener.java new file mode 100644 index 0000000..8c7d171 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/ActionPermissionTableCellListener.java @@ -0,0 +1,83 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.gui; + +import javax.swing.JCheckBox; + +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; + +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener;; + +/** + * + */ +public class ActionPermissionTableCellListener + implements MouseListener +{ + /** + * + */ + public ActionPermissionTableCellListener(JCheckBox editorCheckbox) + { + this.editorCheckbox = editorCheckbox; + } + + MultiContextLogger logger = + MultiContextLogger.getDefault(); + + JCheckBox editorCheckbox; + + /* (non-Javadoc) + * @see java.awt.event.MouseListener#mouseClicked(java.awt.event.MouseEvent) + */ + public void mouseClicked(MouseEvent e) + { + editorCheckbox.doClick(); + + logger.info("mouse clicked"); + } + + /* (non-Javadoc) + * @see java.awt.event.MouseListener#mouseEntered(java.awt.event.MouseEvent) + */ + public void mouseEntered(MouseEvent e) + { + // TODO Auto-generated method stub + + + } + + /* (non-Javadoc) + * @see java.awt.event.MouseListener#mouseExited(java.awt.event.MouseEvent) + */ + public void mouseExited(MouseEvent e) + { + // TODO Auto-generated method stub + + + } + + /* (non-Javadoc) + * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent) + */ + public void mousePressed(MouseEvent e) + { + logger.info("mouse Pressed"); + + } + + /* (non-Javadoc) + * @see java.awt.event.MouseListener#mouseReleased(java.awt.event.MouseEvent) + */ + public void mouseReleased(MouseEvent e) + { + // TODO Auto-generated method stub + + + } + + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/ActionPermissionTableCellRenderer.java b/src/ch/ethz/infsec/secureumlgui/gui/ActionPermissionTableCellRenderer.java new file mode 100644 index 0000000..645bb15 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/ActionPermissionTableCellRenderer.java @@ -0,0 +1,174 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.gui; + +import java.awt.Component; +import java.util.EventObject; + +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.event.CellEditorListener; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableCellRenderer; + +import org.omg.uml.foundation.core.UmlClass; + +import ch.ethz.infsec.secureumlgui.ModuleController; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.ActionPermissionSet; +import ch.ethz.infsec.secureumlgui.wrapper.PolicyWrapper; + +/** + * + */ +public class ActionPermissionTableCellRenderer + implements TableCellEditor, + TableCellRenderer +{ + + //private PolicyWrapper currentPolicy; + private UmlClass currentPolicy; + /** + * + */ +// public ActionPermissionTableCellRenderer(PolicyWrapper currentPolicy) { +// this.currentPolicy = currentPolicy; +// } + public ActionPermissionTableCellRenderer(UmlClass currentPolicy) { + this.currentPolicy = currentPolicy; + } + + MultiContextLogger logger = + MultiContextLogger.getDefault(); + +// static int globalN = 0; +// int n; + + ActionPermissionsTableCellRendererComponent + container = null; + + /* (non-Javadoc) + * @see javax.swing.table.TableCellRenderer#getTableCellRendererComponent(javax.swing.JTable, java.lang.Object, boolean, boolean, int, int) + */ + public Component getTableCellRendererComponent( + JTable table, Object value, + boolean isSelected, boolean hasFocus, + int row, int column) + { + + + if (value instanceof ActionPermissionSet) + { + ActionPermissionSet actionPermissions = + (ActionPermissionSet) value; + + container = new + ActionPermissionsTableCellRendererComponent( + actionPermissions, new PolicyWrapper(ModuleController.getInstance().getModelMap().getElement(currentPolicy))); + + return container; + + + } + else + return new JLabel("error"); + + } + + + /* (non-Javadoc) + * @see javax.swing.DefaultCellEditor#getTableCellEditorComponent(javax.swing.JTable, java.lang.Object, boolean, int, int) + */ + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) + { + // TODO Auto-generated method stub + //return super.getTableCellEditorComponent(table, value, isSelected, row, column); + + return getTableCellRendererComponent( + table, value, + isSelected, false, + row, column); + } + + /* (non-Javadoc) + * @see javax.swing.CellEditor#addCellEditorListener(javax.swing.event.CellEditorListener) + */ + public void addCellEditorListener(CellEditorListener l) + { + // TODO Auto-generated method stub + + + } + + /* (non-Javadoc) + * @see javax.swing.CellEditor#cancelCellEditing() + */ + public void cancelCellEditing() + { + // TODO Auto-generated method stub + } + + /* (non-Javadoc) + * @see javax.swing.CellEditor#getCellEditorValue() + */ + public Object getCellEditorValue() + { + if(container.getCbExplicitPermission().hasFocus()) + return !(container.getCbExplicitPermission().isSelected()); + else + return container.getCbExplicitPermission().isSelected(); + +// if(cbExplicitPermission.hasFocus()) +// return !(cbExplicitPermission.isSelected()); +// else +// return cbExplicitPermission.isSelected(); + // TODO Auto-generated method stub + + //return null; + + + } + + /* (non-Javadoc) + * @see javax.swing.CellEditor#isCellEditable(java.util.EventObject) + */ + public boolean isCellEditable(EventObject anEvent) + { + // TODO Auto-generated method stub + return true; + + + } + + /* (non-Javadoc) + * @see javax.swing.CellEditor#removeCellEditorListener(javax.swing.event.CellEditorListener) + */ + public void removeCellEditorListener(CellEditorListener l) + { + // TODO Auto-generated method stub + + } + + /* (non-Javadoc) + * @see javax.swing.CellEditor#shouldSelectCell(java.util.EventObject) + */ + public boolean shouldSelectCell(EventObject anEvent) + { + // TODO Auto-generated method stub + return true; + } + + /* (non-Javadoc) + * @see javax.swing.CellEditor#stopCellEditing() + */ + public boolean stopCellEditing() + { + //return cbExplicitPermission.hasFocus(); + // TODO Auto-generated method stub + return true; + } + + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/ActionPermissionTableCellSelectionListener.java b/src/ch/ethz/infsec/secureumlgui/gui/ActionPermissionTableCellSelectionListener.java new file mode 100644 index 0000000..7a8d37e --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/ActionPermissionTableCellSelectionListener.java @@ -0,0 +1,37 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.gui; + +import javax.swing.ListSelectionModel; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; + +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; + +/** + * + */ +public class ActionPermissionTableCellSelectionListener + implements ListSelectionListener +{ + MultiContextLogger logger = MultiContextLogger.getDefault(); + + /* (non-Javadoc) + * @see javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event.ListSelectionEvent) + */ + public void valueChanged(ListSelectionEvent e) + { + logger.info("value changed " + e.getSource()); + ListSelectionModel lsm = + (ListSelectionModel)e.getSource(); + + if (!lsm.isSelectionEmpty()) + { + int selectedCol = lsm.getMinSelectionIndex(); + + + } + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/ActionPermissionsTableCellRendererComponent.java b/src/ch/ethz/infsec/secureumlgui/gui/ActionPermissionsTableCellRendererComponent.java new file mode 100644 index 0000000..dca5298 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/ActionPermissionsTableCellRendererComponent.java @@ -0,0 +1,335 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.gui; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +import javax.swing.ImageIcon; +import javax.swing.JCheckBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JToolTip; + +import org.apache.log4j.Logger; +import org.omg.uml.foundation.core.AssociationEnd; +import org.omg.uml.foundation.core.UmlClass; + +import ch.ethz.infsec.secureumlgui.ModuleController; +import ch.ethz.infsec.secureumlgui.ResourceFilesManager; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.ActionPermissionSet; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.PermissionValue; +import ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PermissionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PolicyWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.RoleWrapper; + +/** + * + */ +public class ActionPermissionsTableCellRendererComponent + extends JPanel + implements ActionListener +{ + + /** + * + */ + private static final long serialVersionUID = 1L; + + private PolicyWrapper policy; + //private UmlClass policy; + + + private static Logger aLog = Logger.getLogger(ActionPermissionsTableCellRendererComponent.class); + /** + * + */ + public ActionPermissionsTableCellRendererComponent( + ActionPermissionSet actionPermissions, PolicyWrapper policy) + { + // + this.actionPermissions = actionPermissions; + this.policy = policy; + + this.add(cbExplicitPermission); + + initIconLabels(); + + + + //this.add(lbOtherPermissions); + +// container.addMouseListener( +// new ActionPermissionTableCellListener( +// cbExplicitPermission)); + +// cbExplicitPermission.addMouseListener( +// new ActionPermissionTableCellListener( +// cbExplicitPermission)); + processPermissions(actionPermissions); + + cbExplicitPermission.addActionListener(this); + +// lbOtherPermissions.setText( +// actionPermissions.toString()); + +// this.setToolTipText( +// "Description of the origin of all permissions"); +// + } + + + + static ResourceFilesManager resourceFilesManager = + new ResourceFilesManager(); + + + ActionPermissionSet actionPermissions = null; + + MultiContextLogger logger = + MultiContextLogger.getDefault(); + + JCheckBox cbExplicitPermission = new JCheckBox(); + + + //JLabel lbOtherPermissions = new JLabel(); + JLabel lbConstrained = new JLabel(); + JLabel lbImplicit = new JLabel(); + JLabel lbImplicitConstrained = new JLabel(); + JLabel lbInheritedRole = new JLabel(); + JLabel lbInheritedPolicy = new JLabel(); + JLabel lbInheritedConstrained = new JLabel(); + JLabel lbCompositeFull = new JLabel(); + JLabel lbCompositeFullConstrained = new JLabel(); + JLabel lbImplicitByComposite = new JLabel(); + + + //PermissionValue explicitPermissionValue = null; + + + protected void initIconLabels() + { + + lbConstrained.setIcon(resourceFilesManager.getConstrainedIcon()); + lbInheritedRole.setIcon(resourceFilesManager.getInheritedRoleIcon()); + lbInheritedPolicy.setIcon(resourceFilesManager.getInheritedPolicyIcon()); + lbInheritedConstrained.setIcon(resourceFilesManager.getConstrainedIcon()); + lbImplicit.setIcon(resourceFilesManager.getImplicitIcon()); + lbImplicitConstrained.setIcon(resourceFilesManager.getConstrainedIcon()); + lbCompositeFull.setIcon(resourceFilesManager.getCompositeFullIcon()); + lbCompositeFullConstrained.setIcon(resourceFilesManager.getConstrainedIcon()); + lbImplicitByComposite.setIcon(resourceFilesManager.getImplicitByInheritedIcon()); + + this.add(lbConstrained); + this.add(lbInheritedRole); + this.add(lbInheritedPolicy); + this.add(lbInheritedConstrained); + this.add(lbImplicit); + this.add(lbImplicitConstrained); + this.add(lbCompositeFull); + this.add(lbCompositeFullConstrained); + this.add(lbImplicitByComposite); + + } + + /** + * @param actionPermissions + */ + private void processPermissions(ActionPermissionSet actionPermissions) + { + cbExplicitPermission.setSelected(actionPermissions.isExplicitPermitted(policy)); + // XXX +// explicitPermissionValue = +// actionPermissions.getExplicitPermission(); +// +// cbExplicitPermission.setSelected( +// actionPermissions.getExplicitPermission(). +// getValue() == +// PermissionValue.GRANTED.getValue()); + + // first set all icons invisible + lbConstrained.setVisible(false); + lbInheritedRole.setVisible(false); + lbInheritedPolicy.setVisible(false); + lbInheritedConstrained.setVisible(false); + lbImplicit.setVisible(false); + lbImplicitConstrained.setVisible(false); + lbCompositeFull.setVisible(false); + lbCompositeFullConstrained.setVisible(false); + lbImplicitByComposite.setVisible(false); + + String tooltip = ""; + + // and then show the ones for the defined permissions + for (Iterator iter = actionPermissions.getPermissions(policy).iterator(); iter.hasNext();) + { + PermissionValue pv = (PermissionValue) iter.next(); + + tooltip += pv.getDescription() + " *** \n"; + + int flags = pv.getFlags(); + + aLog.debug("permission (0x" + Integer.toHexString(flags) + ") " + pv.getPermissionWrapper().getName()); + + if ( ( flags & PermissionValue.INT_GRANTED & PermissionValue.INT_CONSTRAINED) > 0 ) { + if(pv.isConstrained()) + lbConstrained.setVisible(true); + } + + if ( (flags & PermissionValue.INT_INHERITED_POLICY ) > 0) { + //ignore all types from super polices + lbInheritedPolicy.setVisible(true); + } else { + if ( (flags & PermissionValue.INT_INHERITED) > 0 ) { + lbInheritedRole.setVisible(true); + if ( (flags & PermissionValue.INT_CONSTRAINED) > 0 ) { + lbInheritedConstrained.setVisible(true); + } + } + + + if ( (flags & (PermissionValue.INT_IMPLICIT | PermissionValue.INT_COMPOSITE) ) > 0 ) { + lbImplicitByComposite.setVisible(true); + } + else { + if ( (flags & PermissionValue.INT_IMPLICIT) > 0 ) { + lbImplicit.setVisible(true); + if ( (flags & PermissionValue.INT_CONSTRAINED) > 0 ) { + lbImplicitConstrained.setVisible(true); + } + } + + if ( (flags & PermissionValue.INT_COMPOSITE) > 0 ) { + lbCompositeFull.setVisible(true); + if ( (flags & PermissionValue.INT_CONSTRAINED) > 0 ) { + lbCompositeFullConstrained.setVisible(true); + } + } + } + } + + + +// int value = pv.getValue(); +// +// if(value == pv.GRANTED.getValue()) +// { +// // this is the explicit permission +// // -> checkbox is displayed and initialized already +// if(pv.isConstrained()) +// lbConstrained.setVisible(true); +// } +// else if(value == pv.DENIED.getValue()) +// { +// // denied permission =^= no permission +// // do nothing +// } +// else if(value == pv.INHERITED.getValue()) +// { +// lbInherited.setVisible(true); +// if(pv.isConstrained()) +// lbInheritedConstrained.setVisible(true); +// } +// else if(value == pv.IMPLICIT.getValue()) +// { +// lbImplicit.setVisible(true); +// if(pv.isConstrained()) +// lbImplicitConstrained.setVisible(true); +// } +// else if(value == pv.COMPOSITE.getValue()) +// { +// lbCompositeFull.setVisible(true); +// if(pv.isConstrained()) +// lbCompositeFullConstrained.setVisible(true); +// } +// else +// { +// aLog.warn("unhandled permission value: " + pv); +// logger.error( +// "unhandled permission value: " + pv); +// } + } + + this.setToolTipText(tooltip); + } + + /** + * @return the cbExplicitPermission + */ + public JCheckBox getCbExplicitPermission() + { + return cbExplicitPermission; + } + + + /* (non-Javadoc) + * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) + */ + public void actionPerformed(ActionEvent e) + { +// PermissionWrapper pw = +// explicitPermissionValue.getPermissionWrapper(); +// +// logger.info("Editing a Permission, old PermissionValue: " +// + explicitPermissionValue + "\n"); + +// if(pw == null) +// { +// logger.error("PermissionWrapper == null"); +// } +// else +// { +// logger.info("Action: " +// + pw.getActionWrapper().getName() +// + ", Role: " +// + pw.getRoleWrapper().getName()); + +// } + + logger.info("Action: " + + actionPermissions.getExplicitActionWrapper() + + ", Role: " + + actionPermissions.getExplicitRoleWrapper()); + + + PermissionWrapper pw = actionPermissions.getExplicitPermittedPermission(policy); + //explicitPermissionValue.getPermissionWrapper(); + if(pw == null) + { + logger.info("creating permission..."); + + Set policies = new HashSet(); + policies.add(policy); + + logger.info("existing permissions: "+actionPermissions); + ModuleController.getInstance().addPermission( + actionPermissions.getExplicitActionWrapper(), + actionPermissions.getExplicitRoleWrapper(), + policies); + } + else + { + logger.info("deleting permission..."); + + ModuleController.getInstance().deletePermission( + pw); + } + + } + + @Override + public JToolTip createToolTip() { + MultiLineToolTip tip = new MultiLineToolTip(); + tip.setComponent(this); + return tip; + } + + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/GenericResourcePermissionsTableModel.java b/src/ch/ethz/infsec/secureumlgui/gui/GenericResourcePermissionsTableModel.java new file mode 100644 index 0000000..fa4c419 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/GenericResourcePermissionsTableModel.java @@ -0,0 +1,227 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.gui; + +import java.util.Collection; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.omg.uml.foundation.core.ModelElement; + +import ch.ethz.infsec.secureumlgui.modelmapping.GenericDialectHelper; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.ActionPermissionSet; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.HierarchicalPermissionsExplorer; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.HierarchicalPolicyExplorer; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.PermissionSet; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.PermissionValue; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.ResourcePermissionsSet; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.DialectMetaModelInfo; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ResourceType; +import ch.ethz.infsec.secureumlgui.transformation.ModelMap; +import ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PermissionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PolicyWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.ResourceWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.RoleWrapper; + +/** + * Swing table model for the permission table displayed in the + * SecureUML properties tab for resources. + * Columns are roles, rows are actions on the resource. + * + */ +public class GenericResourcePermissionsTableModel extends AbstractPermissionsTableModel +{ + private static final long serialVersionUID = 1L; + + ResourceWrapper resourceWrapper; + PermissionSet permissions = new PermissionSet(); + Collection actionWrappers; + private static Logger aLog = Logger.getLogger(GenericResourcePermissionsTableModel.class); + + + public GenericResourcePermissionsTableModel( + ResourceWrapper resourceWrapper) + { + super(resourceWrapper.getModelElement()); + + setResource(resourceWrapper); + } + + + /** + * @param resourceWrapper + */ + protected void setResource(ResourceWrapper resourceWrapper) + { + super.setResource(resourceWrapper); + + this.resourceWrapper = resourceWrapper; + + initActionPermissionSets(); + + // init +// TODO realy needed???? +// Object suModelElement = resourceWrapper.getModelElement(); +// ModelElement umlModelElement = (ModelElement) ModelMap.getDefault().getUmlElement(suModelElement); +// ResourceType rt = GenericDialectHelper.getInstance().getResourceType(umlModelElement); +// DialectMetaModelInfo mmInfo = GenericDialectHelper.getInstance().getDialectMetaModelInfo(); + + actionWrappers = resourceWrapper.getActionWrapper(); + + initExplicitPermissions(resourceWrapper); + + HierarchicalPermissionsExplorer permissionsExplorer = new HierarchicalPermissionsExplorer(); + + permissionsExplorer.collectNonExplicitPermissions(resourceWrapper, permissions); + } + + + /** + * creates the objects that will be filled with explicit and interhited/implicit permissions + * + */ + protected void initActionPermissionSets() { + for (RoleWrapper role : roleWrappers) { + ResourcePermissionsSet resourcePermissions = permissions.getResourcePermissionsSet(role); + + for (ActionWrapper action : resourceWrapper.getActionWrapper()) { + ActionPermissionSet actionPermissions = resourcePermissions.getPermissions(action); + + actionPermissions.setExplicitRoleWrapper(role); + actionPermissions.setExplicitActionWrapper(action); + + + } + } + } + + + private void initExplicitPermissions(ResourceWrapper resource) { + + PolicyWrapper defaultPolicy = HierarchicalPolicyExplorer.getInstance().getDefaultPolicyWrapper(); + + for (ActionWrapper action : resource.getActionWrapper()) { + for (PermissionWrapper permission : action.getPermissionWrappers()) { + RoleWrapper role = permission.getRoleWrapper(); + + if(role != null) { + Set policies = permission.getPolicyWrappers(); + + PolicyWrapper policy = null; + + if (policies != null || policies.size() > 0) { + policy = policies.iterator().next(); + + if (policies.size() > 1 ) { + aLog.error("ignoring all policies except first one.. TODO"); + } + + } + + aLog.debug("policy: " + (policies == null ? "NULL" : policy.getModelElement())); + +// permissions.getResourcePermissionsSet(role).addPermission( +// action, PermissionValue.create(PermissionValue.GRANTED, permission)); + + if ( policy == null ) { + policy = defaultPolicy; + } + + //policy = defaultPolicy; + + aLog.debug("G: add explicit permission: " + role.getName() + " on " + action.getName() + " on policy " + (policy == null ? "NULL" : policy.getName())); + + permissions.getResourcePermissionsSet(role).addPermission( + action, PermissionValue.createGranted(permission), policy); + + + permissions.getResourcePermissionsSet(role).getPermissions(action). + addExplicitPermission(policy, PermissionValue.createGranted(permission)); + + + +// if ( defaultPolicy == null ) { +// permissions.getResourcePermissionsSet(role).getPermissions(action). +// addDefaultPermission(PermissionValue.createGranted(permission)); +// } else { +//// permissions.getResourcePermissionsSet(role).getActionPermissionSet(action). +//// addPermission(policy, PermissionValue.createGranted(permission)); +// } + + ResourcePermissionsSet rps = permissions.getResourcePermissionsSet( + new RoleWrapper(role.getModelElement())); + + //hel ActionPermissionSet aps = rps.getPermissions(actionName); + ActionPermissionSet aps = rps.getPermissions(action.getName()); + + aps.setExplicitRoleWrapper(role); +// logger.info("Test: fetch the added Permission: " + aps.getFlatPermission()); + } + else { + aLog.warn("Permission without role"); + } + } + } + } + + + + + /* (non-Javadoc) + * @see javax.swing.table.TableModel#getRowCount() + */ + public int getRowCount() + { + return actionWrappers.size(); + } + + /* (non-Javadoc) + * @see javax.swing.table.TableModel#getValueAt(int, int) + */ + public Object getValueAt(int row, int col) + { + ActionWrapper aw = (ActionWrapper) actionWrappers.toArray()[row]; + + if(col == 0) { + String actionName = aw.getName(); + return aw; + } + else { // other columns - i.e. return ROLEs and the assigned permissions + RoleWrapper roleWrapper = roleWrappers.get(col-1); + + ResourcePermissionsSet resourcePermissions = + permissions.getResourcePermissionsSet(roleWrapper); + + ActionPermissionSet actionPermissions = + resourcePermissions.getPermissions(aw.getName()); + + return actionPermissions; + } + } + + + /* (non-Javadoc) + * @see ch.ethz.infsec.secureumlgui.gui.AbstractPermissionsTableModel#isCellEditable(int, int) + */ + @Override + public boolean isCellEditable(int row, int col) { + if(col == 0) + return false; + else + return true; + } + + /* (non-Javadoc) + * @see ch.ethz.infsec.secureumlgui.gui.AbstractPermissionsTableModel#getColumnClass(int) + */ + @Override + public Class getColumnClass(int columnIndex) + { + if(columnIndex == 0) + return ActionWrapper.class; + else + return ActionPermissionSet.class; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/JTristateCheckBox.java b/src/ch/ethz/infsec/secureumlgui/gui/JTristateCheckBox.java new file mode 100644 index 0000000..dd857d4 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/JTristateCheckBox.java @@ -0,0 +1,227 @@ +package ch.ethz.infsec.secureumlgui.gui; + +import javax.swing.*; +import javax.swing.event.ChangeListener; +import javax.swing.plaf.ActionMapUIResource; +import java.awt.event.*; + +/** + * 2003-12-02 The Java Specialists' Newsletter [Issue 082] + * TristateCheckBox based on the Swing JCheckBox + * Author: Dr. Heinz M. Kabutz * + * from http://www.javaspecialists.co.za/archive/Issue082.html + * + * Maintenance tip - There were some tricks to getting this code + * working: + * + * 1. You have to overwite addMouseListener() to do nothing + * 2. You have to add a mouse event on mousePressed by calling + * super.addMouseListener() + * 3. You have to replace the UIActionMap for the keyboard event + * "pressed" with your own one. + * 4. You have to remove the UIActionMap for the keyboard event + * "released". + * 5. You have to grab focus when the next state is entered, + * otherwise clicking on the component won't get the focus. + * 6. You have to make a TristateDecorator as a button model that + * wraps the original button model and does state management. + */ +public class JTristateCheckBox extends JCheckBox +{ + /** This is a type-safe enumerated type */ + public static class State { + private State() { } + } + public static final State NOT_SELECTED = new State(); + public static final State SELECTED = new State(); + public static final State DONT_CARE = new State(); + + private final TristateDecorator model; + + public JTristateCheckBox(String text, Icon icon, State initial) + { + super(text, icon); + // Add a listener for when the mouse is pressed + super.addMouseListener(new MouseAdapter() { + public void mousePressed(MouseEvent e) { + grabFocus(); + model.nextState(); + } + }); + // Reset the keyboard action map + ActionMap map = new ActionMapUIResource(); + map.put("pressed", new AbstractAction() { + public void actionPerformed(ActionEvent e) { + grabFocus(); + model.nextState(); + } + }); + map.put("released", null); + SwingUtilities.replaceUIActionMap(this, map); + // set the model to the adapted model + model = new TristateDecorator(getModel()); + setModel(model); + setState(initial); + } + public JTristateCheckBox(String text, State initial) { + this(text, null, initial); + } + public JTristateCheckBox(String text) { + this(text, DONT_CARE); + } + public JTristateCheckBox() { + this(null); + } + + /** No one may add mouse listeners, not even Swing! */ + public void addMouseListener(MouseListener l) { } + /** + * Set the new state to either SELECTED, NOT_SELECTED or + * DONT_CARE. If state == null, it is treated as DONT_CARE. + */ + public void setState(State state) { + model.setState(state); + } + /** Return the current state, which is determined by the + * selection status of the model. */ + public State getState() { + return model.getState(); + } + public void setSelected(boolean b) { + if (b) { + setState(SELECTED); + } else { + setState(NOT_SELECTED); + } + } + /** + * Exactly which Design Pattern is this? Is it an Adapter, + * a Proxy or a Decorator? In this case, my vote lies with the + * Decorator, because we are extending functionality and + * "decorating" the original model with a more powerful model. + */ + private class TristateDecorator implements ButtonModel { + private final ButtonModel other; + private TristateDecorator(ButtonModel other) { + this.other = other; + } + private void setState(State state) { + if (state == NOT_SELECTED) { + other.setArmed(false); + setPressed(false); + setSelected(false); + } else if (state == SELECTED) { + other.setArmed(false); + setPressed(false); + setSelected(true); + } else { // either "null" or DONT_CARE + other.setArmed(true); + setPressed(true); + setSelected(true); + } + } + /** + * The current state is embedded in the selection / armed + * state of the model. + * + * We return the SELECTED state when the checkbox is selected + * but not armed, DONT_CARE state when the checkbox is + * selected and armed (grey) and NOT_SELECTED when the + * checkbox is deselected. + */ + private State getState() { + if (isSelected() && !isArmed()) { + // normal black tick + return SELECTED; + } else if (isSelected() && isArmed()) { + // don't care grey tick + return DONT_CARE; + } else { + // normal deselected + return NOT_SELECTED; + } + } + /** We rotate between NOT_SELECTED, SELECTED and DONT_CARE.*/ + private void nextState() { + State current = getState(); + if (current == NOT_SELECTED) { + setState(SELECTED); + } else if (current == SELECTED) { + setState(DONT_CARE); + } else if (current == DONT_CARE) { + setState(NOT_SELECTED); + } + } + /** Filter: No one may change the armed status except us. */ + public void setArmed(boolean b) { + } + /** We disable focusing on the component when it is not + * enabled. */ + public void setEnabled(boolean b) { + setFocusable(b); + other.setEnabled(b); + } + /** All these methods simply delegate to the "other" model + * that is being decorated. */ + public boolean isArmed() { + return other.isArmed(); + } + public boolean isSelected() { + return other.isSelected(); + } + public boolean isEnabled() { + return other.isEnabled(); + } + public boolean isPressed() { + return other.isPressed(); + } + public boolean isRollover() { + return other.isRollover(); + } + public void setSelected(boolean b) { + other.setSelected(b); + } + public void setPressed(boolean b) { + other.setPressed(b); + } + public void setRollover(boolean b) { + other.setRollover(b); + } + public void setMnemonic(int key) { + other.setMnemonic(key); + } + public int getMnemonic() { + return other.getMnemonic(); + } + public void setActionCommand(String s) { + other.setActionCommand(s); + } + public String getActionCommand() { + return other.getActionCommand(); + } + public void setGroup(ButtonGroup group) { + other.setGroup(group); + } + public void addActionListener(ActionListener l) { + other.addActionListener(l); + } + public void removeActionListener(ActionListener l) { + other.removeActionListener(l); + } + public void addItemListener(ItemListener l) { + other.addItemListener(l); + } + public void removeItemListener(ItemListener l) { + other.removeItemListener(l); + } + public void addChangeListener(ChangeListener l) { + other.addChangeListener(l); + } + public void removeChangeListener(ChangeListener l) { + other.removeChangeListener(l); + } + public Object[] getSelectedObjects() { + return other.getSelectedObjects(); + } + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/MultiLineToolTip.java b/src/ch/ethz/infsec/secureumlgui/gui/MultiLineToolTip.java new file mode 100644 index 0000000..af9d471 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/MultiLineToolTip.java @@ -0,0 +1,63 @@ +/** + * http://www.codeguru.com/java/articles/122.shtml + * + * Author: Zafir Anjum + */ +package ch.ethz.infsec.secureumlgui.gui; + +import javax.swing.*; +import javax.swing.plaf.*; + +import java.awt.*; +import java.awt.font.*; +import java.awt.event.*; +import javax.swing.plaf.*; +import javax.swing.plaf.basic.BasicToolTipUI; +import javax.swing.text.*; + + +/** + * @author Zafir Anjum + */ + + +public class MultiLineToolTip extends JToolTip +{ + private static final String uiClassID = "ToolTipUI"; + + String tipText; + JComponent component; + + public MultiLineToolTip() { + updateUI(); + } + + public void updateUI() { + setUI(MultiLineToolTipUI.createUI(this)); + } + + public void setColumns(int columns) + { + this.columns = columns; + this.fixedwidth = 0; + } + + public int getColumns() + { + return columns; + } + + public void setFixedWidth(int width) + { + this.fixedwidth = width; + this.columns = 0; + } + + public int getFixedWidth() + { + return fixedwidth; + } + + protected int columns = 20; + protected int fixedwidth = 20; +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/MultiLineToolTipUI.java b/src/ch/ethz/infsec/secureumlgui/gui/MultiLineToolTipUI.java new file mode 100644 index 0000000..59c28e1 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/MultiLineToolTipUI.java @@ -0,0 +1,101 @@ +/** + * http://www.codeguru.com/java/articles/122.shtml + * + * Author: Zafir Anjum + */ +package ch.ethz.infsec.secureumlgui.gui; + + +import javax.swing.*; +import javax.swing.plaf.*; + +import java.awt.*; +import java.awt.font.*; +import java.awt.event.*; +import javax.swing.plaf.*; +import javax.swing.plaf.basic.BasicToolTipUI; +import javax.swing.text.*; + + +class MultiLineToolTipUI extends BasicToolTipUI { + static MultiLineToolTipUI sharedInstance = new MultiLineToolTipUI(); + Font smallFont; + static JToolTip tip; + protected CellRendererPane rendererPane; + + private static JTextArea textArea ; + + public static ComponentUI createUI(JComponent c) { + return sharedInstance; + } + + public MultiLineToolTipUI() { + super(); + } + + public void installUI(JComponent c) { + super.installUI(c); + tip = (JToolTip)c; + rendererPane = new CellRendererPane(); + c.add(rendererPane); + } + + public void uninstallUI(JComponent c) { + super.uninstallUI(c); + + c.remove(rendererPane); + rendererPane = null; + } + + public void paint(Graphics g, JComponent c) { + Dimension size = c.getSize(); + textArea.setBackground(c.getBackground()); + rendererPane.paintComponent(g, textArea, c, 1, 1, + size.width - 1, size.height - 1, true); + } + + public Dimension getPreferredSize(JComponent c) { + String tipText = ((JToolTip)c).getTipText(); + if (tipText == null) + return new Dimension(0,0); + textArea = new JTextArea(tipText ); + rendererPane.removeAll(); + rendererPane.add(textArea ); + textArea.setWrapStyleWord(true); + int width = ((MultiLineToolTip)c).getFixedWidth(); + int columns = ((MultiLineToolTip)c).getColumns(); + + if( columns > 0 ) + { + textArea.setColumns(columns); + textArea.setSize(0,0); + textArea.setLineWrap(true); + textArea.setSize( textArea.getPreferredSize() ); + } + else if( width > 0 ) + { + textArea.setLineWrap(true); + Dimension d = textArea.getPreferredSize(); + d.width = width; + d.height++; + textArea.setSize(d); + } + else + textArea.setLineWrap(false); + + + Dimension dim = textArea.getPreferredSize(); + + dim.height += 1; + dim.width += 1; + return dim; + } + + public Dimension getMinimumSize(JComponent c) { + return getPreferredSize(c); + } + + public Dimension getMaximumSize(JComponent c) { + return getPreferredSize(c); + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/PermissionAttributesTableModel.java b/src/ch/ethz/infsec/secureumlgui/gui/PermissionAttributesTableModel.java new file mode 100644 index 0000000..a7d869c --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/PermissionAttributesTableModel.java @@ -0,0 +1,218 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.gui; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; +import java.util.List; + +import javax.swing.event.TableModelEvent; +import javax.swing.table.AbstractTableModel; + +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PermissionWrapper; + +/** + * Swing table model for the permission table displayed in the + * SecureUML properties tab for permissions. + * Each row is one resource-action pair. + * + */ +public class PermissionAttributesTableModel extends AbstractTableModel +{ + /** + * + */ + public PermissionAttributesTableModel( + List permissions) + { + super(); + + setCurrentPermissionWrappers(permissions); + + } + + List currentPermissionWrappers; + + ArrayList actionWrappers = + new ArrayList(); + + MultiContextLogger logger = MultiContextLogger.getDefault(); + + + public void setCurrentPermissionWrappers( + List permissionWrappers) + { + actionWrappers.clear(); + + currentPermissionWrappers = permissionWrappers; + try + { + for (Iterator iter = currentPermissionWrappers.iterator(); iter.hasNext();) + { + PermissionWrapper permissionWrapper = (PermissionWrapper) iter.next(); + + actionWrappers.add(permissionWrapper.getActionWrapper()); + //logger.info(logger.TARGET_EVENTS, "RolePermissionsTable: Added" + actions.size() + " Action(s)"); +// for (Iterator iterator = permission.getAction().iterator(); iterator.hasNext();) +// { +// Action action = (Action) iterator.next(); +// +// actions.add(action); +//// txPermissions.append(action.getResource() +//// + ": " + action.getName() +//// + "\n"); +// } + } + + sortByResource(); + } + catch (Exception e) + { + logger.logException(e); + } + } + + public String getColumnName(int column) + { + //logger.info("requesting Column Name " + column); + + if(column == 0) + { + return "RESOURCE"; + } + else if(column == 1) + { + return "ACTION"; + } + else + return "#ERROR#"; + } + + /* (non-Javadoc) + * @see javax.swing.table.TableModel#getRowCount() + */ + + public int getRowCount() + { + try + { + return actionWrappers.size(); + } + catch (Exception e) + { + return 0; + } + } + + public int getColumnCount() + { + return 2; + } + + public Object getValueAt(int row, int col) + { + if(col == 0) + { + String val = actionWrappers.get(row).getResourceWrapper().getResourcePath(); + if(val==null || val.equals("")) + return "N/A"; + else + return val; + } + else if(col == 1) + { + String val = actionWrappers.get(row).getName(); + if(val==null || val.equals("")) + return "N/A"; + else + return val; + } + else + return null; + } + + /* (non-Javadoc) + * @see javax.swing.table.AbstractTableModel#getColumnClass(int) + */ + @Override + public Class getColumnClass(int columnIndex) + { + return String.class; + } + + + public void fireManually() + { + fireTableStructureChanged(); + fireTableDataChanged(); + fireTableChanged(new TableModelEvent(this)); + + } + + + private void sortByResource() + { + Collections.sort(actionWrappers, new actionResourceComparator()); + } + + private void sortByActionName() + { + Collections.sort(actionWrappers, new actionNameComparator()); + } + + public class actionResourceComparator implements Comparator + { + public int compare(ActionWrapper a1, ActionWrapper a2) + { + try + { + if(a1 == null || a2 == null) + { + if (a1 != null) + return a1.getResource().toString().compareTo(""); + else if(a2 != null) + return a2.getResource().toString().compareTo(""); + else + return 0; + } + else + return a1.getResource().toString().compareTo(a2.getResource().toString()); + } + catch (Exception e) + { + return 0; + } + } + } + + public class actionNameComparator implements Comparator + { + public int compare(ActionWrapper a1, ActionWrapper a2) + { + try + { + if(a1 == null || a2 == null) + { + if (a1 != null) + return a1.getResource().toString().compareTo(""); + else if(a2 != null) + return a2.getResource().toString().compareTo(""); + else + return 0; + } + else + return a1.getName().compareTo(a2.getName()); + } + catch (Exception e) + { + return 0; + } + } + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/PermissionIconTableCellRenderer.java b/src/ch/ethz/infsec/secureumlgui/gui/PermissionIconTableCellRenderer.java new file mode 100644 index 0000000..30dfa10 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/PermissionIconTableCellRenderer.java @@ -0,0 +1,37 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.gui; + +import java.awt.Component; +import java.awt.Container; + +import javax.swing.JLabel; +import javax.swing.JTable; +import javax.swing.table.TableCellRenderer; + +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.PermissionValue; + +/** + * + */ +public class PermissionIconTableCellRenderer + implements TableCellRenderer +{ + public Component getTableCellRendererComponent( + JTable table, Object value, + boolean isSelected, boolean hasFocus, + int row, int column) + { + //Container container = new JPanel(); + + if (value instanceof PermissionValue) + { + PermissionValue pv = (PermissionValue) value; + + return new PermissionIconTableCellRendererComponent(pv); + } + else + return new JLabel("error"); + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/PermissionIconTableCellRendererComponent.java b/src/ch/ethz/infsec/secureumlgui/gui/PermissionIconTableCellRendererComponent.java new file mode 100644 index 0000000..4395373 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/PermissionIconTableCellRendererComponent.java @@ -0,0 +1,89 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.gui; + +import javax.swing.JCheckBox; +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; + +import ch.ethz.infsec.secureumlgui.ResourceFilesManager; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.PermissionValue; + +/** + * + */ +public class PermissionIconTableCellRendererComponent + extends JPanel +{ + + static ResourceFilesManager resourceFilesManager = + new ResourceFilesManager(); + + MultiContextLogger logger = + MultiContextLogger.getDefault(); + + JCheckBox cbExplicitPermission = new JCheckBox(); + JLabel lbConstrained = new JLabel(); + JLabel lbImplicit = new JLabel(); + JLabel lbInherited = new JLabel(); + + //JLabel lbValue = new JLabel(); + + /** + * + */ + public PermissionIconTableCellRendererComponent(PermissionValue pv) + { + initIconLabels(); + //lbValue.setText(pv.getName()); + + setVisible(true); + + + //this.add(lbValue); + + String tooltip = pv.getDescription(); + + if(pv.getValue() == pv.GRANTED.getValue()) + { + this.add(cbExplicitPermission); + cbExplicitPermission.setVisible(true); + } + else if(pv.getValue() == pv.IMPLICIT.getValue()) + { + this.add(lbImplicit); + lbImplicit.setVisible(true); + } + else if(pv.getValue() == pv.INHERITED.getValue()) + { + this.add(lbInherited); + lbImplicit.setVisible(true); + } + else + { + this.add(new JLabel("error")); + } + + if(pv.isConstrained()) + { + this.add(lbConstrained); + lbConstrained.setVisible(true); + } + + setToolTipText(tooltip); + + } + + + protected void initIconLabels() + { + cbExplicitPermission.setSelected(true); + lbConstrained.setIcon(resourceFilesManager.getConstrainedIcon()); + lbInherited.setIcon(resourceFilesManager.getInheritedRoleIcon()); + lbImplicit.setIcon(resourceFilesManager.getImplicitIcon()); + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/PolicyLevelCreator.java b/src/ch/ethz/infsec/secureumlgui/gui/PolicyLevelCreator.java new file mode 100644 index 0000000..6d88876 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/PolicyLevelCreator.java @@ -0,0 +1,9 @@ +package ch.ethz.infsec.secureumlgui.gui; + +import javax.swing.JPanel; + + + +public class PolicyLevelCreator extends JPanel { + +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/RolePermissionsTableModel.java b/src/ch/ethz/infsec/secureumlgui/gui/RolePermissionsTableModel.java new file mode 100644 index 0000000..daea4a2 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/RolePermissionsTableModel.java @@ -0,0 +1,452 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.gui; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.Iterator; + +import javax.swing.event.TableModelEvent; +import javax.swing.table.AbstractTableModel; + +import org.apache.log4j.Logger; +import org.omg.uml.foundation.core.ModelElement; + +import ch.ethz.infsec.secureumlgui.Util; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.modelmapping.GenericDialectHelper; +import ch.ethz.infsec.secureumlgui.modelmapping.GenericDialectModelMapper; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.ActionPermissionSet; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.HierarchicalPermissionsExplorer; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.PermissionSet; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.PermissionValue; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.ResourcePermissionsSet; +import ch.ethz.infsec.secureumlgui.transformation.ModelMap; +import ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PermissionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.RoleWrapper; + +/** + * Swing table model for the permission table displayed in the + * SecureUML properties tab for roles. Each row represents a + * permission for a specific resource-action pair. The first column + * describes the kind of permission (explicit, implicit, inherited, + * etc), the second and third column are resource and action, resp. + * + * + */ +public class RolePermissionsTableModel extends AbstractTableModel +{ + /** + * + */ + public RolePermissionsTableModel(RoleWrapper roleWrapper) + { + super(); + + setCurrentRole(roleWrapper); + + } + + private static Logger aLog = Logger.getLogger(RolePermissionsTableModel.class); + + RoleWrapper currentRoleWrapper; + + //ArrayList actionWrappers = new ArrayList(); + + ArrayList permissionValues = + new ArrayList(); + + MultiContextLogger logger = new MultiContextLogger(MultiContextLogger.GUI); + + + public void setCurrentRole(RoleWrapper roleWrapper) + { + + String loggerString = "RolePermissionsTableModel.setCurrentRole with " ; + if(roleWrapper.getPermissionWrapper() == null) + loggerString += "0"; + else + loggerString += roleWrapper.getPermissionWrapper().size(); + + loggerString += " Permissions"; + + //logger.info(loggerString); + + //actionWrappers.clear(); + permissionValues.clear(); + + currentRoleWrapper = roleWrapper; + try + { + HierarchicalPermissionsExplorer hps = + new HierarchicalPermissionsExplorer(); + + for (Iterator iter = currentRoleWrapper.getPermissionWrapper().iterator(); iter.hasNext();) + { + PermissionWrapper permission = (PermissionWrapper) iter.next(); + + //actionWrappers.add(permission.getActionWrapper()); + + PermissionValue pv = + PermissionValue.create( + PermissionValue.GRANTED, + permission); + + permissionValues.add(pv); + + //logger.info(logger.TARGET_EVENTS, "RolePermissionsTable: Added" + actions.size() + " Action(s)"); +// for (Iterator iterator = permission.getAction().iterator(); iterator.hasNext();) +// { +// Action action = (Action) iterator.next(); +// +// actions.add(action); +//// txPermissions.append(action.getResource() +//// + ": " + action.getName() +//// + "\n"); +// } + + PermissionSet permissions = hps.getExplicitPermissions(permission.getActionWrapper().getResourceWrapper()); + + hps.collectNonExplicitPermissions(permission.getActionWrapper().getResourceWrapper(), permissions); + + ResourcePermissionsSet rps = + permissions.getResourcePermissionsSet(roleWrapper); + + // collect implicit permissions + for (Iterator iterator = rps.getActions().iterator(); iterator + .hasNext();) + { + Object action = iterator.next(); + + ActionPermissionSet aps = + rps.getPermissions(action); + + aLog.warn("setCurrentRole: which policy? using default policy"); + + for (Iterator it = aps.getDefaultPolicyPermissionSet().getPermissions().iterator(); it + .hasNext();) + { + PermissionValue permissionValue = + (PermissionValue) it.next(); + + if(!permissionValues.contains(permissionValue) + && !(permissionValue.getValue() == permissionValue.INHERITED.getValue())) + permissionValues.add(permissionValue); + + //permissionValue.getPermissionWrapper().setAction( + //aps.getExplicitActionWrapper().getModelElement()); + //action); + // aps.getExplicitActionWrapper().getModelElement()); + } + } + + + +// ActionPermissionSet aps = new ActionPermissionSet(); +// aps.setExplicitActionWrapper(permission.getActionWrapper()); +// aps.setExplicitRoleWrapper(roleWrapper); +// +// aps.addPermission( +// PermissionValue.create( +// PermissionValue.GRANTED, +// permission)); + } + + + +// collect inherited permissions + Collection superroles = hps.getSuperRoleWrappersDeep(roleWrapper); + for (Iterator iterator = superroles.iterator(); iterator + .hasNext();) + { + RoleWrapper superrole = (RoleWrapper) iterator.next(); + + Collection permissionWrappers = + superrole.getPermissionWrapper(); + + for (Iterator iter = permissionWrappers.iterator(); iter.hasNext();) + { + PermissionWrapper pw = (PermissionWrapper) iter.next(); + + PermissionValue pv = + PermissionValue.create( + PermissionValue.INHERITED, pw); + + permissionValues.add(pv); + } + } + + sortByResource(); + sortByPermissionValue(); + } + catch (Exception e) + { + logger.logException(e); + } + } + + public String getColumnName(int column) + { + //logger.info("requesting Column Name " + column); + + if(column == 0) + { + return "PERMISSION"; + } + if(column == 1) + { + return "RESOURCE"; + } + else if(column == 2) + { + return "ACTION"; + } + else + return "#ERROR#"; + } + + /* (non-Javadoc) + * @see javax.swing.table.TableModel#getRowCount() + */ + + public int getRowCount() + { + try + { + return permissionValues.size(); + //return actionWrappers.size(); + } + catch (Exception e) + { + return 0; + } + } + + public int getColumnCount() + { + return 3; + } + + + + public Object getValueAt(int row, int col) + { + if(col == 0) + { + return permissionValues.get(row); + } + else if(col == 1) + { + if(permissionValues.get(row) == null) + return "null"; + else + { + //return actionWrappers.get(row).getResource().toString(); + String resourcePath = + permissionValues.get(row).getPermissionWrapper(). + getActionWrapper().getResourceWrapper(). + getResourcePath(); + //actionWrappers.get(row).getResourceWrapper().getResourcePath(); + + return resourcePath; + } + } + else if(col == 2) + { + if(permissionValues.get(row) == null) + return "null"; + else + { + return permissionValues.get(row).getPermissionWrapper(). + getActionWrapper().getName(); + //return actionWrappers.get(row).getName(); + } + } + else + return null; + } + + /* (non-Javadoc) + * @see javax.swing.table.AbstractTableModel#getColumnClass(int) + */ + @Override + public Class getColumnClass(int columnIndex) + { + if(columnIndex == 0) + return PermissionValue.class; + else + return String.class; + } + + + public void fireManually() + { + fireTableStructureChanged(); + fireTableDataChanged(); + fireTableChanged(new TableModelEvent(this)); + + } + + + private void sortByResource() + { + Collections.sort(permissionValues, new permissionActionResourceComparator()); + //Collections.sort(actionWrappers, new actionResourceComparator()); + } + + private void sortByActionName() + { + Collections.sort(//actionWrappers, new actionNameComparator() + permissionValues, new permissionActionNameComparator()); + } + + private void sortByPermissionValue() + { + Collections.sort(permissionValues, + new permissionValuesComparator()); + } + +// public class actionResourceComparator implements Comparator +// { +// public int compare(ActionWrapper a1, ActionWrapper a2) +// { +// try +// { +// if(a1 == null || a2 == null) +// { +// if (a1 != null) +// return a1.getResource().toString().compareTo(""); +// else if(a2 != null) +// return a2.getResource().toString().compareTo(""); +// else +// return 0; +// } +// else +// return a1.getResource().toString(). +// compareTo(a2.getResource().toString()); +// } +// catch (Exception e) +// { +// return 0; +// } +// } +// } + + public class permissionActionResourceComparator + implements Comparator + { + public int compare(PermissionValue pv1, PermissionValue pv2) + { + try + { + if(pv1 == null || pv2 == null) + { + if (pv1 != null) + return pv1.getPermissionWrapper().getActionWrapper(). + getResource().toString().compareTo(""); + else if(pv2 != null) + return pv2.getPermissionWrapper().getActionWrapper(). + getResource().toString().compareTo(""); + else + return 0; + } + else + return pv1.getPermissionWrapper().getActionWrapper(). + getResource().toString(). + compareTo(pv2.getPermissionWrapper().getActionWrapper(). + getResource().toString()); + } + catch (Exception e) + { + return 0; + } + } + } + +// public class actionNameComparator implements Comparator +// { +// public int compare(ActionWrapper a1, ActionWrapper a2) +// { +// try +// { +// if(a1 == null || a2 == null) +// { +// if (a1 != null) +// return a1.getResource().toString().compareTo(""); +// else if(a2 != null) +// return a2.getResource().toString().compareTo(""); +// else +// return 0; +// } +// else +// return a1.getName().compareTo(a2.getName()); +// } +// catch (Exception e) +// { +// return 0; +// } +// } +// } + + public class permissionActionNameComparator + implements Comparator + { + public int compare(PermissionValue pv1, PermissionValue pv2) + { + try + { + if(pv1 == null || pv2 == null) + { + if (pv1 != null) + return pv1.getPermissionWrapper().getActionWrapper(). + getResource().toString().compareTo(""); + else if(pv2 != null) + return pv2.getPermissionWrapper().getActionWrapper(). + getResource().toString().compareTo(""); + else + return 0; + } + else + return pv1.getPermissionWrapper().getActionWrapper(). + getName().compareTo(pv2.getName()); + } + catch (Exception e) + { + return 0; + } + } + } + + + // sorts descending + public class permissionValuesComparator + implements Comparator + { + public int compare(PermissionValue pv1, PermissionValue pv2) + { + try + { + if(pv1 == null || pv2 == null) + { + if (pv1 != null) + return -pv1.getValue(); + else if(pv2 != null) + return pv2.getValue(); + else + return 0; + } + else + return -pv1.compareTo(pv2); + } + catch (Exception e) + { + return 0; + } + } + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/SecureUmlComponent.java b/src/ch/ethz/infsec/secureumlgui/gui/SecureUmlComponent.java new file mode 100644 index 0000000..75ed7e8 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/SecureUmlComponent.java @@ -0,0 +1,422 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.gui; + +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseListener; +import java.util.ArrayList; +import java.util.Enumeration; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import javax.swing.DefaultCellEditor; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JLabel; +import javax.swing.JScrollPane; +import javax.swing.JTabbedPane; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.JPanel; +import javax.swing.ListSelectionModel; +import javax.swing.SwingConstants; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.table.TableColumn; + +import org.apache.log4j.Logger; +import org.argouml.uml.diagram.ui.UMLDiagram; +import org.omg.uml.foundation.core.UmlClass; + +import ch.ethz.infsec.secureumlgui.ModuleController; +import ch.ethz.infsec.secureumlgui.ResourceFilesManager; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.ActionPermissionSet; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.HierarchicalPolicyExplorer; +import ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.AtomicActionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.CompositeActionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PolicyWrapper; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ResourceType; +import ch.ethz.infsec.secureumlgui.wrapper.ResourceWrapper; + +/** + * generic SecureUML properties component for Resources. + * + * Displays which roles have which permissions for which actions on this resource. + * distinguishes between explicit, implicit, and inherited permissions. + * + */ +public class SecureUmlComponent + extends AbstractSecureUmlComponent + //implements MouseListener + implements ChangeListener +{ + + /** + * + */ + public SecureUmlComponent() + { + super(); + initComponents(); + } + + private String NEW_ROLE_NAME = "NewRole"; + + private JTabbedPane tabPane; + //private Map polices; + + //private List policies = new ArrayList(); + private List policies = new ArrayList(); + private List tables = new ArrayList(); + + + + private PolicyLevelCreator policyCreator; + +// private JScrollPane jScrollPane; +// private JTable tblPermissions; + + private TableSorter tableSorter; + + private JTextField txName; + private JLabel lbType; + private JLabel lbName; + + private ResourceWrapper displayedResourceWrapper = null; + + private GenericResourcePermissionsTableModel tableModel; + + private static Logger aLog = Logger.getLogger(SecureUmlComponent.class); + + + + + + public void initComponents() + { + + JButton btNewRole = new JButton("New Role"); + btNewRole.setToolTipText("New Role"); + btNewRole.addActionListener(new createRoleActionListener()); + + try + { //SecureUmlComponent.class + + ResourceFilesManager resourceFilesManager = + new ResourceFilesManager(); + + ImageIcon icon = resourceFilesManager.getCreateRoleIcon(); + + if (icon != null) + { + btNewRole.setIcon(icon); + } + else + { + logger.warn(logger.STARTUP, + "Image File for Button 'New Role' " + + "not found - showing Text only"); + + } + } + catch (Exception e) + { + logger.logException(e); + } + + + /* NOTE: If a JTable is put on a JScrollPane, the Header + * is displayed automatically (otherwise this needs to be + * done manually). The Column Names are fetched from the + * Method 'TableModel.getColumnName(int col)' + */ + +// tblPermissions = new JTable(); +// tblPermissions.setColumnSelectionAllowed(false); +// tblPermissions.setDragEnabled(false); + + tableSorter = new TableSorter(); + + + //tblPermissions.getTableHeader().setSize(200, 50); + + tabPane = new JTabbedPane(SwingConstants.LEFT); + tabPane.addChangeListener(this); + + //JScrollPane jScrollPane = new JScrollPane(tblPermissions); + + + tabPane.add("Create Policy", policyCreator); + + +// int dummyPol = 4; +// policies = new PolicyWrapper[dummyPol+1]; +// for ( int i = 0 ; i < dummyPol; ++i ) { +// tabPane.add("policy Name " + i, new JScrollPane(tblPermissions) ); +// policies[i+1] = null; +// } + + policyCreator = new PolicyLevelCreator(); + + // tblPermissions.setFillsViewportHeight(true); + + lbName=new JLabel("SecureUML Resource:"); + txName= new JTextField(); + txName.setEditable(false); + + lbType = new JLabel("unknown Resource"); + + + JPanel topPane = new JPanel(); + JPanel labels = new JPanel(); + + labels.add(lbName,BorderLayout.LINE_START); + labels.add(lbType,BorderLayout.LINE_START); + labels.add(txName,BorderLayout.LINE_START); + + topPane.add(labels,BorderLayout.LINE_START); + topPane.add(btNewRole,BorderLayout.CENTER); + + this.add(topPane,BorderLayout.PAGE_START); + //this.add(jScrollPane,BorderLayout.CENTER); + this.add(tabPane,BorderLayout.CENTER); + + } + + + + //protected void setDisplayedResourceWrapper(AbstractPermissionsTableModel tableModel) + protected void setDisplayedResourceWrapper() + { + int selectedTab = tabPane.getSelectedIndex(); + if ( selectedTab < 0 || selectedTab >= policies.size()) { + //no policies, create Policy is selected + return; + } + //PolicyWrapper currentPolicy = policies.get(selectedTab); //policies[tabPane.getSelectedIndex()]; + UmlClass currentPolicy = policies.get(selectedTab); //policies[tabPane.getSelectedIndex()]; + JTable tblPermissions = tables.get(selectedTab); + txName.setText(displayedResourceWrapper.getResourcePath()); + + aLog.debug("setDisplayedResourceWrapper tab: " + selectedTab + " policy: " + currentPolicy.getName()); + + try + { + //tblPermissions.setModel(tableModel); + tableSorter.setTableModel(tableModel); + tblPermissions.setModel(tableSorter); + tableSorter.setTableHeader(tblPermissions.getTableHeader()); + + tblPermissions.setSelectionMode( + ListSelectionModel.SINGLE_SELECTION); + //tblPermissions.setAutoResizeMode( + // JTable.AUTO_RESIZE_OFF); + tblPermissions.setCellSelectionEnabled(true); + tblPermissions.setColumnSelectionAllowed(false); + tblPermissions.setRowSelectionAllowed(false); + + initTableCellDimensions(tblPermissions); + + +// tblPermissions.getColumnModel().getColumn(0). +// setCellRenderer( +// new ActionNameTableCellRenderer()); +// tblPermissions.getColumnModel().getColumn(1). +// setCellRenderer( +// new ActionPermissionTableCellRenderer()); + + tblPermissions.setDefaultRenderer( + ActionPermissionSet.class, + new ActionPermissionTableCellRenderer(currentPolicy)); + tblPermissions.setDefaultEditor( + ActionPermissionSet.class, + new ActionPermissionTableCellRenderer(currentPolicy)); + + tblPermissions.setDefaultRenderer( + ActionWrapper.class, + new ActionNameTableCellRenderer()); + tblPermissions.setDefaultEditor( + ActionWrapper.class, + new ActionNameTableCellRenderer()); + + tblPermissions.setDefaultRenderer( + AtomicActionWrapper.class, + new ActionNameTableCellRenderer()); + tblPermissions.setDefaultRenderer( + CompositeActionWrapper.class, + new ActionNameTableCellRenderer()); + + tblPermissions.getColumnModel(). + getColumn(0).setCellRenderer( + new ActionNameTableCellRenderer()); + + //(new ActionPermissionTableCellRenderer()).addCellEditorListener(l) + //tblPermissions.addMouseListener(l); + + tblPermissions.getTableHeader(). + setToolTipText("SecureUML Roles"); + +// logger.info("tableCellRenderer(1,0): " +// + tblPermissions.getCellRenderer(1, 0)); +// +// int columnCount = tableModel.getColumnCount(); +// + tableModel.fireManually(); + + + tblPermissions.getTableHeader().addMouseListener(tableModel); + +// tblPermissions.repaint(); + +// tblPermissions.setValueAt(tblPermissions.getValueAt(1, 0),1,0); +// + // throws NullpointerException only when a first + // UML Element is selected + //jScrollPane.getColumnHeader().setVisible(true); + } + catch (Exception e) + { + logger.logException(e); + } + } + + /** + * + */ + private void initTableCellDimensions(JTable tblPermissions) + { + // hack + tblPermissions.setRowHeight(26); + tblPermissions.getColumnModel().getColumn(0).setMaxWidth(52); + + for (Enumeration cols = tblPermissions.getColumnModel().getColumns(); cols.hasMoreElements();) + { + TableColumn col = (TableColumn) cols.nextElement(); + col.setMinWidth(525); + } + } + + + private class createRoleActionListener implements ActionListener + { + /* (non-Javadoc) + * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) + */ + public void actionPerformed(ActionEvent e) + { + ModuleController.getInstance().addRole( + NEW_ROLE_NAME, + displayedResourceWrapper); + } + } + + private void updatePolicyTabs () { + + aLog.debug("updatePolicyTabs"); + + boolean rebuild = false; + + //List sortedPolicies = HierarchicalPolicyExplorer.getInstance().getSortedPolicies(); + List sortedPolicies = HierarchicalPolicyExplorer.getInstance().getSortedPolicies(); + + int policiesCount = 0; + int tabCount = tabPane.getTabCount(); + + if ( sortedPolicies != null ) { + policiesCount = sortedPolicies.size(); + } + + if ( tabPane.getTabCount()-1 != policiesCount ) { + rebuild = true; + } else { + for (int i = 0; i < policiesCount && i < tabCount; ++i) { + if ( ! sortedPolicies.get(i).getName().equals(tabPane.getTitleAt(i))) { + rebuild = true; + break; + } + } + } + + aLog.debug("updatePolicyTabs: tabCount: " + tabCount+ ", policiesCount: " + policiesCount + " rebuild: " + rebuild); + + if ( rebuild ) { + for ( int i = 0; i < policiesCount && i < tabCount - 1; ++i) { + tabPane.setTitleAt(i, sortedPolicies.get(i).getName()); + policies.set(i, sortedPolicies.get(i)); + aLog.debug("set permissonPanel at index " + i +" for policy " + sortedPolicies.get(i).getName()); + } + if ( policiesCount > (tabCount - 1)) { + //remove (the last) create policy tab + tabPane.remove(tabCount - 1); + + //for (int i = policiesCount; i < (tabCount - 1); ++i) { + for (int i = tabCount - 1; i < policiesCount; ++i) { + JTable tblPermissions; + + if (tables.size() > i && tables.get(i) != null) { + tblPermissions = tables.get(i); + } else { + tblPermissions = new JTable(); + tblPermissions.setColumnSelectionAllowed(false); + tblPermissions.setDragEnabled(false); + } + + JScrollPane jScrollPane = new JScrollPane(tblPermissions); + tabPane.add(sortedPolicies.get(i).getName(), jScrollPane); + + policies.add(i, sortedPolicies.get(i)); //# + tables.add(i, tblPermissions); + + aLog.debug("added permissonPanel at index " + i +" for policy " + sortedPolicies.get(i).getName()); + } + tabPane.add("Create Policy", policyCreator); + } else if ( policiesCount < (tabCount - 1) ) { + for (int i = policiesCount; i < (tabCount - 1); ++i) { + tabPane.remove(i); + policies.remove(i); + aLog.debug("removed permission panel from index " + i); + } + } + aLog.debug("updatePolicyTabs: done"); + } +// if ( sortedPolicies != null) { +// policies = new PolicyWrapper[sortedPolicies.size()]; +// for (int i = 0 ; i < sortedPolicies.size(); ++i) { +// tabPane.add(sortedPolicies.get(i).getName(), new JScrollPane(tblPermissions)); +// policies[i] = sortedPolicies.get(i); +// } +// } + } + + public void setDisplayedSecureUmlElement( + Object suElement, ResourceType rt) + { + aLog.debug("setDisplayedSecureUmlElement"); + updatePolicyTabs(); + super.setDisplayedSecureUmlElement(suElement, rt); + lbType.setText(rt.getName()); + this.displayedResourceWrapper = new ResourceWrapper(suElement); + this.tableModel = new GenericResourcePermissionsTableModel(displayedResourceWrapper); + + //setDisplayedResourceWrapper(tableModel); + setDisplayedResourceWrapper(); + } + + + + public void stateChanged(ChangeEvent arg0) { + if (tableModel != null) { + setDisplayedResourceWrapper(); + } + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/SecureUmlExcpPermissionComponent.java b/src/ch/ethz/infsec/secureumlgui/gui/SecureUmlExcpPermissionComponent.java new file mode 100644 index 0000000..b0de6aa --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/SecureUmlExcpPermissionComponent.java @@ -0,0 +1,65 @@ +package ch.ethz.infsec.secureumlgui.gui; + +import java.awt.Dimension; + +import javax.swing.BoxLayout; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; + +import ch.ethz.infsec.secureumlgui.util.ExcpPermissionDummy; +import ch.ethz.infsec.secureumlgui.util.PermissionDummy; + + +/** + * + * + */ +public class SecureUmlExcpPermissionComponent extends + SecureUmlPermissionComponent { + + + JLabel lbExcpLevel; + JTextField txExcpLevel; + + + public SecureUmlExcpPermissionComponent() + { + super(); + initExcpComponents(); + } + + private void initExcpComponents() { + + super.lbName.setText("Exception Permission Name: "); + + lbExcpLevel = new JLabel("Exception Level: "); + txExcpLevel = new JTextField(); + txExcpLevel.setEditable(false); + + + + } + + //hack... + protected void addAdditionalPanels(JPanel boxes) { + lbExcpLevel = new JLabel("Exception Level: "); + txExcpLevel = new JTextField(); + txExcpLevel.setEditable(false); + + JPanel excpLevel = new JPanel(); + excpLevel.setLayout(new BoxLayout(excpLevel, BoxLayout.LINE_AXIS)); + excpLevel.setMaximumSize(new Dimension(1000,20)); + excpLevel.add(lbExcpLevel); + excpLevel.add(txExcpLevel); + + boxes.add(excpLevel); + } + + public void setDisplayedPermission(ExcpPermissionDummy displayedPermission) { + super.setDisplayedPermission(displayedPermission); + + } + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/SecureUmlPermissionComponent.java b/src/ch/ethz/infsec/secureumlgui/gui/SecureUmlPermissionComponent.java new file mode 100644 index 0000000..14f677e --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/SecureUmlPermissionComponent.java @@ -0,0 +1,366 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.gui; + +import java.awt.Dimension; +import java.awt.BorderLayout; +import java.util.List; + +import javax.swing.BoxLayout; + +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.JTextArea; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +import ch.ethz.infsec.secureumlgui.ModuleController; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ResourceType; +import ch.ethz.infsec.secureumlgui.securemodel.secureuml.Permission; +import ch.ethz.infsec.secureumlgui.util.PermissionDummy; +import ch.ethz.infsec.secureumlgui.wrapper.PermissionWrapper; + +/** + * SecureUML Properties component for permissions. + * + * Displays the role which has this permission, as well as the action, + * this permission permits. + * + */ +public class SecureUmlPermissionComponent + extends AbstractSecureUmlComponent + //implements DocumentListener +{ + /** + * + */ + public SecureUmlPermissionComponent() + { + super(); + initComponents(); + } + + JPanel textboxesPanel; + + JLabel lbName; + JTextField txName; + + JLabel lbAnchor; + JTextField txAnchor; + + JLabel lbRole; + JTextField txRole; + + JLabel lbConstraint; + JTextArea txConstraint; + + JLabel lbPermissionAttributes; + + JScrollPane scpPermissionAttributes; + JTable tblPermissionAttributes; + + + + public void initComponents() + { + + lbName = new JLabel("Permission Name: "); + txName = new JTextField(); + txName.setEditable(false); + + lbAnchor = new JLabel("Anchor: "); + txAnchor = new JTextField(); + txAnchor.setEditable(false); + + lbRole = new JLabel("Role: "); + txRole = new JTextField(); + txRole.setEditable(false); + + lbConstraint = new JLabel("OCL Constraint: "); + txConstraint = new JTextArea(10,60); + txConstraint.setEditable(true); + JScrollPane scpConstr = new JScrollPane(txConstraint); + tblPermissionAttributes = new JTable(); + scpPermissionAttributes = new JScrollPane(tblPermissionAttributes); + // scpPermissionAttributes.setMinimumSize( + // new Dimension(200, 140)); + + JPanel names = new JPanel(); + names.setLayout(new BoxLayout(names, BoxLayout.LINE_AXIS)); + names.setMaximumSize(new Dimension(1000,20)); + names.add(lbName); + names.add(txName); + JPanel roles = new JPanel(); + roles.setLayout(new BoxLayout(roles, BoxLayout.LINE_AXIS)); + roles.setMaximumSize(new Dimension(1000,20)); + roles.add(lbRole); + roles.add(txRole); + JPanel anchors = new JPanel(); + anchors.setLayout(new BoxLayout(anchors, BoxLayout.LINE_AXIS)); + anchors.setMaximumSize(new Dimension(1000,20)); + + anchors.add(lbAnchor); + anchors.add(txAnchor); + + anchors.setAlignmentX(LEFT_ALIGNMENT); + names.setAlignmentX(LEFT_ALIGNMENT); + roles.setAlignmentX(LEFT_ALIGNMENT); + lbConstraint.setAlignmentX(LEFT_ALIGNMENT); + scpConstr.setAlignmentX(LEFT_ALIGNMENT); + + JPanel boxes = new JPanel(); + boxes.setLayout(new BoxLayout(boxes, BoxLayout.PAGE_AXIS)); + + addAdditionalPanels(boxes); + boxes.add(names); + boxes.add(roles); + boxes.add(anchors); + + boxes.add(lbConstraint); + boxes.add(scpConstr); + + txConstraint.getDocument().addDocumentListener(new ConstraintListener()); + + this.add(boxes, BorderLayout.LINE_START); + this.add(scpPermissionAttributes, BorderLayout.CENTER); + } + + //hack... + protected void addAdditionalPanels(JPanel boxes) { + ; + } + + + + private PermissionDummy displayedPermission; + + public PermissionDummy getDisplayedPermission() + { + return displayedPermission; + } + + List displayedPermissionAttributes; + + public void setDisplayedPermission(PermissionDummy displayedPermission) + { + if (displayedPermission == null) logger.error("null in setDisplayedPermission"); + this.displayedPermission = displayedPermission; + +// logger.info(logger.TARGET_EVENTS, "displayedPermission set to: " +// + displayedPermission +// + "\n named: " + displayedPermission.getName() +// + ",\n for anchor: " +// + displayedPermission.getAnchor().getName() +// + ",\n and role: " + +// + displayedPermission.getRole().getName()); + + try + { + if (displayedPermission.getAnchor() == null) logger.error("displayed Permission has no anchor set"); + txName.setText(displayedPermission.getName()); + txAnchor.setText(displayedPermission. + getAnchorWrapper().getName()); + txRole.setText(displayedPermission. + getRoleWrapper().getName()); + if(displayedPermission. + getAuthorizationConstraintWrapper(). + getModelElement() != null) + { + txConstraint.setText(displayedPermission. + getAuthorizationConstraintWrapper().getConstraint()); + } + else + txConstraint.setText(""); + + // setTitle(displayedPermission.getName() + // + " - SecureUML Permission"); + + this.invalidate(); + } + catch (Exception e) + { + logger.logException(e); + } + + displayPermissionAttributes( + displayedPermission.getPermissionAttributeWrappers()); + } + + private void onAuthorizationConstraintChanged() + { + // too verbose - + // 2 lines for each single character change in Textbox +// logger.info(logger.GUI, +// "AuthorizationConstraint changed to: '" +// + txConstraint.getText() + "'"); + ModuleController.getInstance(). + setAuthorizationConstraint(displayedPermission, + txConstraint.getText()); + } + + private void onPermissionNameChanged() + { +// ModuleController.getInstance(). +// setPermissionName(displayedPermission, +// txName.getText()); + } + + protected void displayPermissionAttributes( + List permissionAttributes) + { + this.displayedPermissionAttributes = permissionAttributes; + try + { + PermissionAttributesTableModel tableModel = + new PermissionAttributesTableModel( + displayedPermissionAttributes); + + //tblPermissions.setModel(tableModel); + + TableSorter sorter = new TableSorter(tableModel); + tblPermissionAttributes.setModel(sorter); + //sorter.addMouseListenerToHeaderInTable(tblPermissions); + sorter.setTableHeader( + tblPermissionAttributes.getTableHeader()); + // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html#sorting + + tableModel.fireManually(); + sorter.fireTableStructureChanged(); + sorter.fireTableDataChanged(); + //tblPermissions.validate(); + //scpPermissions.validate(); + //tblPermissions.setTableHeader(new JTableHeader(tableModel)) + // moved to RolePermissionsTableModel +// for (Iterator iter = displayedRole.getPermission().iterator(); iter.hasNext();) +// { +// Permission permission = (Permission) iter.next(); +// +// for (Iterator iterator = permission.getAction().iterator(); iterator.hasNext();) +// { +// Action action = (Action) iterator.next(); +// +// txPermissions.append(action.getResource() +// + ": " + action.getName() +// + "\n"); +// } +// } + } + catch (Exception e) + { + logger.logException(e); + } + } + + + + + + private class ConstraintListener implements DocumentListener + { + + /* Document Listener Handlers */ + + /** + * @see javax.swing.event.DocumentListener#changedUpdate(javax.swing.event.DocumentEvent) + */ + public void changedUpdate(DocumentEvent e) + { + onAuthorizationConstraintChanged(); + } + + /** + * @see javax.swing.event.DocumentListener#insertUpdate(javax.swing.event.DocumentEvent) + */ + public void insertUpdate(DocumentEvent e) + { + onAuthorizationConstraintChanged(); + } + + /** + * @see javax.swing.event.DocumentListener#removeUpdate(javax.swing.event.DocumentEvent) + */ + public void removeUpdate(DocumentEvent e) + { + onAuthorizationConstraintChanged(); + } + + } + + private class PermissionNameListener implements DocumentListener + { + + /* Document Listener Handlers */ + + /** + * @see javax.swing.event.DocumentListener#changedUpdate(javax.swing.event.DocumentEvent) + */ + public void changedUpdate(DocumentEvent e) + { + onPermissionNameChanged(); + + + //txConstraint.getDocument().get + + + //e.getChange(null). + } + + /** + * @see javax.swing.event.DocumentListener#insertUpdate(javax.swing.event.DocumentEvent) + */ + public void insertUpdate(DocumentEvent e) + { + onPermissionNameChanged(); + + } + + /** + * @see javax.swing.event.DocumentListener#removeUpdate(javax.swing.event.DocumentEvent) + */ + public void removeUpdate(DocumentEvent e) + { + onPermissionNameChanged(); + + } + + } + + /* (non-Javadoc) + * @see ch.ethz.infsec.secureumlgui.gui.AbstractSecureUmlComponent#setDisplayedSecureUmlElement(java.lang.Object, ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ResourceType) + */ + @Override + public void setDisplayedSecureUmlElement(Object suElement, ResourceType rt) + { + //setTitle("SecureUML Permission"); + + // TODO Auto-generated method stub + if (suElement == null) logger.error("null in setDisplayedSecureUmlElement"); + if (rt == null) logger.error("null in setDisplayedSecureUmlElement"); + super.setDisplayedSecureUmlElement(suElement, rt); + + setDisplayedPermission((PermissionDummy)suElement); + + } + + /* (non-Javadoc) + * @see javax.swing.JComponent#setMinimumSize(java.awt.Dimension) + */ + @Override + public void setMinimumSize(Dimension minimumSize) + { + // TODO Auto-generated method stub + //super.setMinimumSize(minimumSize); + +// minimumSize.height -= 100; +// minimumSize.height /= 2; +// +// if(minimumSize.height >0) +// scpPermissionAttributes.setMinimumSize(minimumSize); + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/SecureUmlRoleComponent.java b/src/ch/ethz/infsec/secureumlgui/gui/SecureUmlRoleComponent.java new file mode 100644 index 0000000..cda4d39 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/SecureUmlRoleComponent.java @@ -0,0 +1,161 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.gui; + +import java.awt.Dimension; +import java.awt.GridBagConstraints; +import java.awt.BorderLayout; + +import javax.swing.JButton; +import javax.swing.JLabel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.JPanel; + +import org.tigris.swidgets.LabelledLayout; + +import ch.ethz.infsec.secureumlgui.gui.RolePermissionsTableModel; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.PermissionValue; + +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ResourceType; +import ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.RoleWrapper; + +/** + * SecureUML Properties component for Roles. + * + * Displays all actions this role has (explicit, implicit, or inherited) + * + */ +public class SecureUmlRoleComponent extends AbstractSecureUmlComponent +{ + /** + * + */ + public SecureUmlRoleComponent() + { + super();//"SecureUml Role Permissions");//Properties"); + + initComponents(); + } + + JLabel lbName; + JTextField txName; + + JLabel lbPermissions; + + JScrollPane scpPermissions; + JTable tblPermissions; + + JButton btNewRole; + + public void initComponents() + { + lbName = new JLabel("Role Name: "); + txName = new JTextField(); + txName.setEditable(false); + + + tblPermissions= new JTable(); + + // already displayed by the default PropPanel + // but here for testing purposes + + JPanel labels = new JPanel(); + + labels.add(lbName,BorderLayout.LINE_START); + labels.add(txName, BorderLayout.CENTER); + /* NOTE: If a JTable is put on a JScrollPane, the Header + * is displayed automatically (otherwise this needs to be + * done manually). The Column Names are fetched from the + * Method 'TableModel.getColumnName(int col)' + */ + scpPermissions = new JScrollPane(tblPermissions); + + tblPermissions.setRowHeight(26); + //scpPermissions.setMinimumSize(new Dimension(0, 120)); + + //this.add(tblPermissions); + this.add(labels, BorderLayout.LINE_START); + this.add(scpPermissions, BorderLayout.CENTER); + //this.validate(); + + } + + + private RoleWrapper displayedRoleWrapper; + + public RoleWrapper getDisplayedRoleWrapper() + { + return displayedRoleWrapper; + } + + public void setDisplayedRoleWrapper(RoleWrapper displayedRoleWrapper) + { + tblPermissions.setDefaultRenderer( + PermissionValue.class, + new PermissionIconTableCellRenderer()); + +// tblPermissions.getColumnModel(). +// getColumn(0).setCellRenderer( +// new PermissionIconTableCellRenderer()); + + this.displayedRoleWrapper = displayedRoleWrapper; + + if(displayedRoleWrapper != null) + { + txName.setText(displayedRoleWrapper.getName()); + + // setTitle(displayedRoleWrapper.getName() + // + " - SecureUML Role"); + } + + displayPermissions(); + } + + protected void displayPermissions() + { + try + { + RolePermissionsTableModel tableModel = + new RolePermissionsTableModel( + displayedRoleWrapper); + + //tblPermissions.setModel(tableModel); + + TableSorter sorter = new TableSorter(tableModel); + tblPermissions.setModel(sorter); + //sorter.addMouseListenerToHeaderInTable(tblPermissions); + sorter.setTableHeader(tblPermissions.getTableHeader()); + // http://java.sun.com/docs/books/tutorial/uiswing/components/table.html#sorting + + + tableModel.fireManually(); + sorter.fireTableStructureChanged(); + sorter.fireTableDataChanged(); + } + catch (Exception e) + { + logger.logException(e); + } + } + + /* (non-Javadoc) + * @see ch.ethz.infsec.secureumlgui.gui.AbstractSecureUmlComponent#setDisplayedSecureUmlElement(java.lang.Object, ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ResourceType) + */ + @Override + public void setDisplayedSecureUmlElement(Object suElement, ResourceType rt) + { + + //setTitle("SecureUML Role"); + + // TODO Auto-generated method stub + super.setDisplayedSecureUmlElement(suElement, rt); + + setDisplayedRoleWrapper(new RoleWrapper(suElement)); + + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/TableSorter.java b/src/ch/ethz/infsec/secureumlgui/gui/TableSorter.java new file mode 100644 index 0000000..3a71866 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/TableSorter.java @@ -0,0 +1,486 @@ +package ch.ethz.infsec.secureumlgui.gui; + +import java.awt.*; +import java.awt.event.*; +import java.util.*; +import java.util.List; + +import javax.swing.*; +import javax.swing.event.TableModelEvent; +import javax.swing.event.TableModelListener; +import javax.swing.table.*; + +/** + * from: http://java.sun.com/docs/books/tutorial/uiswing/components/examples/TableSorter.java + * + * + * TableSorter is a decorator for TableModels; adding sorting + * functionality to a supplied TableModel. TableSorter does + * not store or copy the data in its TableModel; instead it maintains + * a map from the row indexes of the view to the row indexes of the + * model. As requests are made of the sorter (like getValueAt(row, col)) + * they are passed to the underlying model after the row numbers + * have been translated via the internal mapping array. This way, + * the TableSorter appears to hold another copy of the table + * with the rows in a different order. + *

+ * TableSorter registers itself as a listener to the underlying model, + * just as the JTable itself would. Events recieved from the model + * are examined, sometimes manipulated (typically widened), and then + * passed on to the TableSorter's listeners (typically the JTable). + * If a change to the model has invalidated the order of TableSorter's + * rows, a note of this is made and the sorter will resort the + * rows the next time a value is requested. + *

+ * When the tableHeader property is set, either by using the + * setTableHeader() method or the two argument constructor, the + * table header may be used as a complete UI for TableSorter. + * The default renderer of the tableHeader is decorated with a renderer + * that indicates the sorting status of each column. In addition, + * a mouse listener is installed with the following behavior: + *

    + *
  • + * Mouse-click: Clears the sorting status of all other columns + * and advances the sorting status of that column through three + * values: {NOT_SORTED, ASCENDING, DESCENDING} (then back to + * NOT_SORTED again). + *
  • + * SHIFT-mouse-click: Clears the sorting status of all other columns + * and cycles the sorting status of the column through the same + * three values, in the opposite order: {NOT_SORTED, DESCENDING, ASCENDING}. + *
  • + * CONTROL-mouse-click and CONTROL-SHIFT-mouse-click: as above except + * that the changes to the column do not cancel the statuses of columns + * that are already sorting - giving a way to initiate a compound + * sort. + *
+ *

+ * This is a long overdue rewrite of a class of the same name that + * first appeared in the swing table demos in 1997. + * + * @author Philip Milne + * @author Brendon McLean + * @author Dan van Enckevort + * @author Parwinder Sekhon + * @version 2.0 02/27/04 + */ + +public class TableSorter extends AbstractTableModel { + protected TableModel tableModel; + + public static final int DESCENDING = -1; + public static final int NOT_SORTED = 0; + public static final int ASCENDING = 1; + + private static Directive EMPTY_DIRECTIVE = new Directive(-1, NOT_SORTED); + + public static final Comparator COMPARABLE_COMAPRATOR = new Comparator() { + public int compare(Object o1, Object o2) { + return ((Comparable) o1).compareTo(o2); + } + }; + public static final Comparator LEXICAL_COMPARATOR = new Comparator() { + public int compare(Object o1, Object o2) { + return o1.toString().compareTo(o2.toString()); + } + }; + + private Row[] viewToModel; + private int[] modelToView; + + private JTableHeader tableHeader; + private MouseListener mouseListener; + private TableModelListener tableModelListener; + private Map columnComparators = new HashMap(); + private List sortingColumns = new ArrayList(); + + public TableSorter() { + this.mouseListener = new MouseHandler(); + this.tableModelListener = new TableModelHandler(); + } + + public TableSorter(TableModel tableModel) { + this(); + setTableModel(tableModel); + } + + public TableSorter(TableModel tableModel, JTableHeader tableHeader) { + this(); + setTableHeader(tableHeader); + setTableModel(tableModel); + } + + private void clearSortingState() { + viewToModel = null; + modelToView = null; + } + + public TableModel getTableModel() { + return tableModel; + } + + public void setTableModel(TableModel tableModel) { + if (this.tableModel != null) { + this.tableModel.removeTableModelListener(tableModelListener); + } + + this.tableModel = tableModel; + if (this.tableModel != null) { + this.tableModel.addTableModelListener(tableModelListener); + } + + clearSortingState(); + fireTableStructureChanged(); + } + + public JTableHeader getTableHeader() { + return tableHeader; + } + + public void setTableHeader(JTableHeader tableHeader) { + if (this.tableHeader != null) { + this.tableHeader.removeMouseListener(mouseListener); + TableCellRenderer defaultRenderer = this.tableHeader.getDefaultRenderer(); + if (defaultRenderer instanceof SortableHeaderRenderer) { + this.tableHeader.setDefaultRenderer(((SortableHeaderRenderer) defaultRenderer).tableCellRenderer); + } + } + this.tableHeader = tableHeader; + if (this.tableHeader != null) { + this.tableHeader.addMouseListener(mouseListener); + this.tableHeader.setDefaultRenderer( + new SortableHeaderRenderer(this.tableHeader.getDefaultRenderer())); + } + } + + public boolean isSorting() { + return sortingColumns.size() != 0; + } + + private Directive getDirective(int column) { + for (int i = 0; i < sortingColumns.size(); i++) { + Directive directive = (Directive)sortingColumns.get(i); + if (directive.column == column) { + return directive; + } + } + return EMPTY_DIRECTIVE; + } + + public int getSortingStatus(int column) { + return getDirective(column).direction; + } + + private void sortingStatusChanged() { + clearSortingState(); + fireTableDataChanged(); + if (tableHeader != null) { + tableHeader.repaint(); + } + } + + public void setSortingStatus(int column, int status) { + Directive directive = getDirective(column); + if (directive != EMPTY_DIRECTIVE) { + sortingColumns.remove(directive); + } + if (status != NOT_SORTED) { + sortingColumns.add(new Directive(column, status)); + } + sortingStatusChanged(); + } + + protected Icon getHeaderRendererIcon(int column, int size) { + Directive directive = getDirective(column); + if (directive == EMPTY_DIRECTIVE) { + return null; + } + return new Arrow(directive.direction == DESCENDING, size, sortingColumns.indexOf(directive)); + } + + private void cancelSorting() { + sortingColumns.clear(); + sortingStatusChanged(); + } + + public void setColumnComparator(Class type, Comparator comparator) { + if (comparator == null) { + columnComparators.remove(type); + } else { + columnComparators.put(type, comparator); + } + } + + protected Comparator getComparator(int column) { + Class columnType = tableModel.getColumnClass(column); + Comparator comparator = (Comparator) columnComparators.get(columnType); + if (comparator != null) { + return comparator; + } + if (Comparable.class.isAssignableFrom(columnType)) { + return COMPARABLE_COMAPRATOR; + } + return LEXICAL_COMPARATOR; + } + + private Row[] getViewToModel() { + if (viewToModel == null) { + int tableModelRowCount = tableModel.getRowCount(); + viewToModel = new Row[tableModelRowCount]; + for (int row = 0; row < tableModelRowCount; row++) { + viewToModel[row] = new Row(row); + } + + if (isSorting()) { + Arrays.sort(viewToModel); + } + } + return viewToModel; + } + + public int modelIndex(int viewIndex) { + return getViewToModel()[viewIndex].modelIndex; + } + + private int[] getModelToView() { + if (modelToView == null) { + int n = getViewToModel().length; + modelToView = new int[n]; + for (int i = 0; i < n; i++) { + modelToView[modelIndex(i)] = i; + } + } + return modelToView; + } + + // TableModel interface methods + + public int getRowCount() { + return (tableModel == null) ? 0 : tableModel.getRowCount(); + } + + public int getColumnCount() { + return (tableModel == null) ? 0 : tableModel.getColumnCount(); + } + + public String getColumnName(int column) { + return tableModel.getColumnName(column); + } + + public Class getColumnClass(int column) { + return tableModel.getColumnClass(column); + } + + public boolean isCellEditable(int row, int column) { + return tableModel.isCellEditable(modelIndex(row), column); + } + + public Object getValueAt(int row, int column) { + return tableModel.getValueAt(modelIndex(row), column); + } + + public void setValueAt(Object aValue, int row, int column) { + tableModel.setValueAt(aValue, modelIndex(row), column); + } + + // Helper classes + + private class Row implements Comparable { + private int modelIndex; + + public Row(int index) { + this.modelIndex = index; + } + + public int compareTo(Object o) { + int row1 = modelIndex; + int row2 = ((Row) o).modelIndex; + + for (Iterator it = sortingColumns.iterator(); it.hasNext();) { + Directive directive = (Directive) it.next(); + int column = directive.column; + Object o1 = tableModel.getValueAt(row1, column); + Object o2 = tableModel.getValueAt(row2, column); + + int comparison = 0; + // Define null less than everything, except null. + if (o1 == null && o2 == null) { + comparison = 0; + } else if (o1 == null) { + comparison = -1; + } else if (o2 == null) { + comparison = 1; + } else { + comparison = getComparator(column).compare(o1, o2); + } + if (comparison != 0) { + return directive.direction == DESCENDING ? -comparison : comparison; + } + } + return 0; + } + } + + private class TableModelHandler implements TableModelListener { + public void tableChanged(TableModelEvent e) { + // If we're not sorting by anything, just pass the event along. + if (!isSorting()) { + clearSortingState(); + fireTableChanged(e); + return; + } + + // If the table structure has changed, cancel the sorting; the + // sorting columns may have been either moved or deleted from + // the model. + if (e.getFirstRow() == TableModelEvent.HEADER_ROW) { + cancelSorting(); + fireTableChanged(e); + return; + } + + // We can map a cell event through to the view without widening + // when the following conditions apply: + // + // a) all the changes are on one row (e.getFirstRow() == e.getLastRow()) and, + // b) all the changes are in one column (column != TableModelEvent.ALL_COLUMNS) and, + // c) we are not sorting on that column (getSortingStatus(column) == NOT_SORTED) and, + // d) a reverse lookup will not trigger a sort (modelToView != null) + // + // Note: INSERT and DELETE events fail this test as they have column == ALL_COLUMNS. + // + // The last check, for (modelToView != null) is to see if modelToView + // is already allocated. If we don't do this check; sorting can become + // a performance bottleneck for applications where cells + // change rapidly in different parts of the table. If cells + // change alternately in the sorting column and then outside of + // it this class can end up re-sorting on alternate cell updates - + // which can be a performance problem for large tables. The last + // clause avoids this problem. + int column = e.getColumn(); + if (e.getFirstRow() == e.getLastRow() + && column != TableModelEvent.ALL_COLUMNS + && getSortingStatus(column) == NOT_SORTED + && modelToView != null) { + int viewIndex = getModelToView()[e.getFirstRow()]; + fireTableChanged(new TableModelEvent(TableSorter.this, + viewIndex, viewIndex, + column, e.getType())); + return; + } + + // Something has happened to the data that may have invalidated the row order. + clearSortingState(); + fireTableDataChanged(); + return; + } + } + + private class MouseHandler extends MouseAdapter { + public void mouseClicked(MouseEvent e) { + JTableHeader h = (JTableHeader) e.getSource(); + TableColumnModel columnModel = h.getColumnModel(); + int viewColumn = columnModel.getColumnIndexAtX(e.getX()); + int column = columnModel.getColumn(viewColumn).getModelIndex(); + if (column != -1) { + int status = getSortingStatus(column); + if (!e.isControlDown()) { + cancelSorting(); + } + // Cycle the sorting states through {NOT_SORTED, ASCENDING, DESCENDING} or + // {NOT_SORTED, DESCENDING, ASCENDING} depending on whether shift is pressed. + status = status + (e.isShiftDown() ? -1 : 1); + status = (status + 4) % 3 - 1; // signed mod, returning {-1, 0, 1} + setSortingStatus(column, status); + } + } + } + + private static class Arrow implements Icon { + private boolean descending; + private int size; + private int priority; + + public Arrow(boolean descending, int size, int priority) { + this.descending = descending; + this.size = size; + this.priority = priority; + } + + public void paintIcon(Component c, Graphics g, int x, int y) { + Color color = c == null ? Color.GRAY : c.getBackground(); + // In a compound sort, make each succesive triangle 20% + // smaller than the previous one. + int dx = (int)(size/2*Math.pow(0.8, priority)); + int dy = descending ? dx : -dx; + // Align icon (roughly) with font baseline. + y = y + 5*size/6 + (descending ? -dy : 0); + int shift = descending ? 1 : -1; + g.translate(x, y); + + // Right diagonal. + g.setColor(color.darker()); + g.drawLine(dx / 2, dy, 0, 0); + g.drawLine(dx / 2, dy + shift, 0, shift); + + // Left diagonal. + g.setColor(color.brighter()); + g.drawLine(dx / 2, dy, dx, 0); + g.drawLine(dx / 2, dy + shift, dx, shift); + + // Horizontal line. + if (descending) { + g.setColor(color.darker().darker()); + } else { + g.setColor(color.brighter().brighter()); + } + g.drawLine(dx, 0, 0, 0); + + g.setColor(color); + g.translate(-x, -y); + } + + public int getIconWidth() { + return size; + } + + public int getIconHeight() { + return size; + } + } + + private class SortableHeaderRenderer implements TableCellRenderer { + private TableCellRenderer tableCellRenderer; + + public SortableHeaderRenderer(TableCellRenderer tableCellRenderer) { + this.tableCellRenderer = tableCellRenderer; + } + + public Component getTableCellRendererComponent(JTable table, + Object value, + boolean isSelected, + boolean hasFocus, + int row, + int column) { + Component c = tableCellRenderer.getTableCellRendererComponent(table, + value, isSelected, hasFocus, row, column); + if (c instanceof JLabel) { + JLabel l = (JLabel) c; + l.setHorizontalTextPosition(JLabel.LEFT); + int modelColumn = table.convertColumnIndexToModel(column); + l.setIcon(getHeaderRendererIcon(modelColumn, l.getFont().getSize())); + } + return c; + } + } + + private static class Directive { + private int column; + private int direction; + + public Directive(int column, int direction) { + this.column = column; + this.direction = direction; + } + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/gui/package.html b/src/ch/ethz/infsec/secureumlgui/gui/package.html new file mode 100644 index 0000000..74d54f7 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/gui/package.html @@ -0,0 +1,10 @@ + + + + +GUI components for the SecureUML GUI. + +Basically everything that is displayed in the details pane in ArgoUML. + + + diff --git a/src/ch/ethz/infsec/secureumlgui/icons/combined_icon.png b/src/ch/ethz/infsec/secureumlgui/icons/combined_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..973cb753434ef887e653ddd3d80741ca4c969846 GIT binary patch literal 570 zcmV-A0>%A_P)Px#24YJ`L;(K){{a7>y{D4^000SaNLh0L01m_e01m_fl`9S#00007bV*G`2iXD) z4jnS|)*A@`00Fv5L_t(2&xMdZXcKW5#-I0pABlG!*Vb#&8i{DBVuMAfOE6xsxQIIG zAOvU0)DGg+%|Wz733PE$5hA!d2yUT+h}5XG3Zm_xqU8K|>v6ey{kZ!(w2Hd;n;!T* zJi`Oe^E}UE=6bzetyTe4DwRf~!M_jyk|Ze<3awVFTrL9$qv*!XTbCv;8-@u0uIp-= zCWH_|5D|b~z0Qe!d;4tj>b2|4OhhE5+;mb(00am^3J4*b-kb{Hx7*4!TH!2j_)4}fM^miF(Ak@#Im97eEN)2p8}svJ8SDorV~eg z@Xj`0VB`6O8xu40H~;>_$59lfGL?Wru(m11emkGvIdpL3Cz&d-Qb_(-Z2$lO07*qo IM6N<$f_eY?$p8QV literal 0 HcmV?d00001 diff --git a/src/ch/ethz/infsec/secureumlgui/icons/composite_full_icon.png b/src/ch/ethz/infsec/secureumlgui/icons/composite_full_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..48afae8cab142dede91ef0dea453e132190a5f8e GIT binary patch literal 230 zcmeAS@N?(olHy`uVBq!ia0vp^+(0bA!2~4z?+a-HDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(ehe3dtTpz6=aiY77hwEes65fIQUckm;<}4!>8c8YH;4 zaGy<;sEN_q(8h5k#OLt;|Nr}QWOt>#aqRhEbwlt(-_ay%F=G#o(ikt!<1!4p{yU#( T7jKpY8qMJ8>gTe~DWM4f4pu`` literal 0 HcmV?d00001 diff --git a/src/ch/ethz/infsec/secureumlgui/icons/constrained_icon.png b/src/ch/ethz/infsec/secureumlgui/icons/constrained_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..40e4dc58ea758cfa73fb0fcc2a896cf84e3059fe GIT binary patch literal 222 zcmeAS@N?(olHy`uVBq!ia0vp^tUxTn!2~2vwI}odDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB!W~bBzpw;GB8xBF)%c=FfjZA3N^f7U???UV0e|lz+g3lfkC`r&aOZkpaf@u zM`SSr1K$x4W}K?cCk+&I_jGX#(Fjhi`1vW-&5ezjnRx=sCP$G8%t?){689Pp9&YDv ztcj107x;gum7C+MgWUvX7J=3Pu0xHVEPx#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy32;bRa{vGi!~g&e!~vBn4jTXf0vAa{K~yMHV|@4S9RnCFSg_#i z*|Y5I?7x2fa&vR@@$rF(GXPb*c=5u(z#uw0ddie33l}b&ICZLptzAl5`i~z!LHfUc z|88ez=j-bm8ynl$)>+-!8D?+isiq{s&)w424pOmm=T2p1Wp8h9V_WAiO__Eh;k{nM z&r3A6#){;IJH7k(g&{aNSX*1$)Y3M@Sn~gTgZ~Rn{;#n9Ki~9Yheo9x|CviS7)(t~ zRaI4`l{KdY$iHsTdeNl)s#*I*qxRKY#bR^8{l`u-xVX3oi-?GbOH6kYKa;F*GFj<# zs?v!h#a)3Si3ZX~PoHA|x*zBxHeP`^4gSMH(mR4=b_UDr2$G&_!WL|9aPHD&kZ&_H zGg(*|f$C!9Sm#>`&$keotH%~9$ThjI3*;9d27->BiJS(t-i#bo3=Aa<429C_+CE$D zE9OI0+<*SrIQmKHl>d&EZ(CNs>)ZNi-tGV1mCv#o|C=TsVEFRwhkM$U=)C_qt^d-y zzlQbP-T31FmY4s{<8A;|7>C^g*&=0kDJ<<@Z1LaR_Wz!lFI#pzpMB}QTjHD8oc}t( zH$f`cjE*@(z70$NA6xi8z52g@(+WYI<`{XE)7O>#CX=wZl&M|a@o1oskEe@ch{pNk zn(yyqnd1%|ao`XLJIIvI$;qkceIR#vn{H1=ouH7Ald$3~9+Pw>>uIc)KQ=Wry}!Tz s_$qc+*=ZjRtm5nToRMa5N%a{+-7BTr+j`|HfaWrIy85}Sb4q9e0LWWD9RL6T literal 0 HcmV?d00001 diff --git a/src/ch/ethz/infsec/secureumlgui/icons/implicit_icon.png b/src/ch/ethz/infsec/secureumlgui/icons/implicit_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..f43a0d1da8b93811c6bf930e4b65606fef312ee5 GIT binary patch literal 235 zcmeAS@N?(olHy`uVBq!ia0vp^+(0bA!2~4z?+a-HDaPU;cPEB*=VV?2IV|apzK#qG z8~eHcB(ehe3dtTpz6=aiY77hwEes65fI*^d*R?QhqphFxzp=QpHaxl9 zQS*c?K~OC#FYicDYf0G6V;^4xHJ?d6Zmo33t?hN@x>Yji)8}hFOP*VD{PE(i9DD!A Zu$uQepZT)zbQjQk22WQ%mvv4FO#nbgOJ4v0 literal 0 HcmV?d00001 diff --git a/src/ch/ethz/infsec/secureumlgui/icons/inherited_icon.png b/src/ch/ethz/infsec/secureumlgui/icons/inherited_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..459f19ef116fb8a7ffaae0e19a51c9dc5204658e GIT binary patch literal 686 zcmV;f0#W^mP)Px#1ZP1_K>z@;j|==^1poj5AY({UO#lFTCIA3{ga82g0001h=l}q9FaQARU;qF* zm;eA5aGbhPJOBUy32;bRa{vGi!~g&e!~vBn4jTXf0vAa{K~yMHV|@4S9RnCFSg_#i z*|Y5I?7x2fa&vR@@$rF(GXPb*c=5u(z#uw0ddie33l}b&ICZLptzAl5`i~z!LHfUc z|88ez=j-bm8ynl$)>+-!8D?+isiq{s&)w424pOmm=T2p1Wp8h9V_WAiO__Eh;k{nM z&r3A6#){;IJH7k(g&{aNSX*1$)Y3M@Sn~gTgZ~Rn{;#n9Ki~9Yheo9x|CviS7)(t~ zRaI4`l{KdY$iHsTdeNl)s#*I*qxRKY#bR^8{l`u-xVX3oi-?GbOH6kYKa;F*GFj<# zs?v!h#a)3Si3ZX~PoHA|x*zBxHeP`^4gSMH(mR4=b_UDr2$G&_!WL|9aPHD&kZ&_H zGg(*|f$C!9Sm#>`&$keotH%~9$ThjI3*;9d27->BiJS(t-i#bo3=Aa<429C_+CE$D zE9OI0+<*SrIQmKHl>d&EZ(CNs>)ZNi-tGV1mCv#o|C=TsVEFRwhkM$U=)C_qt^d-y zzlQbP-T31FmY4s{<8A;|7>C^g*&=0kDJ<<@Z1LaR_Wz!lFI#pzpMB}QTjHD8oc}t( zH$f`cjE*@(z70$NA6xi8z52g@(+WYI<`%A_P)Px#24YJ`L;wH)0002_L%V+f000SaNLh0L01m_e01m_fl`9S#00007bV*G`2iXG* z4>1i#BOV<900Fv5L_t(2&s~qdi{d~W#lIOxk_kjptqKZ)m4w_DR_SaMK?^Ip+g@&K zLAb_3xUKB1wDE7S+QP=lMzB$cAsP!whG;?@2O(Dodp}c3gSeAut+vc2~ z&u7ChPNx(6t1t|4I-TC{_Xwf;{eCzc{v(pfBx<+YuIoloWSZvndi8z(Z$cDBppFvw=JK@hyWyqKn`>-x9X*IyqW0KgbSjIr%@%Q^Rb zKaOL^an|egvxQRncsvA3X{}b%G)+}iLI@#*F(wGY?RJZzXt`Ws0LbU_wr#tvO9;Uj z-)=WbsVvK!^J=v!P)a?|o6qNA7(QPJf*{LsE|<$>GP disabledLoggers = new HashSet(); + + public boolean isLoggerContextDisabled(LoggerContext context) + { + return disabledLoggers.contains(context); + } + + + public void enableLoggerContext(LoggerContext context) + { + disabledLoggers.remove(context); + } + + public void disableLoggerContext(LoggerContext context) + { + //disabledLoggers.add(context); + } + + + /** + * @param context + * + */ + private void logContext(LoggerContext context) + { + if(getGlobalCurrentContext() != context) + { + if(defaultContext == null) + { + setIndent(indent = " "); + } + else + { + setIndent(""); + log(" o ");// + getCurrentContext().getLongName() + " "); + } + + if(context != null) + { + setIndent(indent = ""); + log(""); + log("-+ <<< " + context.getLongName() + " >>>"); + //System.out.println(""); + //setCurrentContext(context); + setGlobalCurrentContext(context); + setIndent(indent = " |- "); + setAdditionalLineIndent(" | "); + } + } + else + { + ; + } + + } + + + /* Global Properties */ + + private static LoggerContext globalCurrentContext = null; + + public static LoggerContext getGlobalCurrentContext() + { + return globalCurrentContext; + } + + public static void setGlobalCurrentContext(LoggerContext globalCurrentContext) + { + MultiContextLogger.globalCurrentContext = globalCurrentContext; + } + + /* Logger Properties */ + + + private LoggerContext defaultContext = null; + public LoggerContext getDefaultContext() + { + return defaultContext; + } +// public void setCurrentContext(LoggerContext currentContext) +// { +// this.defaultContext = currentContext; +// } + + //Set loggerContexts = new HashSet(); + + /* standard logging */ + + public void log(int type, LoggerContext context, String message) + { +// if(context != null && !isLoggerContextDisabled(context)) +// { + logContext(context); +// + super.log(type, message); +// } +// +// else +// ; + } + + public void log(int type, String message) + { + logContext(getDefaultContext()); + super.log(type, message); + } + +// public void log(String message) +// { +// logContext(getCurrentContext()); +// super.log(message); +// } + + public void info(String message) + { + //For release, just log warnings and errors, not informational messages. + log(2,message); + } + public void warn(String message) + { + log(1,message); + } + public void error(String message) + { + log(0,message); + } + + /* special debug logging */ + + /** standard logging action when an Exception occurred + * (to call from 'catch' or 'finally' blocks) + */ + public void logException(Exception e) + { + //if(debug) + { + try + { + e.printStackTrace(); + } + catch (Exception ex) + { + ex.printStackTrace(); + } + } + } + + /** log Method to call from unimplemented Methods + * (currently used from unimplemented Methods + * in my Implementations of the JMI Interfaces) + */ + public void logUnimplemented() + { + try + { + throw new NotImplementedException(); + } + catch (Exception e) + { + logException(e); + } + } + + public void logUnimplemented(LoggerContext context) + { + if(context != null && !isLoggerContextDisabled(context)) + { + try + { + throw new NotImplementedException(); + } + catch (Exception e) + { + log(ERROR, MY_JMI_IMPL, e.getStackTrace().toString()); + } + } + else + ; + } + + public void logCallstack() + { + try + { + throw new Exception(); + } + catch (Exception e) + { + logException(e); + } + } + + + /* shortcuts */ + + + public void info(LoggerContext context, String message) + { + if(context != null && !isLoggerContextDisabled(context)) + { + //logContext(context); + + // log(INFORMATIONAL, context, message); + } + + } + + public void warn(LoggerContext context, String message) + { + if(context != null && !isLoggerContextDisabled(context)) + { + //logContext(context); + + log(WARNING, context, message); + } + + } + + public void error(LoggerContext context, String message) + { + if(context != null && !isLoggerContextDisabled(context)) + { + // logContext(context); + + log(ERROR, context, message); + } + + } + + + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/logging/SimpleLogger.java b/src/ch/ethz/infsec/secureumlgui/logging/SimpleLogger.java new file mode 100644 index 0000000..5971baf --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/logging/SimpleLogger.java @@ -0,0 +1,309 @@ +package ch.ethz.infsec.secureumlgui.logging; + +import java.util.ArrayList; + + +public class SimpleLogger implements SimpleMessageSink +{ + public SimpleLogger() + { + ; + } + + + /* Types */ + public static final int ERROR = 0; + public static final int WARNING = 1; + public static final int INFORMATIONAL = 2; + + + + /* Logger Properties */ + + protected boolean verbose = true; + public void setVerbose(boolean verbose) { + this.verbose = verbose; + } + public boolean isVerbose() { + return verbose; + } + + private int maxCharactersPerLine = 78; + + public int getMaxCharactersPerLine() + { + return maxCharactersPerLine; + } + + //@require maxCharactersPerLine>10 + public void setMaxCharactersPerLine(int maxCharactersPerLine) + { + this.maxCharactersPerLine = maxCharactersPerLine; + } + + + protected String indent = " "; + protected String additionalLineIndent = " "; + + public String getAdditionalLineIndent() + { + return additionalLineIndent; + } + public void setAdditionalLineIndent(String additionalLineIndent) + { + this.additionalLineIndent = additionalLineIndent; + if(additionalLineIndent == null) + additionalLineIndent = ""; + } + public String getIndent() + { + return indent; + } + public void setIndent(String indent) + { + this.indent = indent; + if(indent == null) + this.indent = ""; + } + + + /* standard logging */ + + protected void log(String message) + { + + try + { + printString(message); + //System.out.println(message); + } + catch (Exception e) + { + // TODO: handle exception + e.printStackTrace(); + } + + } + + public void log(int type, String message) + { + String out_message = ""; + try + { + switch (type) { + case 0: + out_message += "[ERROR] " + message; + break; + case 1: + out_message += "[WARN] " + message; + break; + case 2: + out_message += "[INFO] " + message; + break; + } + } + catch (Exception e) + { + // TODO: handle exception + e.printStackTrace(); + } + log(out_message); + } + + +// public void printString(String s) +// { +// try +// { +// if(s!=null) +// { +// +// +// if(s.length() <= maxCharactersPerLine) +// { +// System.out.println(indent + s); +// } +// else +// { +// +// while(s.length() > maxCharactersPerLine) +// { +// System.out.println(additionalLineIndent + s.substring(0, maxCharactersPerLine)); +// s = s.substring(maxCharactersPerLine); +// } +// +// System.out.println(additionalLineIndent + s); +// } +// +// } +// } +// catch (Exception e) +// { +// e.printStackTrace(); +// } +// } + + // advanced multiline support + public void printString(String s) + { + if(maxCharactersPerLine < 1) + return; + try + { + if(s!=null) + { + + String[] lines = s.split("\n"); + + //if(lines.length > 1) + //System.out.println("@@@@@ logging " + lines.length + " lines"); + + String firstline = lines[0]; + int startindex = 0; + // print first line - with original indent + if(firstline.length() <= maxCharactersPerLine) + { + System.out.println(indent + firstline); + startindex = 1; + } + else + { + System.out.println(indent + firstline.substring(0, maxCharactersPerLine)); + lines[0] = firstline.substring(maxCharactersPerLine); + startindex = 0; + } + + // print other lines with empty indent + // one longer than the orignial indent + for (int i = startindex; i < lines.length; i++) + { + String line = lines[i]; + while(line.length() > maxCharactersPerLine) + { + System.out.println(additionalLineIndent + line.substring(0, maxCharactersPerLine)); + line = line.substring(maxCharactersPerLine); + } + + System.out.println(additionalLineIndent + line); + } + } + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + // advanced multiline support +// public void printString(String s) +// { +// try +// { +// if(s!=null) +// { +// System.out.println(s); +// ArrayList lines = split(s, '\n'); +// lines = split(s, '\r'); +// +// if(lines.size() > 1) +// System.out.println("@@@@@ logging " + lines.size() + " lines"); +// +// String firstline = lines.get(0); +// // print first line - with original indent +// if(firstline.length() <= maxCharactersPerLine) +// { +// System.out.println(indent + firstline); +// } +// else +// { +// System.out.println(indent + s.substring(0, maxCharactersPerLine)); +// firstline = firstline.substring(maxCharactersPerLine); +// +// lines.set(0, firstline); +// // print other lines with empty indent +// // one longer than the orignial indent +// for (int i = 0; i < lines.size(); i++) +// { +// String line = lines.get(i); +// while(line.length() > maxCharactersPerLine) +// { +// System.out.println(additionalLineIndent + line.substring(0, maxCharactersPerLine)); +// line = line.substring(maxCharactersPerLine); +// } +// +// System.out.println(additionalLineIndent + line); +// } +// } +// } +// } +// catch (Exception e) +// { +// e.printStackTrace(); +// } +// } + + /* shortcuts */ + + public void info(String s) { + if (verbose) + { + log(INFORMATIONAL, s); + } + } + + public void warning(String s) { + log(WARNING, s); + } + + public void error(String s) { + log(ERROR, s); + } + + public void error(Exception e) { + log(ERROR, e.toString()); + + try + { + e.printStackTrace(); + } + catch (Exception ex) + { + // TODO: handle exception + ex.printStackTrace(); + } + } + + + public ArrayList split(String s, Character c) + { + ArrayList lines = new ArrayList(); + + while(s.length() > 1 && s.indexOf(c)>=0) + { + + if(s.indexOf(c) == 0) + { + s = s.substring(1); + } + else + { + String line = s.substring(0, s.indexOf(c)); + lines.add(line); + + s = s.substring(s.indexOf(c)); + } + } + lines.add(s); + + return lines; + + } + + + /* simplemessagesink */ + + public void processMessage(String s) { + info(s); + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/logging/SimpleMessageSink.java b/src/ch/ethz/infsec/secureumlgui/logging/SimpleMessageSink.java new file mode 100644 index 0000000..cefca38 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/logging/SimpleMessageSink.java @@ -0,0 +1,7 @@ +package ch.ethz.infsec.secureumlgui.logging; + +public interface SimpleMessageSink +{ + void processMessage(String arg); + +} diff --git a/src/ch/ethz/infsec/secureumlgui/main/ClassLoaderProviderImpl.java b/src/ch/ethz/infsec/secureumlgui/main/ClassLoaderProviderImpl.java new file mode 100644 index 0000000..649226f --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/main/ClassLoaderProviderImpl.java @@ -0,0 +1,44 @@ +package ch.ethz.infsec.secureumlgui.main; + +//import org.argouml.uml.reveng.ImportClassLoader; +import org.netbeans.mdr.handlers.ClassLoaderProvider; + +import ch.ethz.infsec.secureumlgui.securemodel.SecureModelPackage; +//import ch.ethz.infsec.secureumlgui.securemodelimpl.SecureModelFactory; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; + +import org.argouml.application.Main; + +public class ClassLoaderProviderImpl implements ClassLoaderProvider +{ + + private MultiContextLogger logger = new MultiContextLogger( + MultiContextLogger.STARTUP); + + + public ClassLoaderProviderImpl() { + super(); + logger.info("ClassLoaderProviderImpl constructed"); + } + + public ClassLoader getClassLoader() + { + + //return ImportClassLoader.getSystemClassLoader(); + logger.info("*** ClassLoaderProvider invoked - returned Classlodader: " + + Main.class.getClassLoader()); + + + return Main.class.getClassLoader(); + } + + public Class defineClass(String className, byte[] classFile) + { + //return this.getClassLoader().defineClass(className, classFile, 0, classFile.length); + // TODO Auto-generated method stub + logger.info("*** defineClass called!"); + //return this.getClassLoader().defineClass(arg0, arg1, 0, arg0.length()); + return null; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/main/FileLoader.java b/src/ch/ethz/infsec/secureumlgui/main/FileLoader.java new file mode 100644 index 0000000..9909592 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/main/FileLoader.java @@ -0,0 +1,84 @@ +package ch.ethz.infsec.secureumlgui.main; + +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; + +public class FileLoader { + + private static MultiContextLogger logger = new MultiContextLogger(); + + public static File loadXmiFromArgoFile(String inputFile) { + try { + // load the .argo file + File argoFile = loadFile(inputFile); + // extract the xmi file + String argoName = argoFile.getName(); + String baseName = argoName.substring(0, argoName.indexOf(".")); + File temp = File.createTempFile(baseName, ".xmi"); + temp.deleteOnExit(); + ZipFile argoZipFile = new ZipFile(argoFile); + ZipEntry xmiFile = argoZipFile.getEntry(baseName + ".xmi"); + if (xmiFile != null) { + argoZipFile.getInputStream(xmiFile); + copyInputStream(argoZipFile.getInputStream(argoZipFile + .getEntry(baseName + ".xmi")), + new BufferedOutputStream(new FileOutputStream(temp))); + argoZipFile.close(); + return temp; + } + logger + .error("invalid argo file, does not contain a xmi file named " + + baseName + ".xmi"); + return null; + } catch (IOException ioe) { + System.err.println("Unhandled exception:"); + ioe.printStackTrace(); + } + return null; + } + + public static File loadFile(String fileName) { + if (fileName == null || fileName.equals("")) { + return null; + } + try { + File file = new File(fileName); + return file; + } catch (Exception e) { + logger.error("could not load " + fileName); + return null; + } + } + + public static File createFile(String fileName) { + try { + File file = loadFile(fileName); + file.createNewFile(); + return file; + } catch (Exception e) { + logger.error("could not load " + fileName); + return null; + } + } + + private static void copyInputStream(InputStream in, OutputStream out) + throws IOException { + byte[] buffer = new byte[1024]; + int len; + + while ((len = in.read(buffer)) >= 0) + out.write(buffer, 0, len); + + in.close(); + out.close(); + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/main/SecureUmlConstants.java b/src/ch/ethz/infsec/secureumlgui/main/SecureUmlConstants.java new file mode 100644 index 0000000..c88d677 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/main/SecureUmlConstants.java @@ -0,0 +1,193 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.main; + +import org.omg.uml.foundation.core.Classifier; + +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ResourceType; + +/** + * + * SecureUml-related Constants used by several Classes + */ +public class SecureUmlConstants +{ +// public static final String STEREOTYPE_COMPUML_ENTITY = "compuml.entity"; + + public static final String BASE_CLASS = "Class"; + public static final String BASE_ASSOCCLASS = "AssociationClass"; + + + public static enum SECUML_STEREOTYPES { + STEREOTYPE_SECUML_USER ( "secuml.user", BASE_CLASS ), + STEREOTYPE_SECUML_ROLE ( "secuml.role", BASE_CLASS), + STEREOTYPE_SECUML_RESOURCE ( "secuml.resource", null ), + STEREOTYPE_SECUML_ACTIONTYPE ( "secuml.actiontype", null ), + STEREOTYPE_SECUML_PERMISSION ( "secuml.permission", BASE_ASSOCCLASS ), + STEREOTYPE_SECUML_CONSTRAINT ( "secuml.constraint", null ), + STEREOTYPE_SECUML_POLICY ( "secuml.policy", BASE_CLASS ); + + private String value; + private String base; + + SECUML_STEREOTYPES ( String value, String baseClass) { + this.value = value; + this.base = baseClass; + } + + public String toString() { + return value; + } + + public String getBase() { + return base; + } + } + + + public static enum UML_OCL { + OCL_ANY ("OclAny", new UML_OCL[] {}), +// OCL_TYPE ("OclType", new UML_OCL[] {OCL_ANY}), +// OCL_STATE ("OclState", new UML_OCL[] {OCL_ANY}), +// OCL_MODELELEMENT ("OclModelElement", new UML_OCL[] {OCL_ANY}), + OCL_BOOLEAN ("Boolean", new UML_OCL[] {OCL_ANY}), + OCL_REAL ("Real", new UML_OCL[] {OCL_ANY}), + OCL_STRING ("String", new UML_OCL[] {OCL_ANY}), + OCL_INTEGER ("Integer", new UML_OCL[] {OCL_REAL}), +// OCL_VOID ("OclVoid", new UML_OCL[] {OCL_TYPE, OCL_STATE, OCL_MODELELEMENT, +// OCL_BOOLEAN, OCL_INTEGER, OCL_STRING}); + OCL_VOID ("OclVoid", new UML_OCL[] {OCL_BOOLEAN, OCL_INTEGER, OCL_STRING}); + private String value; + private UML_OCL superTypes[]; + + UML_OCL (String value, UML_OCL superTypes[]) { + this.value = value; + this.superTypes = superTypes; + } + + public String toString() { + return this.value; + } + + public UML_OCL[] getSuperTypes() { + return this.superTypes; + } + } + + + public static final String STEREOTYPE_SECUML_PERMISSION = SECUML_STEREOTYPES.STEREOTYPE_SECUML_PERMISSION.toString(); + + //public static final String STEREOTYPE_SECUML_EXCP_PERMISSION = "secuml.excppermission"; + + public static final String STEREOTYPE_SECUML_POLICY = SECUML_STEREOTYPES.STEREOTYPE_SECUML_POLICY.toString(); + + public static final String STEREOTYPE_SECUML_ROLE = SECUML_STEREOTYPES.STEREOTYPE_SECUML_ROLE.toString(); + + public static final String STEREOTYPE_SECUML_ACTIONTYPE = SECUML_STEREOTYPES.STEREOTYPE_SECUML_ACTIONTYPE.toString(); + +// public static final String STEREOTYPE_ENTITY_ATTRIBUTE_ACTION = "dialect.entityattributeaction"; +// +// public static final String STEREOTYPE_ENTITY_ACTION = "dialect.entityaction"; +// +// public static final String STEREOTYPE_ENTITY_OPERATION_ACTION = "dialect.entityoperationaction"; + + public static final String STEREOTYPE_SECUML_CONSTRAINT = SECUML_STEREOTYPES.STEREOTYPE_SECUML_CONSTRAINT.toString(); + + public static final String STEREOTYPE_SECUML_RESOURCE = SECUML_STEREOTYPES.STEREOTYPE_SECUML_RESOURCE.toString(); + + public static final String STEREOTYPE_SECUML_USER = SECUML_STEREOTYPES.STEREOTYPE_SECUML_USER.toString(); + + public static final String STEREOTYPE_OCL_TYPE = "ocltype"; + + + + public static final String TAG_DEFINITION_AUTHORIZATION_CONSTRAINT = "authorizationConstraint"; + + private static ResourceType permissionResourceTypeDummy; + //private static ResourceType excpPermissionResourceTypeDummy; + private static ResourceType roleResourceTypeDummy; + //private static ResourceType excpLevelResourceTypeDummy; + private static ResourceType policyResourceTypeDummy; + + public static final String NEW_PERMISSION_SUFFIX = "Perm"; + + //public static final String AuthorizationConstraintTagName = "AuthorizationConstraint"; + + + + public static final String UML_CLASS = "UmlClass"; + public static final String UML_ASSOCIATION = "AssociationClass"; + + public static final String ROLE_NAME = "Role"; + public static final String ROLE_CLASSNAME = UML_CLASS; + + public static final String POLICY_NAME = "Policy"; + public static final String POLICY_CLASSNAME = UML_CLASS; + public static final String DEFAULT_POLICY_NAME = "DefaultPolicy"; + + public static final String POLICY_INHERITANCE_REFINEDBY = "refinedBy"; + public static final String POLICY_INHERITANCE_REFINES = "refines"; + + public static final String PERMISSION_NAME = "Permission"; + public static final String PERMISSION_CLASSNAME = UML_ASSOCIATION; + + + public static final String PACKAGE_SECUML = "secUML"; + public static final String PACKAGE_PERMISSIONS = "permissions"; + public static final String PACKAGE_OCL ="UML_OCL"; + + + + + + /** + * @return the permissionResourceTypeDummy + */ + public static ResourceType getPermissionResourceTypeDummy() + { + if(permissionResourceTypeDummy == null) + { + permissionResourceTypeDummy = new ResourceType(); + + permissionResourceTypeDummy.setName(PERMISSION_NAME); + permissionResourceTypeDummy.setUmlClassName(PERMISSION_CLASSNAME); + permissionResourceTypeDummy.setModelElementStereotype( + SecureUmlConstants.STEREOTYPE_SECUML_PERMISSION); + } + return permissionResourceTypeDummy; + } + + + + public static ResourceType getPolicyResourceTypeDummy() { + if ( policyResourceTypeDummy == null ) { + + policyResourceTypeDummy = new ResourceType(); + + policyResourceTypeDummy.setName(POLICY_NAME); + policyResourceTypeDummy.setUmlClassName(POLICY_CLASSNAME); + policyResourceTypeDummy.setModelElementStereotype(STEREOTYPE_SECUML_POLICY); + } + return policyResourceTypeDummy; + } + + + + + public static ResourceType getRoleResourceTypeDummy() + { + if(roleResourceTypeDummy == null) + { + roleResourceTypeDummy = new ResourceType(); + + roleResourceTypeDummy.setName(ROLE_NAME); + roleResourceTypeDummy.setUmlClassName(ROLE_CLASSNAME); + roleResourceTypeDummy.setModelElementStereotype( + SecureUmlConstants.STEREOTYPE_SECUML_ROLE); + //roleResourceTypeDummy.setAnchorPath("self"); + } + return roleResourceTypeDummy; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmanagement/ExtentInfo.java b/src/ch/ethz/infsec/secureumlgui/modelmanagement/ExtentInfo.java new file mode 100644 index 0000000..0abfa2a --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmanagement/ExtentInfo.java @@ -0,0 +1,36 @@ +package ch.ethz.infsec.secureumlgui.modelmanagement; + +public class ExtentInfo { + + private final String name; + + private final String topPackage; + + private final Class type; + + private final String metamodelName; + + public ExtentInfo(String name, String topPackage, String metamodelName, Class type) { + this.name = name; + this.topPackage = topPackage; + this.type = type; + this.metamodelName = metamodelName; + } + + public String getName() { + return name; + } + + public String getTopPackage() { + return topPackage; + } + + public Class getType() { + return type; + } + + public String getMetaModelName() { + return metamodelName; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmanagement/ModelConst.java b/src/ch/ethz/infsec/secureumlgui/modelmanagement/ModelConst.java new file mode 100644 index 0000000..9987571 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmanagement/ModelConst.java @@ -0,0 +1,68 @@ +package ch.ethz.infsec.secureumlgui.modelmanagement; + +import ch.ethz.infsec.secureumlgui.main.SecureUmlConstants; +import ch.ethz.infsec.secureumlgui.modelmanagement.OclModelInfo.MetaModelName; +import ch.ethz.infsec.secureumlgui.securemodel.SecureModelPackage; + +public class ModelConst { + + // note: xmi files must be given as absolute path vs. ocl files must be + // given as URI + private static final String BASE = System.getProperty("user.dir"); + + private static final String URI_BASE = "file:" + BASE; + + public static final OclModelInfo seccompuml; + + public static final ExtentInfo secureuml_componentuml_extent; + + static { + // metamodel extents + secureuml_componentuml_extent = new ExtentInfo( + "securityModel"/* name */, "SecureModel"/* packagename */, + "su2holocl_metamodel"/* metamodel */, SecureModelPackage.class/* type */); + + // secureuml/componentuml metamodel + seccompuml = new OclModelInfo(URI_BASE + + "/metamodels/securecomponentuml/securecomponentuml_mof.xmi", + BASE + "/metamodels/securecomponentuml/securecomponentuml.ocl", + "securecomponentuml", MetaModelName.MOF14); + } + + public static final String SECUREUML_TYPES_PACKAGE = "UML_OCL"; + + public static final String ENVIRONMENTPACKAGE_NAME = "AuthorizationEnvironment"; + + // additional + public static final String SECUREUML_PACKAGE_NAME = "SecureUML"; + + public static final String SECUREMODEL_PACKAGE_NAME = "SecureModel"; + public static final String SECUREMODEL_EXTENT_NAME = "SecureModel"; + public static final String SECUREMODEL_INSTANCE_NAME = "mySecureModel"; + public static final String DIALECT_PACKAGE_NAME_PART = "dialect"; + public static final String DIALECT_PACKAGE_SUFFIX = "Dialect"; + + public static final String SECUREUML_RESOURCE_NAME = "Resource"; + public static final String SECUREUML_ACTION_NAME = "ActionClass"; + public static final String SECUREUML_ATOMIC_ACTION_NAME = "AtomicAction"; + public static final String SECUREUML_COMPOSITE_ACTION_NAME = "CompositeAction"; + + @Deprecated + public static final String STEREOTYPE_SECUML_ACTIONTYPE = SecureUmlConstants.STEREOTYPE_SECUML_ACTIONTYPE; //"secuml.actiontype"; + + @Deprecated + public static final String STEREOTYPE_SECUML_ROLE = SecureUmlConstants.STEREOTYPE_SECUML_ROLE; + + @Deprecated + public static final String STEREOTYPE_SECUML_PERMISSION = SecureUmlConstants.STEREOTYPE_SECUML_PERMISSION; + + + + + public static String getDialectPackageName(String dialectName) + { + return dialectName + DIALECT_PACKAGE_SUFFIX; + } + + public static final String ACTION_RESOURCE_ASSOCIATION_NAME = "actionResource"; +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmanagement/OclModelInfo.java b/src/ch/ethz/infsec/secureumlgui/modelmanagement/OclModelInfo.java new file mode 100644 index 0000000..0a59f99 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmanagement/OclModelInfo.java @@ -0,0 +1,50 @@ +package ch.ethz.infsec.secureumlgui.modelmanagement; + +public class OclModelInfo { + + public static enum MetaModelName { + UML15, MOF14 + } + + private final String xmi; + + private final String name; + + private MetaModelName metaModelName; + + private String oclUri; + + public OclModelInfo(String xmi, String oclUri, String name, MetaModelName metaModelName) { + this.xmi = xmi; + this.name = name; + this.metaModelName = metaModelName; + this.oclUri = oclUri; + } + + public String getName() { + return name; + } + + public String getXmi() { + return xmi; + } + + public MetaModelName getMetaModelName() { + return metaModelName; + } + + public String getMetaModelNameString() { + switch (metaModelName) { + case MOF14: + return "MOF14"; + case UML15: + return "UML15"; + } + return null; + } + + public String getOclUri() { + return oclUri; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/GenericDialectHelper.java b/src/ch/ethz/infsec/secureumlgui/modelmapping/GenericDialectHelper.java new file mode 100644 index 0000000..7b1f94e --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/GenericDialectHelper.java @@ -0,0 +1,1829 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.modelmapping; + +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.Set; + +import javax.jmi.reflect.RefObject; + + +import org.apache.log4j.Logger; +import org.argouml.model.Model; +import org.omg.uml.foundation.core.AssociationClass; +import org.omg.uml.foundation.core.Classifier; +import org.omg.uml.foundation.core.ModelElement; +import org.omg.uml.foundation.core.Namespace; +import org.omg.uml.foundation.core.Stereotype; +import org.omg.uml.foundation.core.UmlClass; +import ch.ethz.infsec.secureumlgui.Util; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ActionType; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.AssociationEnd; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.DialectMetaModelInfo; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.InterResourceAssociation; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.MetaModelClass; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.MetaModelConst; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ResourceType; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions.OclEvaluatorException; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions.OclExpression; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions.OclExpressionEvaluator; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions.OclExpressionsParser; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions.OclUmlExpressionEvaluator; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.main.SecureUmlConstants; +import ch.ethz.infsec.secureumlgui.transformation.MetaModelMap; +import ch.ethz.infsec.secureumlgui.transformation.ModelMap; +import ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper; + +/** + * + */ +public class GenericDialectHelper +{ + /** + * + */ + // public GenericDialectHelper(DialectMetaModelInfo mmInfo)//, MetaModelMap map) + // { + // this.dialectMetaModelInfo = mmInfo; + // + // this.map = MetaModelMap.getDefault(); + // } + /** + * + */ + private GenericDialectHelper() + { + this.map = MetaModelMap.getDefault(); + + logger.disableLoggerContext(logger.MODELMAPPER_DETAILLED); + + } + + static private GenericDialectHelper instance; + + static public GenericDialectHelper getInstance() + { + if (instance == null) + instance = new GenericDialectHelper(); + + return instance; + } + + DialectMetaModelInfo dialectMetaModelInfo; + + MetaModelMap map; + + MultiContextLogger logger = MultiContextLogger.getDefault(); + + private static Logger aLog = Logger.getLogger(GenericDialectHelper.class); + + public MetaModelClass getMetaModelClass(ModelElement m) + { + if (m == null || dialectMetaModelInfo == null) { + aLog.debug("getMetaModelClass: ModelElement or dialectMetaModelInfo == null (" + m + ")"); + return null; + } + + Collection mmcs = dialectMetaModelInfo + .getMetaModelClasses(); + + + for (MetaModelClass mmc : mmcs) + { + String umlClassNameTag = mmc.getUmlClassName(); + + if (hasType(m, umlClassNameTag)) + { + return mmc; + } + } + + // if mmc not found until here + + return getResourceType(m); + } + + + /** If the UML Modelelement m represents a SecureUML element + * (Role, Permission, Policy or Resource), this function returns it's + * Resourcetype. + * + * For roles and permissions, dummy resourcetypes + * are created. + */ + public ResourceType getSecureUmlType(ModelElement m) + { + if(isSecureUmlRole(m)) { + return SecureUmlConstants.getRoleResourceTypeDummy(); + } + else if(isSecureUmlPermission(m)) { + return SecureUmlConstants.getPermissionResourceTypeDummy(); + } + else if(isSecureUmlPolicy(m)) { + return SecureUmlConstants.getPolicyResourceTypeDummy(); + } + else { // is the target a resource? + return getResourceType(m); + } + } + + /** + * If the UML ModelElement m represents a SecureUML-Resource, this function + * examines and returns it's ResourceType - otherwise returns null. + * + * @param m + * UML ModelElement + * @return The ResourceType of m if exists, null otherwise + */ + public ResourceType getResourceType(ModelElement m) { + + if (m == null || dialectMetaModelInfo == null) + return null; + + for (ResourceType resourceType : dialectMetaModelInfo.getResourceTypes() ) { + // Assume m is of Resource-Type r + + logger.info(MultiContextLogger.MODELMAPPER_DETAILLED, "is " + + m.getName() + " a " + resourceType.getName() + "?"); + + if (!hasType(m, resourceType.getUmlClassName())) { + logger.info(MultiContextLogger.MODELMAPPER_DETAILLED, + "no! (wrong class: " + m.getClass().getSimpleName()); + continue; + } + // if anchorPath == 'self' + + String anchorPath = resourceType.getAnchorPath(); + String modelElementStereotype = resourceType.getModelElementStereotype(); + + if (hasStereotype(m, modelElementStereotype)) { + resourcePath = m.getName(); + logger.info(MultiContextLogger.MODELMAPPER_DETAILLED, + "ModelElement " + m.getName() + " is of ResourceType " + + resourceType.getName()); + logger.info(MultiContextLogger.MODELMAPPER_DETAILLED, + "... yes, marked explicitly!"); + // found the right resource Type + return resourceType; + } else if (modelElementStereotype == null + || modelElementStereotype.length() == 0) { + ModelElement anchor = findAnchor(m, resourceType); + + ResourceType anchorType = getResourceType(anchor); + + if (anchor != null + && anchorType != null + && hasStereotype(anchor, anchorType + .getModelElementStereotype())) { + String anchorName = Util.getProperty(anchor, "name") + .toString(); + // logger.info("ModelElement " + // + m.getName() + // + " is of ResourceType " + // + r.getName()); + // found the right Resource Type + logger.info(MultiContextLogger.MODELMAPPER_DETAILLED, + "... yes, implicitly " + "- because the anchor '" + + anchorName + "' is a resource!"); + return resourceType; + } + } + } + // else + // - if arrived here, + // the ModelElement m is not a ResourceType + + // Collection mmClasses = + // dialectMetaModelInfo.getMetaModelClasses(); + // for (Iterator iter = mmClasses.iterator(); iter.hasNext();) + // { + // MetaModelClass mmClass = (MetaModelClass) iter.next(); + + // logger.info(MultiContextLogger.MODELMAPPER_DETAILLED, "is " + // + m.getName() + " a " + mmClass.getName() + "?"); + + // if (hasType(m, mmClass.getUmlClassName())) + // { + // logger.info(MultiContextLogger.MODELMAPPER_DETAILLED, + // "ModelElement " + m.getName() + // + " is of MetamodelClass " + mmClass.getName()); + + // } + // } + + logger.info(MultiContextLogger.MODELMAPPER_DETAILLED, "... no!"); + + return null; + } + + public ActionType getActionType(Object suAction) + { + if (suAction == null || dialectMetaModelInfo == null) + return null; + + + for (ActionType at : dialectMetaModelInfo.getActionTypes() ) + { +// logger.info(MultiContextLogger.MODELMAPPER_DETAILLED, "is " +// + suAction + " actionType " + at.getName() + "?"); + + ActionWrapper suActionWrapper = ActionWrapper.createActionWrapper(suAction); + + if(at.getShortName().equals(suActionWrapper.getName())) + { +// logger.info("...yes"); + return at; + } + else + { +// logger.info("...no"); + + } + } + + return null; + } + + public boolean isSecureUmlRole(ModelElement m) + { + try + { + String umlClassName = + SecureUmlConstants.getRoleResourceTypeDummy().getUmlClassName(); + String modelElementStereotype = + SecureUmlConstants.getRoleResourceTypeDummy().getModelElementStereotype(); + +// logger.info( +// "isSecureUmlRole(" +// //+ m.get +// + umlClassName +// + " ?= " +// + m.getClass().getSimpleName() +// + ", " +// + modelElementStereotype +// + " ?= " +// + ((Stereotype) m.getStereotype().iterator().next()).getName()); + + if (hasType(m, umlClassName) + && hasStereotype(m, modelElementStereotype)) + { + return true; + } + } + catch (Exception e) + { + + } + + return false; + } + + public boolean isSecureUmlPermission(ModelElement m) + { +// logger.info( +// "isSecureUmlPermission(umlClassname: " +// + umlClassName +// + ", stereotype: " +// + modelElementStereotype); + + if (hasType(m, SecureUmlConstants.PERMISSION_CLASSNAME) + && hasStereotype(m, SecureUmlConstants.STEREOTYPE_SECUML_PERMISSION)) + { + return true; + } + else + return false; + } + + public boolean isSecureUmlPolicy(ModelElement m) { + try + { +// logger.info( +// "isSecureUmlRole(" +// //+ m.get +// + umlClassName +// + " ?= " +// + m.getClass().getSimpleName() +// + ", " +// + modelElementStereotype +// + " ?= " +// + ((Stereotype) m.getStereotype().iterator().next()).getName()); + + if (hasType(m, SecureUmlConstants.POLICY_CLASSNAME) + && hasStereotype(m, SecureUmlConstants.STEREOTYPE_SECUML_POLICY)) + { + return true; + } + } + catch (Exception e) + { + e.printStackTrace(); + } + return false; + } + + public boolean isSecureUmlExcpLevel(ModelElement m) + { + String umlClassName = ""; + + if (hasType(m, umlClassName) && hasStereotype(m, SecureUmlConstants.STEREOTYPE_SECUML_POLICY)) { + return true; + } else { + return false; + } + + } + + + public Classifier findAnchor(AssociationClass permission) + { + Collection ends = permission.getConnection(); + for (Iterator iter = ends.iterator(); iter.hasNext();) + { + org.omg.uml.foundation.core.AssociationEnd end = + (org.omg.uml.foundation.core.AssociationEnd) iter.next(); + + ResourceType rt = getResourceType(end.getParticipant()); + if(rt != null) + return end.getParticipant(); + } + return null; + } + + public Classifier getPermissionRole(AssociationClass permission) + { + Collection ends = permission.getConnection(); + for (Iterator iter = ends.iterator(); iter.hasNext();) + { + org.omg.uml.foundation.core.AssociationEnd end = + (org.omg.uml.foundation.core.AssociationEnd) iter.next(); + + boolean isRole = isSecureUmlRole(end.getParticipant()); + if(isRole) + return end.getParticipant(); + } + return null; + } + + public UmlClass findAnchor(ModelElement resource) + { + logger.info("find Anchor for resource "+resource.getName()); + ResourceType startPointResourceType = + getResourceType(resource); + + return findAnchor(resource, startPointResourceType); + } + + String resourcePath = null; + + /** finds the Anchor of a Resource and calculates + * the Resource's resourcePath. + * + * @param resource + * @param startPointResourceType + * @return the anchor of the resource + */ + public UmlClass findAnchor(ModelElement resource, + ResourceType startPointResourceType) + { +// org.omg.uml.foundation.core.AssociationEnd end; +// end. + + if (resource == null || startPointResourceType == null) + { + resourcePath = ""; + return null; + } + + resourcePath = resource.getName(); + + ResourceType resourceType = startPointResourceType; + + ModelElement modelElement = resource; + + // TODO: follow startPointResourceType.getAnchorPath() + // from startPoint + + String anchorPath = startPointResourceType.getAnchorPath(); + + ModelElement result = + //evaluateUniquePathExpression( + evaluateUniqueOclExpression( + resource, resourceType, anchorPath); + + if (result instanceof UmlClass) + return (UmlClass) result; + else + return null; + } + + + private ModelElement evaluateUniqueOclExpression( + ModelElement startpoint, + MetaModelClass metaModelClass, + /*ModelElement modelElement,*/ + String oclExpression) + { + //Object startpoint = map.getElement(modelElement); + + logger.info("parsing OCL-Expression: " + + oclExpression); + + OclExpressionsParser parser = + new OclExpressionsParser(); + + OclExpression expression = + parser.parseOclExpression(oclExpression); + +// logger.info("OCL-Expression parsed - starting at " +// + startpoint.getClass().getSimpleName() + " " +// + startpoint.getName() +// + " with evaluation of: " +// + expression); + + OclUmlExpressionEvaluator evaluator = + new OclUmlExpressionEvaluator( + expression, startpoint, startpoint, + dialectMetaModelInfo, metaModelClass); + + try + { + Set result = evaluator.evaluateExpression(); + + this.resourcePath = evaluator.getResourcePath(); + + if(result == null || result.size() == 0) + { + logger.error("result set is empty"); + logger.error("no anchor found for: " + startpoint.getName()); + return null; + } + if(result.size() == 1) + { + Object o = result.iterator().next(); + if (o instanceof ModelElement) + { + ModelElement me = (ModelElement) o; + +// logger.info("anchor of " +// + startpoint.getName() +// + " is: " +// + me.getName()); + + return me; + } + } + else + { + logger.error("more than one Object in result set"); + logger.error("no anchor found for: " + startpoint.getName()); + } + } + catch (Exception e) + { + logger.logException(e); + } + + return null; + } + + public static final char OPENING_BRACKET_CHAR = '['; + public static final char CLOSING_BRACKET_CHAR = ']'; + + /** + * not working correctly, + * and using pathExpressions instead of OCL-Expressions + * + * @param startPoint + * @param metaModelClass + * @param maxdepth + * @param pathExpression + * + */ + private ModelElement evaluateUniquePathExpression(ModelElement startPoint, MetaModelClass metaModelClass, /*ModelElement modelElement,*/ String pathExpression, int maxdepth) + { + if(maxdepth < 0) + { + logger.error("evaluateUniquePathExpression recursion too deep"); + return null; + } + maxdepth--; + + ModelElement modelElement = startPoint; + + String[] pathSteps = null; + if (pathExpression != null) + { + pathSteps = pathExpression.split("\\."); + } + +// logger.info("evaluating path expression: " + pathExpression); + //ModelElement anchor; + + if (pathSteps != null && pathExpression.length() > 0) + { + int startIndex = 0; + if(pathSteps[0].equals(MetaModelConst.SELF_PATH)) + startIndex = 1; + + int bracketsdepth = 0; + + for (int i = startIndex; i < pathSteps.length; i++) + { + String step = pathSteps[i]; + + logger.info("evaluatePathExpression - step: " + step ); + + // boolean stepTaken = false; + + Collection associations = dialectMetaModelInfo + .getInterResourceAssociations(metaModelClass); + + for (Iterator iter = associations.iterator(); iter.hasNext();) + { + InterResourceAssociation association = (InterResourceAssociation) iter + .next(); + + ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel. + AssociationEnd otherEnd = + association.getOtherEnd(metaModelClass); + + //logger.info("evaluatePathExpression - otherEnd: " + otherEnd); + + if(step.charAt(step.length()-1) + == CLOSING_BRACKET_CHAR) + // step is a selection + { + bracketsdepth = 0; + try + { + String condition = + step.substring(0, step.length() + -1); + // remove CLOSING_BRACKET_CHAR + + if(condition.charAt(0)==OPENING_BRACKET_CHAR) + condition = condition.substring(1); + + logger.info( + "evaluatePathExpression: " + + "evaluating selection with condition" + + condition); + + Collection c = null; + c = navigateAssociation(modelElement, otherEnd); + + String leftpart = ""; + String rightpart = ""; + boolean equality = false; + + if(condition.contains("=")) + { + leftpart = condition.split("=")[0]; + rightpart = condition.split("=")[1]; + + equality = true; + } + else if(condition.contains("<>")) + { + leftpart = condition.split("<>")[0]; + rightpart = condition.split("<>")[1]; + + equality = false; + } + else + { + logger.error("evaluatePathExpression: invalid path selection condition"); + return null; + } + + for (Iterator iterator = c.iterator(); iterator.hasNext();) + { + ModelElement me = (ModelElement) iterator.next(); + + ModelElement leftModelElement = null; + + + if(leftpart.startsWith(MetaModelConst.SELF_PATH)) + { +// logger.info( +// "would evaluate left part recursively, here: " +// + rightpart); + evaluateUniquePathExpression( + startPoint, + getResourceType(startPoint), + leftpart, maxdepth); + } + else + { +// logger.info( +// "would evaluate left part recursively, here: " +// + leftpart); + evaluateUniquePathExpression( + me, + getResourceType(me), + leftpart, maxdepth); + } + ModelElement rightModelElement = null; + if(rightpart.startsWith(MetaModelConst.SELF_PATH)) + { +// logger.info( +// "would evaluate right part recursively, here: " +// + rightpart); + evaluateUniquePathExpression( + startPoint, + getResourceType(startPoint), + rightpart, maxdepth); + } + else + { +// logger.info( +// "would evaluate right part recursively, here: " +// + rightpart); + evaluateUniquePathExpression( + me, + getResourceType(me), + rightpart, maxdepth); + } + + logger.info("Condition compares " + + leftModelElement + + " and " + + rightModelElement); + + boolean equals = + leftModelElement.equals(rightModelElement); + + if(equals == equality) + { + modelElement = me; + // continue + } + //return me; + } + if(modelElement == null) + { + logger.error("there is no ModelElement " + + "satisfying the selection condition"); + return null; + } + } + catch (Exception e) + { + logger.logException(e); + } + } + else if(step.indexOf(OPENING_BRACKET_CHAR) != -1 + || bracketsdepth > 0) + // step is first part of a selection + { + bracketsdepth = 1; + pathSteps[i+1] = step + pathSteps[i+1]; + break; + } + else if (step.endsWith("*")) + // step is a repetition + { + step = step.substring(0, step.length() - 1); + + if(otherEnd != null + && otherEnd.getName().equals( + step.substring(0, step.length() - 1))) + { + //Collection c = navigateAssociation(modelElement, otherEnd); + + ModelElement temp = null; + + do // take this step 0-n times, as long as it leads somewhere else + { + temp = + takeAnchorPathStep(modelElement, step, otherEnd); + + if(temp != null && temp != modelElement) + modelElement = temp; + else + temp = null; + + } while (temp != null); + + } + } + else if (otherEnd != null + && otherEnd.getName().equals(step)) + { + // take the step via + try + { + //String startPointName = startPoint.getName(); + + modelElement = takeAnchorPathStep(modelElement, step, otherEnd); + + metaModelClass = /*(ResourceType)*/ otherEnd.getType(); + metaModelClass.toString(); + // stepTaken = true; + } + catch (Exception e) + { + logger.logException(e); + // do nothing - assumption was wrong & try next + } + // here was a problem because + // 'stepTaken = true' was here, before + } + else + { + // do nothing + } + } + // if (!stepTaken) + // return null; + } + /* until now, all steps have been taken + * but the first one in the array + * which is == 'self' (has been verified above) + * + * --> this is the anchor + */ + + if (modelElement instanceof UmlClass) + { + logger.info("anchor of " + + startPoint.getName() + + " is: " + + modelElement.getName()); + + return (UmlClass) modelElement; + } + else + { + logger.error("no anchor found for: " + startPoint.getName()); + return null; + } + } + else + { + logger.error(MultiContextLogger.MODELMAPPER, "Invalid anchorPath: " + + pathExpression); + } + + return null; + + } + + /** finds the Anchor of a Resource and calculates + * the Resource's resourcePath + * + * @param resource + * @param startPointResourceType + * @return the anchor of the resource + */ + public UmlClass findAnchorOld(ModelElement resource, + ResourceType startPointResourceType) + { + if (resource == null || startPointResourceType == null) + { + resourcePath = ""; + return null; + } + + resourcePath = resource.getName(); + + ResourceType resourceType = startPointResourceType; + + ModelElement modelElement = resource; + + // TODO: follow startPointResourceType.getAnchorPath() + // from startPoint + + String anchorPath = startPointResourceType.getAnchorPath(); + String[] anchorPathSteps = null; + if (anchorPath != null) + { + anchorPathSteps = anchorPath.split("\\."); + } + //ModelElement anchor; + + if (anchorPathSteps != null && anchorPath.length() > 0 + && anchorPathSteps[0].equals(MetaModelConst.SELF_PATH)) + { + + for (int i = 1; i < anchorPathSteps.length; i++) + { + String step = anchorPathSteps[i]; + + // boolean stepTaken = false; + + Collection associations = dialectMetaModelInfo + .getInterResourceAssociations(resourceType); + + for (Iterator iter = associations.iterator(); iter.hasNext();) + { + InterResourceAssociation association = (InterResourceAssociation) iter + .next(); + + ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.AssociationEnd otherEnd = + association.getOtherEnd(resourceType); + + if (step.endsWith("*")) + { + step = step.substring(0, step.length() - 1); + + //Collection c = navigateAssociation(modelElement, otherEnd); + + ModelElement temp = null; + + do // take this step 0-n times, as long as it leads somewhere else + { + temp = + takeAnchorPathStep(modelElement, step, otherEnd); + + if(temp != null && temp != modelElement) + modelElement = temp; + else + temp = null; + + } while (temp != null); + + } + else if (otherEnd.getName().equals(step)) + { + // take the step via + try + { + String startPointName = resource.getName(); + + modelElement = takeAnchorPathStep(modelElement, step, otherEnd); + + resourceType = (ResourceType) otherEnd.getType(); + resourceType.toString(); + // stepTaken = true; + } + catch (Exception e) + { + logger.logException(e); + // do nothing - assumption was wrong & try next + } + // here was a problem because + // 'stepTaken = true' was here, before + } + else + { + // do nothing + } + } + // if (!stepTaken) + // return null; + } + /* until now, all steps have been taken + * but the first one in the array + * which is == 'self' (has been verified above) + * + * --> this is the anchor + */ + + if (modelElement instanceof UmlClass) + return (UmlClass) modelElement; + else + return null; + } + else + { + logger.error(MultiContextLogger.MODELMAPPER, "Invalid anchorPath: " + + anchorPath); + } + + return null; + } + + /** + * @param modelElement + * @param step + * @param otherEnd + * @return ModelElement which is reached by taking the step + */ + private ModelElement takeAnchorPathStep( + ModelElement modelElement, + String step, + ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.AssociationEnd otherEnd) + { + Collection c = null; + c = navigateAssociation(modelElement, otherEnd); + + if (c == null) + return null; + else + // if (c instanceof Collection) + { + /* + * consider only the first element - anchor path must be unique + */ + Collection collection = (Collection) c; + + if (collection.size() > 1) + { + logger.error(MultiContextLogger.MODELMAPPER, + "Anchor Path Step: " + step + " not unique."); + //return null; + } + else if (collection.size() == 0) + { + logger.error(MultiContextLogger.MODELMAPPER, + "Anchor Path Step: " + step + "could not be followed."); + //return null; + } + else + // collection.size == 1 + { + Object o = collection.iterator().next(); + if (o instanceof ModelElement) + { + modelElement = (ModelElement) o; + + if (resourcePath == null || resourcePath.length() == 0) + { + resourcePath = modelElement.getName(); + } + else + { + resourcePath = modelElement.getName() + "." + + resourcePath; + } + +// logger.info("step taken: " + step +// + ", resourcePath so far: " + resourcePath); + //break; + } + } + } + return modelElement; + } + +// public String getResourcePath(ModelElement resourceUml) +// { +// +// UmlClass anchor = findAnchor(resourceUml); +// +// return resourcePath; +// } + +// public UmlClass findClass(RefPackage umlPackage, String name) +// { +// if (umlPackage == null || umlPackage.getOwnedElement() == null) +// return null; +// +// //tudresden.ocl20.core.jmi.uml15.core.Namespace n; +// for (Iterator iter = umlPackage.getOwnedElement().iterator(); iter +// .hasNext();) +// { +// Object item = iter.next(); +// +// if (item instanceof UmlClass) +// { +// UmlClass umlClass = (UmlClass) item; +// +// if (umlClass.getName().equals(name)) +// return (UmlClass) umlClass; +// +// logger.info(" ! " + umlClass.getName()); +// } +// else if (item instanceof RefPackage) +// { +// UmlClass result = findClass((RefPackage) item, name); +// +// if (result != null) +// return result; +// } +// +// // else +// // { +// // try +// // { +// // Class[] argTypes = new Class[0]; +// // Object[] args = new Object[0]; +// // +// // Method m = item.getClass().getMethod("getName", argTypes); +// // logger.info(" ! " + m.invoke(item, args) + " : " + item.getClass()); +// // } +// // catch (Exception e) +// // { +// // //logger.logException(e); +// // //logger.info(" ! " + item.getClass()); +// // } +// } +// +// // for (Iterator iterator = umlNamespace.getOwnedElement().iterator(); iter.hasNext();) +// // { +// // RefPackage refPackage = (RefPackage) iterator.next(); +// // +// // UmlClass result = findClass(refPackage, name); +// // if(result != null) +// // return result; +// // +// // } +// +// return null; +// } + +// public RefPackage findPackage(Collection packages, String name) +// { +// for (Iterator iter = packages.iterator(); iter.hasNext();) +// { +// Object item = iter.next(); +// if (item instanceof Package) +// { +// RefPackage p = (RefPackage) item; +// String packagename = p.getName(); +// +// if (packagename.equals(name)) +// return p; +// +// RefPackage result = findPackage(p, name); +// if (result != null) +// return result; +// } +// } +// return null; +// } +// +// public RefPackage findPackage(RefPackage umlPackage, String name) +// { +// if (umlPackage == null || umlPackage.getOwnedElement() == null) +// return null; +// +// for (Iterator iter = umlPackage.getOwnedElement().iterator(); iter +// .hasNext();) +// { +// Object item = iter.next(); +// +// if (item instanceof RefPackage) +// { +// RefPackage p = (RefPackage) item; +// +// String pName = p.getName(); +// if (pName.equals(name)) +// return p; +// else +// { +// logger.info(" ! " + p.getName()); +// RefPackage result = findPackage((RefPackage) item, name); +// } +// } +// } +// return null; +// } + + public String findPackage(ModelElement elem) + { + Namespace result = null; + while (result == null) + { + result = elem.getNamespace(); + elem = (ModelElement) elem.refImmediateComposite(); + } + if (elem instanceof Classifier) + { + result = elem.getNamespace(); + } + return result.getName(); + } + + public Namespace findNamespaceByName(ModelElement startpoint, String name) + { + //Namespace result = null; + try + { + Collection elements = startpoint.getNamespace().getOwnedElement(); + + for (Iterator iter = elements.iterator(); iter.hasNext();) + { + Object item = (Object) iter.next(); + + if (item instanceof Namespace) + { + Namespace ns = (Namespace) item; + + if(ns.getName().equals(name)) + return ns; + } + } + + + } + catch (Exception e) + { + logger.logException(e); + } + + return null; + } + + public Collection navigateAssociation(ModelElement from, + InterResourceAssociation association) + { + MetaModelClass mmc = getMetaModelClass(from); + if (mmc != null) + { + AssociationEnd otherEnd = association.getOtherEnd(mmc); + if (otherEnd != null) + return navigateAssociation(from, otherEnd); + } + + return null; + } + + /** + * @param from + * @param targetAssociationEnd + * @return if the Association could not be navigated, + * 'null' is returned + */ + public Collection navigateAssociation( + ModelElement from, + ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel. + AssociationEnd targetAssociationEnd) + { + if(from == null || targetAssociationEnd == null) + { + logger.error("navigateAssociation: null argument (" + + from + ", " + targetAssociationEnd + ")"); + return null; + } + + String methodName = targetAssociationEnd.getUmlPropertyGetter(); + Object result = null; + + try + { + Method umlPropertyGetter = null; + if(methodName != null && methodName.length() != 0) + { + umlPropertyGetter = + from.getClass().getMethod( + methodName, new Class[0]); + + result = umlPropertyGetter.invoke(from, new Object[0]); + } + // else + if(result == null || + (result instanceof Collection + && ((Collection)result).size() == 0)) + // try to navigate backwards + { + // logger.info( + // "navigateAssociation - Navigating backwards:" + // + " using Method " + //+ targetAssociationEnd.getOwner()); +// AssociationEnd otherEnd = targetAssociationEnd. +// getOwner().getOtherEnd(targetAssociationEnd.getType()); + + AssociationEnd otherEnd = + targetAssociationEnd.getOwner().getEnd1(); + if(otherEnd == targetAssociationEnd) + otherEnd = + targetAssociationEnd.getOwner().getEnd2(); + + methodName = + otherEnd.getUmlPropertyGetter(); + + if(methodName != null && methodName.length() != 0) + { +// logger.info( +// "navigateAssociation - Navigating backwards:" +// + " using Method " + methodName); + Collection/**/ relatedElements = + new LinkedList/**/(); + result = relatedElements; + + Set allUmlElements = + ModelMap.getDefault().getAllUmlElements(); + + // logger.info("trying to start from " + //+ allUmlElements.size() + " Uml ModelElements " + //+ " via Method " + methodName); + for (Iterator iter = allUmlElements.iterator(); iter.hasNext();) + { + RefObject modelElement = (RefObject) iter.next(); + + //MetaModelClass mmc = getMetaModelClass(modelElement); + + //if(mmc == ) + //result == null; + try + { + umlPropertyGetter = modelElement.getClass(). + getMethod(methodName,new Class[0]); + + Object res = umlPropertyGetter.invoke( + modelElement, new Object[0]); + + if (res instanceof ModelElement) + { + ModelElement resMe = (ModelElement) res; + + logger.info(" ... invoked - method returned: " + + resMe.getName()); + + } + + if (res instanceof Collection) + { + Collection resultCollection = (Collection) result; + if(resultCollection.contains(from)) + { + //result = modelElement; + //break; + relatedElements.add(modelElement); + } + } + else if (res != null) + { + if(res == from) + { +// result = modelElement; +// break; + relatedElements.add(modelElement); + } + } + } + catch (Exception e) + { + //logger.logException(e); + } + //result = null; + } + } + } + + // if (result instanceof Collection) + // { + // // only consider the first element + // result = ((Collection) result).iterator().next(); + // } + + // if (result instanceof ModelElement) + // { + // modelElement = (ModelElement) result; + // + // } + } + catch (Exception e) + { + logger.error("Problem navigating AssociationEnd " + + targetAssociationEnd + + " from " + from.getName()); + logger.logException(e); + } + + if (result instanceof Collection) + return (Collection) result; + else if (result != null) + { + LinkedList l = new LinkedList(); + + l.add(result); + + return l; + } + else + return null; + } + + /* utility methods */ + + public boolean hasType(ModelElement modelElement, String className) + { + className += MetaModelConst.MDR_IMPL_SUFFIX; + +// logger.info("hasType(" +// + modelElement.getClass().getSimpleName() +// + ", " +// + className); + + if (modelElement != null && className != null) + { + boolean result = modelElement.getClass().getSimpleName(). + startsWith(className); +// logger.info("... " + result); + + return result; + } + else + return false; + } + + public boolean hasStereotype(ModelElement element, String stereotype) + { + if (element == null || stereotype == null || stereotype.length() == 0) + return false; + + Collection stereotypes = element.getStereotype(); + int nofStereotypes = stereotypes.size(); + +// logger.info("hasStereotype(sterotype:" + stereotype +// + " - searching among " + nofStereotypes); + + if (stereotypes == null || stereotypes.size() == 0) + return false; + + for (Iterator it = stereotypes.iterator(); it.hasNext();) + { + Stereotype s = (Stereotype) it.next(); + if (s.getName().equals(stereotype)) + { +// logger.info("... found"); + return true; + } + } + return false; + } + + public boolean haveStereotype(Collection elements, + String stereotype) + { + for (ModelElement elem : elements) + { + if (!hasStereotype(elem, stereotype)) + { + return false; + } + } + return true; + } + + /** + * @return the map + */ + public MetaModelMap getMap() + { + return map; + } + + /** + * @param map the map to set + */ + public void setMap(MetaModelMap map) + { + this.map = map; + } + + /** + * @return the dialectMetaModelInfo + */ + public DialectMetaModelInfo getDialectMetaModelInfo() + { + return dialectMetaModelInfo; + } + + /** + * @param dialectMetaModelInfo the dialectMetaModelInfo to set + */ + public void setDialectMetaModelInfo(DialectMetaModelInfo dialectMetaModelInfo) + { + this.dialectMetaModelInfo = dialectMetaModelInfo; + } + + /** + * @return the resourcePath + */ + public String getResourcePath() + { + return resourcePath; + } + + public String getResourcePath(ModelElement resourceUml) + { + UmlClass anchor = findAnchor(resourceUml); + + // generic solution, doesn't work correctly +// MetaModelClass anchorMetaModelClass = getMetaModelClass(anchor); +// +// ResourceType resourceType = getResourceType(resourceUml); +// +// if(resourceType != null && resourceType.getResoucePath() != null) +// { +// OclExpressionsParser parser = new OclExpressionsParser(); +// +// try +// { +// OclExpression resourcePathExpression = +// parser.parseOclExpression(resourceType.getResoucePath()); +// +// OclUmlExpressionEvaluator evaluator = +// new OclUmlExpressionEvaluator( +// resourcePathExpression, anchor, anchor, +// dialectMetaModelInfo, anchorMetaModelClass); +// +// Set reachedObjects = evaluator.evaluateExpression(); +// +// Object resourceUmlObject = findElementByName(reachedObjects, resourceUml.getName()); +// if(evaluator.getResourcePaths().containsKey(resourceUmlObject)) +// { +// resourcePath = evaluator.getResourcePaths().get(resourceUmlObject); +// logger.info("##resourcePath for " +// + resourceUml.getName() +// + " recalucalated: " +// + resourcePath); +// } +// else +// // ugly, non-generic hack +// { +// String[] resourcePathFragments = resourcePath.split("\\."); +// resourcePath = resourcePathFragments[0] +// + "." + resourcePathFragments[1]; +// } +// } +// catch (Exception e) +// { +// e.printStackTrace(); +// } +// } + +// ugly, non-generic hack + String[] resourcePathFragments = resourcePath.split("\\."); + if(resourcePathFragments.length == 1) + return resourcePathFragments[0]; + else + { + resourcePath = resourcePathFragments[0] + + "." + resourcePathFragments[1]; + return resourcePathFragments[0] + + "." + resourcePathFragments[1]; + } + + //return resourcePath; + } + + /** + * Find a resource in a modelelement according to the given pathName. + * + * @param pathName + * @param anchor + * @return the found element + */ + @SuppressWarnings("unchecked") + public ModelElement resolvePath( + String pathName, ModelElement anchor) + { + logger.info("resolving resource Path: '" + pathName + + "' starting at " + anchor.getName()); + + String[] components = pathName.split("\\."); + if (components.length == 0) + { + logger.error("invalid path expression: " + pathName); + return null; + } + int pathOffset = 0; + if (components[pathOffset].equals(anchor.getName())) + { + if (components.length == 1) + { + // path name denotes the anchor, return it + return anchor; + } + else + { + // path name has an anchor prefix, skip it + pathOffset = 1; + } + } + ModelElement result = anchor; + // follow path to find resource + while (pathOffset < components.length) + { + result = findRelatedElement( + result, components[pathOffset]); + pathOffset++; + } + + if (result == null) + { + logger.error("invalid path expression - target not found: " + pathName); + } + return result; + } + + /** + * Finds an element with the given name inside its containing object. + * + * @param startPoint + * @param name + * @return the found element + */ + @SuppressWarnings("unchecked") + private ModelElement findRelatedElement( + ModelElement startPoint, + String name) + { + + if(startPoint == null) + { + logger.error("findRelatedElement - start point null, name = "+name); + return null; + } + + + + logger.info("searching related Element with Name '" + name + + "' starting from "+startPoint.getName() + "'"); + + MetaModelClass metaModelClass = + getMetaModelClass(startPoint); + + + if(metaModelClass == null) + { + + logger.error(startPoint.getName() + + " is not a metaModelClass Instance"); + return null; + } else { + logger.info("startPoint is a '"+metaModelClass.getName()+"' instance"); + } + + for (Iterator iter = + dialectMetaModelInfo.getInterResourceAssociations( + metaModelClass).iterator(); iter.hasNext();) + { + InterResourceAssociation association = + (InterResourceAssociation) iter.next(); + +// logger.info("... along " + association.getName()); + + Collection result = navigateAssociation(startPoint, association); + +// if(result != null) +// logger.info("...among " + result.size() + " elements"); + + ModelElement relatedElement = findElementByName(result, name); + + if(relatedElement != null) + return relatedElement; + else + { + result = new LinkedList(); + + Set allUmlElements = + ModelMap.getDefault().getAllUmlElements(); + + for (Iterator it = allUmlElements.iterator(); it.hasNext();) + { + RefObject item = (RefObject) it.next(); + + if (item instanceof ModelElement) + { + ModelElement modelElement = (ModelElement) item; + + Classifier anchor = findAnchor(modelElement); + + if(anchor == startPoint) + { + result.add(modelElement); + } + } + } + + relatedElement = findElementByName(result, name); + + if(relatedElement != null) + return relatedElement; + } +// else +// { +// AssociationEnd otherEnd = +// association.getOtherEnd(metaModelClass); +// AssociationEnd end = +// association.getOtherEnd(otherEnd.getType()); +// +// Collection relatedElements = +// new LinkedList(); +//// tryNavigateBackwards(otherEnd, end, +//// Model.getCoreHelper(). +//// getAllClassifiers(startPoint.getNamespace()) +//// , startPoint); +// Set allUmlElements = +// ModelMap.getDefault().getAllUmlElements(); +// +// +// return findElementByName(relatedElements, name); +// +// //return relatedElement; +// } + } +// org.omg.uml.foundation.core.AssociationEnd a; +// a.getParticipant(); + + return null; + } + + private ModelElement findElementByName(Collection elems, String name) { + if(elems == null) + return null; + + for (ModelElement elem : elems) + { + if (elem == null) + { + logger.info("elem==null in findElementByName"); + } + if(elem.getName()==null) { + logger.error("elem.getName() == null in findElementByName"); + if ("".equals(name)) + return elem; + } else if (elem.getName().equals(name)) + { + return elem; + } + else + { + // logger.info("... is not: " + elem.getName()); + } + } + return null; + } + + private Collection tryNavigateBackwards( + AssociationEnd otherEnd, + AssociationEnd end, + Collection modelElements, + ModelElement target)//,int maxDepth) + { + Set visitedElements = new LinkedHashSet(); + return tryNavigateBackwards( + otherEnd, end, modelElements, + visitedElements, target); + } + + /** + * @param otherEnd + * @param end + * @param modelElements + */ + private Collection tryNavigateBackwards( + AssociationEnd otherEnd, AssociationEnd end, + Collection modelElements, Set visitedElements, + ModelElement target) + { + Collection res = new LinkedList(); +// if(maxDepth <= 0) +// return; + + if(modelElements == null || modelElements.size() == 0) + return null; + +// logger.info(logger.MODELMAPPER_DETAILLED, +// "Try to navigate Association the other way round - " +// + "iterating over all ModelElements in the Namespace - n = " +// + modelElements.size()); + + + for (Iterator iterator = modelElements.iterator(); iterator + .hasNext();) + { + Object object = iterator.next(); + +// if (object instanceof Namespace) +// { +// Namespace ns = (Namespace) object; +// tryNavigateBackwards(otherEnd, end, ns.getOwnedElement()); +//// +//// Util.addAllSave(allElementsInNamespace, ns.getOwnedElement()); +// } + // TODO: replace this hardcoded hack by a generic solution + + if (object instanceof ModelElement) + { + + ModelElement m = (ModelElement) object; + + if(visitedElements.contains(m)) + return null; + else + visitedElements.add(m); + + + if (hasType(m, otherEnd.getType().getName())) + { + logger + .info("try to navigate Association in reverse Direction " + + "from end: " + + otherEnd.getName()); + + Collection coll = navigateAssociation(m, end); + String s = "... leads to: "; + if(coll.size()>1) + s = s + " Collection containing: "; + + if(coll.size() > 0) + s = s + Util.getProperty(coll.iterator().next(), "name");//+ coll); + + logger.info(s); +// if (coll instanceof Collection) +// { + if(coll != null) + { + //Collection c1 = (Collection) coll; + + //addModelElementsToScope(otherEnd, coll); + + if(coll.contains(target)) + { + res.add(m); + } + // TODO: do something here + //addModelElementToScope(otherEnd, m); + } +// else if (c1 instanceof ModelElement) +// { +// try +// { +// addModelElementToScope(otherEnd, m); +// } +// catch (Exception e) +// { +// ; +// } +// +// } + + } + else + { + + // +// if(m instanceof Association) +// { +// Association a = (Association) m; +// +// tryNavigateBackwards(otherEnd, end, a.getConnection(), maxDepth/1); +// +//// +//// Util.addAllSave(allElementsInNamespace, a.getConnection()); +// } + + +// logger.info("wrong type: " +// + m.getClass().getSimpleName() +// + " : " + m.getName()); + +// logger.info( +// "can't reach the ModelElement directly, " + +// "try to reach it in several hops..."); + + // but can try to reach the source ModelElement via + // more than one step + + MetaModelClass mmClass = getMetaModelClass(m); + + if(mmClass != null && mmClass.getUmlClassName() != null) + { +// logger.info("...from: " +// + m.getClass().getSimpleName() +// + " : " +// + m.getNameA()); + + Collection associations = dialectMetaModelInfo.getInterResourceAssociations(mmClass); + + if(associations != null) + { + for (Iterator iter = associations.iterator(); iter.hasNext();) + { + InterResourceAssociation association = (InterResourceAssociation) iter.next(); + + + Collection result = + navigateAssociation( + m, association.getOtherEnd(mmClass)); +// Collection coll; +// if (result instanceof Collection) +// { +// coll = (Collection) result; +// +// } +// else +// { +// coll = new LinkedList(); coll.add(result); +// } + + //tryNavigateBackwards(otherEnd, end, coll, maxDepth-1); + return tryNavigateBackwards(otherEnd, end, result, visitedElements, target); + } + } + + + } + + + } + } + } + return res; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/GenericDialectModelMapper.java b/src/ch/ethz/infsec/secureumlgui/modelmapping/GenericDialectModelMapper.java new file mode 100644 index 0000000..8188046 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/GenericDialectModelMapper.java @@ -0,0 +1,1398 @@ +package ch.ethz.infsec.secureumlgui.modelmapping; + +import java.beans.PropertyVetoException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.jmi.model.MofPackage; +import javax.jmi.reflect.RefObject; +import javax.jmi.reflect.RefPackage; + +import org.apache.log4j.Logger; +import org.argouml.model.ClassDiagram; +import org.argouml.model.CoreHelper; +import org.argouml.model.DiDiagram; +import org.argouml.model.DiagramInterchangeModel; +import org.argouml.model.Facade; +import org.argouml.model.Model; +import org.argouml.uml.diagram.ArgoDiagram; +import org.argouml.uml.diagram.static_structure.ClassDiagramGraphModel; +import org.argouml.uml.diagram.static_structure.ui.ClassDiagramRenderer; +import org.argouml.uml.diagram.static_structure.ui.FigClass; +import org.argouml.uml.diagram.static_structure.ui.UMLClassDiagram; +import org.argouml.uml.ui.ActionClassDiagram; +import org.netbeans.api.mdr.MDRManager; + +import org.omg.uml.foundation.core.AssociationEnd; +import org.omg.uml.foundation.core.Classifier; +import org.omg.uml.foundation.core.Generalization; +import org.omg.uml.foundation.core.ModelElement; +import org.omg.uml.foundation.core.Namespace; +import org.omg.uml.foundation.core.Stereotype; +import org.omg.uml.foundation.core.AssociationClass; +import org.omg.uml.foundation.core.UmlAssociation; +import org.omg.uml.foundation.core.UmlClass; +import org.omg.uml.modelmanagement.UmlPackage; +import org.tigris.gef.base.Layer; +import org.tigris.gef.base.LayerDiagram; +import org.tigris.gef.presentation.FigNode; + +import ch.ethz.infsec.secureumlgui.Util; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ActionType; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.CompositeActionType; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.DialectMetaModelInfo; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.InterResourceAssociation; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.MetaModelClass; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.MetaModelClassAttribute; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ResourceType; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions.OclExpression; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions.OclExpressionEvaluator; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions.OclExpressionsParser; +import ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PolicyWrapper; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.main.SecureUmlConstants; +import ch.ethz.infsec.secureumlgui.main.SecureUmlConstants.SECUML_STEREOTYPES; +import ch.ethz.infsec.secureumlgui.main.SecureUmlConstants.UML_OCL; +import ch.ethz.infsec.secureumlgui.modelmanagement.ModelConst; +//FIXME: is this missing intentionally? ask Marcel... +//import ch.ethz.infsec.secureumlgui.modelmapping.strategies.MapAll; +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.HierarchicalPolicyExplorer; +import ch.ethz.infsec.secureumlgui.modelmapping.strategies.MapSelfAndAssociatedResources; +import ch.ethz.infsec.secureumlgui.modelmapping.strategies.MappingScopeStrategy; + +import ch.ethz.infsec.secureumlgui.securemodelimpl.SecureModelFactory; + +/** + * A generic dialect mapper that maps dialect specific elements in the UML model + * to dialect metamodel instances, according to the annotations in the dialect + * metamodel. + * + * + */ +public class GenericDialectModelMapper extends SecureUmlModelMapper { + + private static GenericDialectModelMapper instance; + + private ModelWriter modelWriter; + + MappingScopeStrategy mappingScopeStrategy = null; + + /** all uml classes representing roles */ + Set roleClasses = new LinkedHashSet(); + + /** all actions for resources in the model */ + Set actions = new LinkedHashSet(); + + /** all uml classes representing polices */ + Set policyClasses = new LinkedHashSet(); + + /** all association classes representing permissions */ + Set permissionsAssociations = new LinkedHashSet(); + + /** all inheritance relations between roles */ + Set roleHierarchyGeneralizations = new LinkedHashSet(); + + /** all inheritance relations between policies */ + Set policyHierarchyGeneralizations = new LinkedHashSet(); + + // Set resources = new LinkedHashSet(); + + /** all policy assignments: the key are permissions (Association Class), values are policies **/ + //Map policyAssignments = new HashMap(); + Map policyAssignments = new HashMap(); + + + + Map permissionsPerPolicy = new HashMap(); + + + Map oclMappings = new HashMap(); + + private static Logger aLog = Logger.getLogger(GenericDialectModelMapper.class); + + private Namespace root_namespace = null; + + private UmlPackage secUMLPackage = null; + private UmlPackage permissionPackage = null; + private UmlPackage oclPackage = null; + + /** + * + */ + public GenericDialectModelMapper(DialectMetaModelInfo dialectMetaModelInfo) { + mappingScopeStrategy = new + // MapAll( + MapSelfAndAssociatedResources(dialectMetaModelInfo); + + this.dialectMetaModelInfo = dialectMetaModelInfo; + + if (instance != null) + logger.error("GenericDialectModelMapper instantiated twice!"); + instance = this; + + logger.disableLoggerContext(logger.MODELMAPPER_DETAILLED); + } + + + /** + * initialize ModelMapper: clear all cached mapped elements. + * + * Also deletes and recreated the dialect model extent, so that we don't + * accumulate duplicate elements in the repository. + */ + public void init() { + super.init(); + + roleClasses.clear(); + policyClasses.clear(); + permissionsAssociations.clear(); + roleHierarchyGeneralizations.clear(); + policyHierarchyGeneralizations.clear(); + policyAssignments.clear(); + + actions.clear(); + + permissionsPerPolicy.clear(); + + // equivalent: dialectMetaModelInfo.getDialectExtent().refDelete(); + MDRManager.getDefault().getDefaultRepository().getExtent( + "mySecureModel").refDelete(); + + RefPackage model = null; + try { + model = MDRManager.getDefault().getDefaultRepository() + .createExtent("mySecureModel", + dialectMetaModelInfo.getDialectMetaExtent()); + } catch (Exception e) { + logger.logException(e); + } + + dialectMetaModelInfo.setDialectExtent(model); + + aLog.debug("GenericDialectModelMapper cleared"); + // logger.info("GenericDialectModelMapper cleared"); + + //ensureNeededElementsExist(null); + } + + public static GenericDialectModelMapper getInstance() { + if (instance == null) + logger.info("GenericDialectModelMapper not yet instantiated!"); + return instance; + } + + public ModelWriter getModelWriter() { + if (modelWriter == null && map != null) + modelWriter = new ModelWriter(map); + return modelWriter; + } + + public void setModelWriter(ModelWriter modelWriter) { + this.modelWriter = modelWriter; + } + + // = new MapNamespaceContents(); + /** + * @return the mappingScopeStrategy + */ + public MappingScopeStrategy getMappingScopeStrategy() { + return mappingScopeStrategy; + } + + /** + * @param mappingScopeStrategy + * the mappingScopeStrategy to set + */ + public void setMappingScopeStrategy( + MappingScopeStrategy mappingScopeStrategy) { + this.mappingScopeStrategy = mappingScopeStrategy; + } + + /** + * If modelElement represents a resource, map it, and create + * all actions for this resource. + * + * Does nothing otherwise. + */ + public void examineModelElement(ModelElement modelElement) { + if ( modelElement == null ) { + aLog.error("#######################################"); + aLog.error("modelElement == null!!!!"); + aLog.error("#######################################"); + System.out.println("#######################################"); + System.out.println("modelElement == null!!!!"); + System.out.println("#######################################"); +// try { +// throw new Exception(); +// } catch(Exception e) { +// e.printStackTrace(); +// } + return; + } + else { + aLog.debug("examineModelElement: " + modelElement.getName()); + //ensureNeededElementsExist(modelElement); + } + ResourceType resourceType = helper.getResourceType(modelElement); + MetaModelClass metaModelClass = resourceType; + + if (metaModelClass == null) { + metaModelClass = helper.getMetaModelClass(modelElement); + logger.info("MetaModelClass for " + + modelElement.getName() + + ": " + + (metaModelClass == null ? "null" : metaModelClass + .getName())); + + if ( modelElement instanceof Stereotype ) { + map.putStereotype((Stereotype)modelElement); + } + +// aLog.debug("MetaModelClass for " +// + modelElement.getName() +// + ": " +// + (metaModelClass == null ? "null" : metaModelClass +// .getName()) + " ::: "+ modelElement.getClass() + " (" + (modelElement instanceof Stereotype) + "), "); +// //aLog.debug("Modelmap.put(" + src.getClass() + " (" + (src instanceof Stereotype) + "), " + target.getClass() +" (" + (target instanceof Stereotype) + ")"); + } + + RefObject metaModelObject = null; + if (metaModelClass != null) { + aLog.info("mapping model element " + modelElement.getName() + " metaModelClass: " + metaModelClass.getName()); + logger.info("mapping model element " + modelElement.getName()); + metaModelObject = createMetaModelClass(metaModelClass, modelElement); + setProperties(metaModelClass, metaModelObject, modelElement); + instantiateAllActions(resourceType, metaModelObject); + map.put(modelElement, metaModelObject); + // resources.add(metaModelObject); + } + } + + /** + * create a resource as an instance of metaModelClass, + * corresponding to the UML element modelElement. + */ + public RefObject createMetaModelClass(MetaModelClass metaModelClass, + ModelElement modelElement) { + RefObject newMetaModelClassObject = null; + Object metaModelClassObject = null; + try { + RefPackage dialectPackage = getDialectPackage(); + metaModelClassObject = Util.invokeParameterlessMethod( + getDialectPackage(), "get" + metaModelClass.getName()); + + newMetaModelClassObject = (RefObject) Util + .invokeParameterlessMethod(metaModelClassObject, "create" + + metaModelClass.getName()); + + } catch (Exception e) { + logger.logException(e); + Util.printInterfaces(metaModelClassObject.getClass()); + } + return newMetaModelClassObject; + } + + /** + * returns the action specified by reference from the given resource. If the + * Action has been created yet (i.e. corresponding Property of the Resource + * is set), the Action is just returned. + * + * Otherwise (if not there), the Action is created (lazy), the corresponding + * Property of the Resource is set and then the Action is returned. + * + * @param resource + * the resource for which the action is to be created. + * @param shortActionName + * the name by which the action is referenced from the resource + * @return the action + */ + @Override + public RefObject getOrCreateAction(RefObject resource, + String shortActionName) { + RefObject newActionObject = null; + if (resource == null) { + logger.error("resource = null in getOrCreateAction"); + } + ResourceType resourceType = dialectMetaModelInfo + .getResourceType(resource); + + if (resourceType == null) { + logger.error("could not get resourceType for resource " + resource); + return null; + } + ActionType actionType = dialectMetaModelInfo.getActionType( + resourceType, shortActionName); + + if (actionType != null) { + if (!actionType.getShortName().equals(shortActionName)) + logger.error("actionType.getShortName() = " + + actionType.getShortName() + ", shortActionName = " + + shortActionName + "."); + + newActionObject = (RefObject) Util.getProperty(resource, actionType + .getShortName()); + + if (newActionObject == null) { + newActionObject = SecureModelFactory.getInstance() + .createAction(actionType); + if (newActionObject == null) + logger.error("createAction failed"); + Util.setProperty(resource, actionType.getShortName(), + newActionObject); + + Collection resourceActions = (Collection) Util.getProperty( + resource, "action"); + if (newActionObject != null + && !resourceActions.contains(newActionObject)) { + resourceActions.add(newActionObject); + actions.add(newActionObject); + } + } + } else { + logger.error("did not get actiontype for " + shortActionName + + " on " + resourceType.getName()); + } + return newActionObject; + } + + /** + * Only String Properties are supported + * + * @param metaModelClass + * @param resourceObject + * @param modelElement + */ + public void setProperties(MetaModelClass metaModelClass, + RefObject resourceObject, ModelElement modelElement) { + for (Iterator iter = metaModelClass.getAttributes().iterator(); iter + .hasNext();) { + try { + MetaModelClassAttribute rta = (MetaModelClassAttribute) iter + .next(); + + // get + // Class[] argTypes = new Class[0]; + + // String getter = rta.getUmlGetterName(); + + String propertyName = rta.getUmlName(); + + if (propertyName == null || propertyName.length() == 0) + // if no UMLPropertyName specified, + // use the attribute name as default + propertyName = rta.getName(); + + // logger.info("setting property '" + // + metaModelClass.getName() + "." + propertyName + // + " of " + // + resourceObject.getClass().getSimpleName()); + + if (propertyName != null) { + Object attributeValue = Util.tryGetProperty(modelElement, + propertyName); + + // logger.info("... to Value " + attributeValue); + + // Method m = modelElement.getClass().getMethod(getter, + // argTypes); + + // Object attributeValue = m.invoke(modelElement, new + // Object[0]); + + // String name = modelElement.getName(); + + // set + + /* + * this way it doesn't work for value-type Properties like + * 'bool', 'int', ... because the call below results in a + * java.lang.NoSuchMethodException, because e.g. for int, + * argTypes = {Integer.class} instead of {int.class} + */ + + // argTypes = new Class[] {attributeValue.getClass()}; + // //String.class + // String setterName = //rta.getSetterName(); + // m = Util.findMethodByName(resourceObject.getClass(), + // setterName); + // m = + // resourceObject.getClass().getMethod(rta.getSetterName(), + // argTypes); + if (attributeValue != null)// && m != null) + { + // argTypes = m.getParameterTypes(); + + // Object[] args = new Object[] + // {attributeValue};//.toString() + + Util.setProperty(resourceObject, propertyName, + attributeValue); + + // logger.info(//logger.MODELMAPPER_DETAILLED, + // logger.MODELMAPPER, + // "set ResourceObject Property " + // + propertyName + // + " with Value: " + // + attributeValue); + // + // try + // { + // + // //m.invoke(resourceObject, args); + // } + // catch (Exception e) + // { + // logger.error( + // "failed to set Property '" + // + setterName + // + " with Value " + // + attributeValue.getClass().getSimpleName() + // + attributeValue.toString()); + // logger.logException(e); + // } + + } + + } + + } catch (Exception e) { + logger.logException(e); + } + + // UmlClass c; + // c. + + // AssociationEnd a; + // a.getTypeA() + + } + + } + + + + public void ensureNeededElementsExist(ModelElement startPoint) { + //get namespace of current element + Namespace ns = startPoint.getNamespace(); + + //search for root namespace (do not jet save it to class variable, as we need to check if root namespace changed + Namespace rootns = ns; + while ( rootns.getNamespace() != null ) { + aLog.debug("step back from " + rootns.getName() + " to " + rootns.getNamespace().getName()); + rootns = rootns.getNamespace(); + } + + + if ( root_namespace == null || ! root_namespace.getName().equals(ns.getName()) ) { + + CoreHelper cHelper = Model.getCoreHelper(); + + //did we already find our packages directly under root namespace? + if ( secUMLPackage == null || oclPackage == null ) { + + Collection root_packages = Model.getModelManagementHelper().getAllModelElementsOfKind(rootns, UmlPackage.class.getCanonicalName()); + + Collection root_packageNames = new HashSet(); + aLog.debug("existing packages: " + root_packages.size()); + for ( UmlPackage package_ : root_packages ) { + aLog.debug(package_.getName()); + root_packageNames.add(package_.getName()); + } + + /** get or create secUMLPackage **/ + if ( ! root_packageNames.contains(SecureUmlConstants.PACKAGE_SECUML)) { + aLog.debug(SecureUmlConstants.PACKAGE_SECUML + " does not exists... create it"); + + secUMLPackage = (UmlPackage) Model.getModelManagementFactory().createPackage(); + cHelper.setName(secUMLPackage, SecureUmlConstants.PACKAGE_SECUML); + cHelper.setNamespace(secUMLPackage, rootns); + } else { + for ( UmlPackage package_ : root_packages ) { + if ( SecureUmlConstants.PACKAGE_SECUML.equals(package_.getName())) { + secUMLPackage = package_; + aLog.debug("found existing " + SecureUmlConstants.PACKAGE_SECUML + " package"); + break; + } + } + } + + + /** get or create OCL_UML **/ + if ( ! root_packageNames.contains(SecureUmlConstants.PACKAGE_OCL)) { + aLog.debug(SecureUmlConstants.PACKAGE_OCL + " does not exists... create it"); + + oclPackage = (UmlPackage) Model.getModelManagementFactory().createPackage(); + + cHelper.setName(oclPackage, SecureUmlConstants.PACKAGE_OCL); + cHelper.setNamespace(oclPackage, rootns); + } else { + for ( UmlPackage package_ : root_packages ) { + if ( SecureUmlConstants.PACKAGE_OCL.equals(package_.getName())) { + oclPackage = package_; + aLog.debug("found existing " + SecureUmlConstants.PACKAGE_OCL + " package"); + break; + } + } + } + + + //oclMappings + + + Collection oclTypes = Model.getModelManagementHelper().getAllModelElementsOfKind(oclPackage, UmlClass.class.getCanonicalName()); + UmlClass oclTypesA[] = new UmlClass[oclTypes.size()]; + oclTypes.toArray(oclTypesA); + + ArrayList oclTypeNames = new ArrayList(); + + for ( UmlClass umlClass : oclTypesA ) { + oclTypeNames.add(umlClass.getName()); + } + + //create OCL types + if ( modelWriter == null ) { + getModelWriter(); + } + + for ( UML_OCL ocl : UML_OCL.values() ) { + aLog.debug("OCL Type: " + ocl.toString()); + if ( oclTypeNames.contains(ocl.toString()) ) { //at least, the type already exists.. we do not need to create it + if ( ! oclMappings.containsKey(ocl) ) { + oclMappings.put(ocl, oclTypesA[oclTypeNames.indexOf(ocl.toString())]); + aLog.debug("added existing UMLClass to mapper"); + } + } else { // create uml class for ocl type + //createOclType + aLog.debug("craete OCL Type with " + ocl.getSuperTypes().length + " super Types"); + Set superTypes = new HashSet(); + for ( UML_OCL superType : ocl.getSuperTypes() ) { + superTypes.add(oclMappings.get(superType)); + aLog.debug("class: " + oclMappings.get(superType).getName()); + } + oclMappings.put(ocl, modelWriter.createOclType(ocl.toString(), superTypes)); + } + } + } + + //check for permission package under secuml packages + if ( permissionPackage == null ) { + + if ( secUMLPackage == null) { + throw new RuntimeException("could not find secUML Package"); + } + + Collection secuml_packages = Model.getModelManagementHelper().getAllModelElementsOfKind(secUMLPackage, UmlPackage.class.getCanonicalName()); + + for ( UmlPackage package_ : secuml_packages) { + if ( SecureUmlConstants.PACKAGE_PERMISSIONS.equals(package_.getName())) { + permissionPackage = package_; + break; + } + } + + if ( permissionPackage == null ) { + permissionPackage = (UmlPackage) Model.getModelManagementFactory().createPackage(); + + cHelper.setName(permissionPackage, SecureUmlConstants.PACKAGE_PERMISSIONS); + cHelper.setNamespace(permissionPackage, secUMLPackage); + } + } + + + + + + + + + + + + + if ( modelWriter == null ) { + getModelWriter(); + } + /** create stereotypes **/ + try { + for ( SECUML_STEREOTYPES stereotype : SecureUmlConstants.SECUML_STEREOTYPES.values() ) { + modelWriter.getOrCreateStereotype(stereotype.toString(), secUMLPackage, stereotype.getBase() ); + } + //aLog.debug("Successfully created " + SecureUmlConstants.SECUML_STEREOTYPES.values().length + " stereotypes"); + modelWriter.getOrCreateStereotype("compuml.entity", secUMLPackage, SecureUmlConstants.BASE_CLASS); + //modelWriter.getOrCreateStereotype(SecureUmlConstants.STEREOTYPE_OCL_TYPE, oclPackage, SecureUmlConstants.BASE_CLASS); + + aLog.debug("checked or created stereotypes"); + } catch (Exception e) { + aLog.error("Could not create stereotype: " + e.getMessage(), e); + } + + + ActionClassDiagram actionClassDiagram = new ActionClassDiagram(); + + + + UMLClassDiagram policyClassDiag = (UMLClassDiagram) actionClassDiagram.createDiagram(secUMLPackage); + try { + policyClassDiag.setName("PolicyHierarchy"); + } catch (PropertyVetoException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + +// //DiagramInterchangeModel diagFact = Model.getDiagramInterchangeModel(); +// //ClassDiagram policyClassDiag = (ClassDiagram) diagFact.createDiagram(ClassDiagram.class, ns); +// //policyClassDiag. +// +// +//// Create new Fig classes to represent the element on the diagram and add them to the graph model +//// (org.argouml.uml.diagram.xxxx.XxxxDiagramGraphModel.java) and renderer +//// (org.argouml.uml.diagram.xxxx.ui.XxxxDiagramRenderer.java). +// +// //get default Policy (model element) +// UmlClass defaultPolicy = HierarchicalPolicyExplorer.getInstance().getDefaultPolicy(); +// //create Fig class of model element +// FigClass defaultPolicyFig = new FigClass(defaultPolicy, 40, 40, 40, 40); +// +// +// ClassDiagramGraphModel classDiagGModel = new ClassDiagramGraphModel(); +// +// classDiagGModel.addNode(defaultPolicyFig); +// +// //ClassDiagramRenderer classDiagRenderer = new ClassDiagramRenderer(); +// +// //FigNode figNode = classDiagRenderer.getFigNodeFor(classDiagGModel, new LayerDiagram(), defaultPolicy, new HashMap()); +// +// +// //classDiagGModel.addNode(figNode); +// +// +// +// +// +// ActionClassDiagram actionClassDiagram = new ActionClassDiagram(); +// +// aLog.debug("create class diagram for namespace " + ns.getName()); +// +// UMLClassDiagram policyClassDiag = (UMLClassDiagram) actionClassDiagram.createDiagram(ns); +// +// policyClassDiag.add(defaultPolicyFig); +// +// try { +// policyClassDiag.setName("PolicyHierarchy"); +// +// //policyClassDiag. +// +// aLog.debug("set name to class diagram"); +// +// +// +// aLog.debug("got defaultPolicy"); +// +// policyClassDiag.setModelElementNamespace(defaultPolicy, ns); +// +// aLog.debug("added defaultPolicy"); +// +// //policyClassDiag. +// +// } catch (PropertyVetoException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } +// +// + } + root_namespace = rootns; + } + + public Namespace getInitNamespace() { + return root_namespace; + } + + public UmlPackage getSecUMLPackage() { + return secUMLPackage; + } + + public UmlPackage getPermissionPackage() { + return permissionPackage; + } + + public UmlPackage getOclPackage() { + return this.oclPackage; + } + + + /** + * Maps UML model elements to the dialect model, starting from + * startPoint. + * + * @param startPoint + * @return the transformed object + */ + public Object transform(ModelElement startPoint) // , Package + // sourcePackage) + { + // logger.info("transform started at "+startPoint.getName()); + + + if (startPoint != null) { + // (JD) this is a hack. apparently, the navigationDepth in the + // mappingScopeStrategy gets messed up sometimes. So we just create + // a new one + // each time... + mappingScopeStrategy = new MapSelfAndAssociatedResources( + dialectMetaModelInfo); + Collection mappingScope = mappingScopeStrategy + .getMappingScope(startPoint); + logger.info("found_" + mappingScope.size() + + " elements to transform"); + for (ModelElement me : mappingScope) { + if (me == null) { + logger.info("model element = null"); + } else if (me.getName() == null) { + logger.info("model element name = null. type = " + + me.getClass().getName()); + } else { + logger.info(me.getName()); + } + } + transformModelElements(mappingScope); + transformAssociations(mappingScope); + initActionHierarchies(); + + // TODO: transform only relevant permissions + // (such attached to Resources in the mappingScope) + findSecumlModelElements(startPoint); + transformAllRoles(); + tramsformAllPolicies(); + transformAllPermisssions(); + + ensureNeededElementsExist(startPoint); + + return map.getElement(startPoint); + } else + return null; + } + + /** + * @return the permissionsAssociations + */ + public Set getPermissionsAssociations() { + return permissionsAssociations; + } + + /** + * @return the roleClasses + */ + public Set getRoleClasses() { + return roleClasses; + } + + public Set getPolicyClasses() { + return policyClasses; + } + + /** + * @return the roleHierarchyGeneralizations + */ + public Set getRoleHierarchyGeneralizations() { + return roleHierarchyGeneralizations; + } + + /** + * @return the policyHierarchyGeneralizations + */ + public Set getPolicyHierarchyGeneralizations() { + return this.policyHierarchyGeneralizations; + } + + /** + * + * @param permission a permission which is assigned to a policy + * @return the assigned policy + */ + public UmlClass getPolicy(UmlAssociation permission) { + StringBuffer buff = new StringBuffer(); + + for ( String key : policyAssignments.keySet()) { + buff.append(key + "::"); + } + + aLog.debug("policyAssignments contains " + policyAssignments.size() + " entries: " + buff.toString() + "\n search for " + permission.getName()); + if ( policyAssignments.containsKey(permission.getName()) ) { + return policyAssignments.get(permission.getName()); + } else { + aLog.warn("TODO: assigned default policy to permission?"); + return (UmlClass) this.getDefaultPolicy(); + } + } + + + /** + * returns the package inside the dialect metamodel containing the design + * modeling language elements. E.g., the ComponentUML package inside the + * dialect metamodel for ComponentUML. FIXME: should this function really be + * here, or somewhere else? + */ + private RefPackage getDialectPackage() { + return (RefPackage) Util.invokeParameterlessMethod(dialectMetaModelInfo + .getDialectExtent(), "get" + + dialectMetaModelInfo.getDialectName()); + } + + + + /** + * create all action instances that are defined for + * metaModelObject of type resourceType. + * + * @param resourceType + * @param metaModelObject + */ + private void instantiateAllActions(ResourceType resourceType, + RefObject metaModelObject) { + if (metaModelObject == null) { + logger.error("metaModelObject = null"); + } + try { + for (Iterator iter = dialectMetaModelInfo + .getActionTypesOfResourceType(resourceType).iterator(); iter + .hasNext();) { + + ActionType at = (ActionType) iter.next(); + + Object action = getOrCreateAction(metaModelObject, at + .getShortName()); + } + + } catch (Exception e) { + logger.logException(e); + } + } + + private void initActionHierarchies() { + for (Iterator iter = actions.iterator(); iter.hasNext();) { + try { + + Object action = (Object) iter.next(); + + ActionWrapper actionWrapper = new ActionWrapper(action); + + Object resource = actionWrapper.getResource(); + ModelElement resourceUml = (ModelElement) map + .getUmlElement(resource); + + ResourceType rt = helper.getResourceType(resourceUml); + + ActionType at = dialectMetaModelInfo. + // getActionTypeByName(actionWrapper.getName()); + getActionType(rt, actionWrapper.getName()); + + if (at != null && at.getSubactionsDefinition() != null) { + logger.info(logger.MODELMAPPER_DETAILLED, + "examining Action Hierarchy of " + at.getName()); + try { + // CompositeActionType compositeActionType = + // (CompositeActionType) at; + + String subactionsDefinitionString = at + .getSubactionsDefinition(); + + OclExpressionsParser parser = new OclExpressionsParser(); + + OclExpression subactionsDefinition = parser + .parseOclExpression(subactionsDefinitionString); + + OclExpressionEvaluator evaluator = new OclExpressionEvaluator( + subactionsDefinition, actionWrapper + .getModelElement()); + // + Set subactions = evaluator.evaluateExpression(); + + for (Iterator iterator = subactions.iterator(); iterator + .hasNext();) { + Object subaction = (Object) iterator.next(); + + logger.info(logger.MODELMAPPER_DETAILLED, + "found Action Hierarchy: " + + actionWrapper.getName() + + "->" + + Util.getProperty(subaction, + "name")); + + Collection actionSubactions = (Collection) Util + .getProperty(action, "subactions"); + Collection subactionSuperactions = (Collection) Util + .getProperty(subaction, "superactions"); + + actionSubactions.add(subaction); + subactionSuperactions.add(action); + } + + } catch (Exception e) { + logger.logException(e); + } + } + } catch (Exception e) { + logger.logException(e); + } + } + } + + /** + * Maps all resources in the mappingScope. + * + * @param mappingScope + */ + private void transformModelElements(Collection mappingScope) { + if (mappingScope.size() == 0) { + logger.error("no model elements to transform!"); + return; + } + + for (Iterator iter = mappingScope.iterator(); iter.hasNext();) { + try { + ModelElement modelElement = (ModelElement) iter.next(); + examineModelElement(modelElement); + } catch (Exception e) { + logger.logException(e); + } + } + + //ensureNeededElementsExist(mappingScope.iterator().next()); + } + + private void transformAssociations(Collection mappingScope) { + for (Iterator iter = mappingScope.iterator(); iter.hasNext();) { + try { + ModelElement umlModelElement = (ModelElement) iter.next(); + + Object secureUmlModelElement = map.getElement(umlModelElement); + + MetaModelClass metaModelClass = helper + .getMetaModelClass(umlModelElement); + + Collection associations = dialectMetaModelInfo + .getInterResourceAssociations(metaModelClass); + + if (associations != null) { + for (Iterator iterator = associations.iterator(); iterator + .hasNext();) { + try { + InterResourceAssociation association = (InterResourceAssociation) iterator + .next(); + + Collection values = helper.navigateAssociation( + umlModelElement, association); + + MetaModelClass mmClass = helper + .getMetaModelClass(umlModelElement); + + // String umlGetterName = + // association.getOtherEnd(mmClass). + // getUmlPropertyGetter(); + // + Class[] argTypes = new Class[0]; + // + // Method umlGetter = umlModelElement.getClass(). + // getMethod(umlGetterName, argTypes); + + String secureUmlGetterName = association + .getOtherEnd(mmClass).getGetterName(); + + Method secureUmlGetter = secureUmlModelElement + .getClass().getMethod(secureUmlGetterName, + argTypes); + + if (values != null // otherwise, there is nothing + // to do + // because no associated elements to map + && secureUmlGetter != null + && secureUmlGetter != null) { + Object value = secureUmlGetter.invoke( + secureUmlModelElement, new Object[0]); + + Class propertyType = secureUmlGetter + .getReturnType(); + + if (value instanceof Collection) // -> + // propertyType.equals(Collection.class) + // i.e. Association is multiple + // -> Collection Property -> no Setter + { + if (value == null) { + logger + .error("Collection Property not initialized: " + + secureUmlGetterName); + continue; + } + // else + + Collection valueCollection = (Collection) value; + + for (Iterator it = values.iterator(); it + .hasNext();) { + try { + RefObject umlValue = (RefObject) it + .next(); + + if (umlValue instanceof ModelElement + && helper + .hasType( + (ModelElement) umlValue, + association + .getOtherEnd( + mmClass) + .getType() + .getUmlClassName()) + && map + .mapContainsKey(umlValue)) { + Object secureUmlValue = map + .getElement(umlValue); + if (secureUmlValue != null) { + try { + + valueCollection + .add(secureUmlValue); + } catch (Exception e) { + logger + .error("failed to add Object of Type " + + secureUmlValue + .getClass() + + "to" + + secureUmlGetterName); + // logger.logException(e); + } + + } else { + logger + .warn("Association value not modelmapped: " + + umlValue + .getClass() + .getSimpleName()); + } + } + } catch (Exception e) { + logger.logException(e); + } + } + } else + // no Collection Property -> there must be a + // Setter + { + + String setterName = association + .getOtherEnd( + helper + .getMetaModelClass(umlModelElement)) + .getSetterName(); + + if (setterName != null) { + argTypes = new Class[1]; + argTypes[0] = propertyType; + + Method setter = secureUmlModelElement + .getClass().getMethod( + setterName, argTypes); + + if (setter != null) { + Object[] args = new Object[1]; + Object umlValue = null; + if (values.iterator().hasNext()) { + umlValue = values.iterator() + .next(); + } + if (umlValue instanceof RefObject + && map + .mapContainsKey((RefObject) umlValue)) { + args[0] = map + .getElement((RefObject) umlValue); + try { + setter + .invoke( + secureUmlModelElement, + args); + } catch (Exception e) { + logger + .error("problem executing " + + setterName + + " on object " + + secureUmlModelElement); + logger.logException(e); + } + } + } + } + } + } + } catch (Exception e) { + logger.logException(e); + } + } + } + } + + // AssociationEnd a;a.getp + catch (Exception e) { + logger.logException(e); + } + } + } + + // protected void findSecumlModelElements() + // { + // findSecumlModelElements();//modelPackage); + // } + /** + * Finds all the SecureUML Elements, i.e., roles, permissions and action + * types, etc. Goes to the top-most namespace and calls + * {@link #findSecumlModelElements(Collection)} from there. + */ + protected void findSecumlModelElements(ModelElement resource) { + if (resource == null) { + return; + } + Namespace n = null; + + if (resource instanceof Namespace) + n = (Namespace) resource; + else + n = resource.getNamespace(); + + if (n == null) { + Classifier anchor = helper.findAnchor(resource); + n = anchor.getNamespace(); + } + + if (n == null) { + logger.error("couldn't find namespace for resource " + resource); + return; + } + + Namespace outerNs = n.getNamespace(); + while (outerNs != null && n != outerNs) { + n = outerNs; + outerNs = n.getNamespace(); + } + + Collection modelElements = n.getOwnedElement(); + + findSecumlModelElements(modelElements); + + // RefPackage p = n.refImmediatePackage();//refOutermostPackage(); + + // findSecumlModelElements(p); + } + + /** + * Finds the SecureUML elements in the given collection of model elements. + * Found elements are stored in {@link #roleClasses}, + * {@link #permissionsAssociations}, {@link #roleHierarchyGeneralizations}, + * {@link ch.ethz.infsec.secureumlgui.transformation.ModelMap#stereotypeMap} + * {@link ch.ethz.infsec.secureumlgui.transformation.ModelMap#actionMap} + * Recurses into packages and namespaces. + * + * @param modelElements + */ + private void findSecumlModelElements(Collection modelElements) + { + + + //for (Iterator iter = modelElements.iterator(); iter.hasNext();) + for ( Object item : modelElements ) + { + //Object item = iter.next(); + + if (item instanceof Stereotype) + { + Stereotype stereotype = (Stereotype) item; + + map.putStereotype(stereotype); + + aLog.debug("Found Stereotype: " + stereotype.getName()); + } + else if (item instanceof AssociationClass) + { + AssociationClass association = (AssociationClass) item; + + if(isOfType(association, SecureUmlConstants.STEREOTYPE_SECUML_PERMISSION)) + { + aLog.debug("Found SecureUml Permission Association: " + + association.getName() + " : " + + association.getClass().getSimpleName()); + + permissionsAssociations.add(association); + + //TODO assign this association to the corresponding policy and save via policy as key in permissionsPerPolicy + // when a permission is not assigned to a policy, assign to DEFAULT_POLICY_IDENTIFIER + } +// else +// logger.info("this is not a SecureUml Permission: " + association.getName()); + } + else if(item instanceof UmlClass) + { + UmlClass umlClass = (UmlClass) item; + + if(isOfType(umlClass, SecureUmlConstants.STEREOTYPE_SECUML_ROLE)) + { + aLog.debug("Found a SecureUML Role: " + umlClass.getName()); + roleClasses.add(umlClass); + } + else if (isOfType(umlClass, SecureUmlConstants.STEREOTYPE_SECUML_POLICY)) + { + aLog.debug("Found a SecureUML Policy: " + umlClass.getName()); + policyClasses.add(umlClass); + } + else if(isOfType(umlClass, SecureUmlConstants.STEREOTYPE_SECUML_ACTIONTYPE)) + { + aLog.debug("Found a SecureUML ActionType: " + umlClass.getName()); + map.putActionClass(umlClass.getName(), umlClass); + } +// else +// logger.info("this is not a SecureUml Role: " + umlClass.getName()); + } + else if (item instanceof Generalization) + { + Generalization generalization = (Generalization) item; + if (isOfType(generalization.getChild(),SecureUmlConstants.STEREOTYPE_SECUML_ROLE) + && isOfType(generalization.getParent(), SecureUmlConstants.STEREOTYPE_SECUML_ROLE)) { + roleHierarchyGeneralizations.add(generalization); + } + + if (isOfType(generalization.getChild(),SecureUmlConstants.STEREOTYPE_SECUML_POLICY) + && isOfType(generalization.getParent(), SecureUmlConstants.STEREOTYPE_SECUML_POLICY)) { + this.policyHierarchyGeneralizations.add(generalization); + } + } + else if (item instanceof Namespace) + { + Namespace namespace = (Namespace) item; + + findSecumlModelElements(namespace.getOwnedElement()); + + // findSecumlModelElements(namespace); + } + else if(item instanceof org.omg.uml.UmlPackage) + { + org.omg.uml.UmlPackage p = (org.omg.uml.UmlPackage) item; + + logger.info("UmlPackage Element found!!"); + + Collection me = new LinkedList(); + + me.addAll(p.refAllAssociations()); + me.addAll(p.refAllClasses()); + me.addAll(p.refAllPackages()); + findSecumlModelElements(me); + } + else if ( item instanceof UmlAssociation) { + UmlAssociation asso = (UmlAssociation) item; + + List assoEnds = asso.getConnection(); + + boolean perm_pol = true; + + UmlClass policy = null; + AssociationClass permission = null; + + if ( assoEnds.size() == 2 ) { + for ( AssociationEnd end : assoEnds ) { + Classifier classf = end.getParticipant(); + + if ( isOfType(classf, SecureUmlConstants.STEREOTYPE_SECUML_PERMISSION) ) { + permission = (AssociationClass) classf; + } else if ( isOfType(classf, SecureUmlConstants.STEREOTYPE_SECUML_POLICY) ) { + policy = (UmlClass) classf; + } else { + perm_pol = false; + break; + } + } + } else { + perm_pol = false; + } + + if ( perm_pol ) { + aLog.debug("found a UmlAssociation between policy " + policy.getName() + " and permission " + permission.getName()); + policyAssignments.put(permission.getName(), policy); + } + + } + else + { + aLog.warn(item.getClass() + " Element not handled!"); + } + } + } + + /** + * maps all roles in {@link #roleClasses}. Takes into account the role + * inheritance from {@link #roleHierarchyGeneralizations} + */ + protected void transformAllRoles() { + for ( UmlClass roleClass : roleClasses ) { + transformRole(roleClass); + } + for (Generalization roleHierarchyGeneralization : roleHierarchyGeneralizations ) { + transformRoleInheritance(roleHierarchyGeneralization); + } + } + + /** maps all permissions in {@link #permissionsAssociations}. */ + protected void transformAllPermisssions() { + for (AssociationClass permissionAssociation : permissionsAssociations ) { + transformPermissionClass(permissionAssociation); + } + } + + protected void tramsformAllPolicies() { + for ( UmlClass policyClass : policyClasses ) { + transformPolicy(policyClass); + } + + for (Generalization policyHierarchyGeneralization : policyHierarchyGeneralizations ) { + transformPolicyInheritance(policyHierarchyGeneralization); + } + + } + + + private RefObject defaultPolicy = null; + private PolicyWrapper defaultPolicyWrapper = null; + + public Object getDefaultPolicy() { + + + return null; +// if ( defaultPolicy == null ) { +// defaultPolicy = SecureModelFactory.getInstance().createPolicy(SecureUmlConstants.DEFAULT_POLICY_NAME); +// } +// return defaultPolicy; + } + + public PolicyWrapper getDefaultPolicyWrapper() { +// if ( defaultPolicyWrapper == null ) { +// defaultPolicyWrapper = new PolicyWrapper(getDefaultPolicy()); +// } +// return defaultPolicyWrapper; + return null; + } + + + + // public void examineUmlClass(UmlClass umlClass) + // { + // // no special treatment -> this method not needed here + // super.examineUmlClass(umlClass); + // } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/ModelMapper.java b/src/ch/ethz/infsec/secureumlgui/modelmapping/ModelMapper.java new file mode 100644 index 0000000..4ea4d8c --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/ModelMapper.java @@ -0,0 +1,70 @@ +package ch.ethz.infsec.secureumlgui.modelmapping; + +import javax.jmi.reflect.RefPackage; + +// import tudresden.ocl20.core.jmi.uml15.core.Association; +// import tudresden.ocl20.core.jmi.uml15.core.Generalization; +// import tudresden.ocl20.core.jmi.uml15.core.UmlAssociationClass; +// import tudresden.ocl20.core.jmi.uml15.core.UmlClass; + +import org.omg.uml.foundation.core.UmlClass; +import org.omg.uml.foundation.core.Generalization; +import org.omg.uml.foundation.core.UmlAssociation; +import org.omg.uml.foundation.core.UmlAssociationClass; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.transformation.ModelMap; + + +/** + * Base class that doesn't do much. The real functionality is in the subclasses. + * + * @version 1.0 + */ +public class ModelMapper +{ + + public ModelMapper() + { + } + + public void init() + { + map.clear(); + } + + protected static MultiContextLogger logger = new MultiContextLogger(MultiContextLogger.MODELMAPPER); + + protected ModelMap map = ModelMap.getDefault(); + + @SuppressWarnings("unchecked") + public void transform() + { + // empty + } + + protected void examineUmlClass(UmlClass umlClass) + { + // empty + } + + protected void examineUmlGeneralization(Generalization generalization) + { + // empty + } + + protected void examineUmlAssociationClass( + UmlAssociationClass associationClass) + { + // empty + } + + protected void examineUmlAssociation(UmlAssociation assoc) + { + // empty + } + + public ModelMap getModelMap() + { + return map; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/ModelWriter.java b/src/ch/ethz/infsec/secureumlgui/modelmapping/ModelWriter.java new file mode 100644 index 0000000..0f00b74 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/ModelWriter.java @@ -0,0 +1,860 @@ +package ch.ethz.infsec.secureumlgui.modelmapping; + +import java.security.InvalidParameterException; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.jmi.model.Association; +import javax.jmi.reflect.RefObject; + +import org.apache.log4j.Logger; +import org.argouml.kernel.Project; +import org.argouml.kernel.ProjectManager; +import org.argouml.model.CoreFactory; +import org.argouml.model.CoreHelper; +import org.argouml.model.Facade; +import org.argouml.model.Model; +import org.omg.uml.foundation.core.AssociationClass; +import org.omg.uml.foundation.core.AssociationEnd; +import org.omg.uml.foundation.core.Attribute; +import org.omg.uml.foundation.core.Classifier; +import org.omg.uml.foundation.core.ModelElement; +import org.omg.uml.foundation.core.Namespace; +import org.omg.uml.foundation.core.Operation; +import org.omg.uml.foundation.core.Stereotype; +import org.omg.uml.foundation.core.UmlAssociation; +import org.omg.uml.foundation.core.UmlClass; +import org.omg.uml.modelmanagement.UmlPackage; + +//import java.lang.String; + +import ch.ethz.infsec.secureumlgui.Util; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.main.SecureUmlConstants; +import ch.ethz.infsec.secureumlgui.modelmanagement.ModelConst; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ActionType; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.MetaModelConst; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ResourceType; +import ch.ethz.infsec.secureumlgui.transformation.ModelMap; +import ch.ethz.infsec.secureumlgui.util.PermissionDummy; +import ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.NamedModelElementWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PermissionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PolicyWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.ResourceWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.RoleWrapper; + +/** + * Writes SecureUml Model Elements to UML Model. + * + * Only elements for which a mapping is contained in modelmap can be written + * + * + */ +public class ModelWriter { + + public ModelWriter(ModelMap modelmap) { + this.modelmap = modelmap; + } + + ModelMap modelmap; + + GenericDialectHelper helper = GenericDialectHelper.getInstance(); + + private Logger aLog = Logger.getLogger(ModelWriter.class); + + + private int hack_count = 0; + + + + /** + * ModelMap containing (both-sided) Mapping between UML Model Elements and + * SecureUml Entities. + * + */ + public ModelMap getModelmap() { + return modelmap; + } + + MultiContextLogger logger = MultiContextLogger.getDefault(); + + public void createPermission(Object resourceUml, Object roleUml, + ActionWrapper actionWrapper, Set policies) { + String name = helper.getResourcePath((ModelElement) resourceUml); + + createPermission(resourceUml, roleUml, name, actionWrapper, policies); + } + + public void createPermission(ResourceWrapper resourceWrapper, + RoleWrapper roleWrapper, ActionWrapper actionWrapper, Set policies) { + Object secUmlModelElement = resourceWrapper.getModelElement(); + + ModelElement resourceUml = (ModelElement) getModelmap().getUmlElement( + secUmlModelElement); + + String permissionAttributeName = getPermissionAttributeName(resourceUml); + + createPermission(resourceWrapper, roleWrapper, permissionAttributeName, + actionWrapper, policies); + } + + protected void createPermission(Object resourceUml, Object roleUml, + String permissionAttributeName, ActionWrapper actionWrapper, Set policies) { + + Classifier anchor = helper.findAnchor((ModelElement) resourceUml); + + createPermissionViaModelCore(permissionAttributeName, resourceUml, + (Classifier) anchor, (Classifier) roleUml, actionWrapper, policies); + } + + //XXX +// protected void createPermission(ResourceWrapper resourceWrapper, +// RoleWrapper roleWrapper, String permissionAttributeName, +// ActionWrapper actionWrapper) { +// try { +// logger.info(logger.MODELWRITER, "creating Permission: \n" +// + " resourceWrapper: " + resourceWrapper.getName() + "\n" +// + " roleWrapper: " + roleWrapper.getName() + "\n" +// + " actionWrapper: " + actionWrapper.getName()); +// +// RefObject resourceUml = getModelmap().getUmlElement( +// resourceWrapper.getModelElement()); +// +// Classifier anchor = helper.findAnchor((ModelElement) resourceUml); +// +// Classifier roleClassifier = (Classifier) getModelmap() +// .getUmlElement(roleWrapper.getModelElement()); +// +// createPermissionViaModelCore(permissionAttributeName, resourceUml, +// anchor, roleClassifier, actionWrapper); +// } catch (Exception e) { +// logger.logException(e); +// } +// } + + protected void createPermission(ResourceWrapper resourceWrapper, + RoleWrapper roleWrapper, String permissionAttributeName, + ActionWrapper actionWrapper, Set policies) { + try { + logger.info(logger.MODELWRITER, "creating Permission: \n" + + " resourceWrapper: " + resourceWrapper.getName() + "\n" + + " roleWrapper: " + roleWrapper.getName() + "\n" + + " actionWrapper: " + actionWrapper.getName()); + + RefObject resourceUml = getModelmap().getUmlElement( + resourceWrapper.getModelElement()); + + Classifier anchor = helper.findAnchor((ModelElement) resourceUml); + + Classifier roleClassifier = (Classifier) getModelmap() + .getUmlElement(roleWrapper.getModelElement()); + + //Classifier policyClassifier = (Classifier) getModelmap().getUmlElement(policyWrapper.getModelElement()); + + + + createPermissionViaModelCore(permissionAttributeName, resourceUml, + anchor, roleClassifier, actionWrapper, policies); + } catch (Exception e) { + logger.logException(e); + } + } + + /** + * @param anchor + * @param roleClass + * @param actionWrapper + */ + protected void createPermissionViaModelCore(String permissionName, + Object resourceUml, Classifier anchor, Classifier roleClass, + ActionWrapper actionWrapper, Set policies) { + try { + // check if Association class + // with same Name already exists! + String newPermissionName = permissionName + + Util.getNewPermissionNumber(); + + Collection classifiers = null; + + boolean isNameAlreadyUsed = false; + + do { + isNameAlreadyUsed = false; + if (classifiers != null) { + for (Iterator iter = classifiers.iterator(); iter.hasNext();) { + Classifier classifier = (Classifier) iter.next(); + + if (classifier.getName().equalsIgnoreCase( + newPermissionName)) { + isNameAlreadyUsed = true; + + logger.info(logger.MODELWRITER, + "AssociationClass with Name " + + newPermissionName + + " already exists -> " + + "incrementing sequence Number"); + + newPermissionName = permissionName + + Util.getNewPermissionNumber(); + break; + } + } + } + } while (isNameAlreadyUsed); + + AssociationClass newUmlPermission = (AssociationClass) Model + .getCoreFactory().buildAssociationClass(anchor, roleClass); + + logger.info("Permission AssociationClass created: " + + newUmlPermission.getName()); + + UmlPackage permissionPackage = GenericDialectModelMapper.getInstance().getPermissionPackage(); + + newUmlPermission.setName(newPermissionName); + newUmlPermission.setNamespace(permissionPackage); // TODO + + + + + // hel put permission in sub namespace + newUmlPermission.setActive(true); + + Stereotype stereotype = null;// Util.findStereotypeByName(newUmlPermission, + // SecureUmlConstants.STEREOTYPE_SECUML_PERMISSION); + + // TODO; + // Util.findStereotypeByName(newUmlPermission, + // SecureUmlConstants.STEREOTYPE_SECUML_PERMISSION); + stereotype = getOrCreateStereotype(newUmlPermission, + SecureUmlConstants.STEREOTYPE_SECUML_PERMISSION, + newUmlPermission.getNamespace()); + // modelmap.getStereotype(SecureUmlConstants.STEREOTYPE_SECUML_PERMISSION); + + newUmlPermission.getStereotype().add(stereotype); + + String permissionAttributeName = getPermissionAttributeName((ModelElement) resourceUml); + + String actionShortname = actionWrapper.getName(); + + Classifier actionType = getOrCreateActionType(actionShortname, + newUmlPermission.getNamespace()); + + // TODO: examine the Type + + // String attributeName = helper.getResourcePath( + // (ModelElement)resourceUml); + + Attribute permissionAttribute = (Attribute) addAttribute( + newUmlPermission, "foobar", actionType); + + permissionAttribute.setName(permissionAttributeName); + + permissionAttribute.setType(actionType); + + // TODO: examine Stereotype + + String stereotypeName = getActionStereotype(resourceUml); + + stereotype = getOrCreateStereotype(permissionAttribute, + stereotypeName, newUmlPermission.getNamespace()); + + if (stereotype != null) + permissionAttribute.getStereotype().add(stereotype); + + + + if (policies != null || policies.size() == 0 ) { + + + if (policies.size() != 1) { + aLog.error("All policies than the first are ignored.... TODO!"); + } + + + PolicyWrapper policyWrapper = policies.iterator().next(); + + + Classifier policy = (Classifier) getModelmap().getUmlElement(policyWrapper.getModelElement()); + +// UmlAssociation perm_pol = (UmlAssociation) Model.getCoreFactory().buildAssociation( +// newUmlPermission, true, policy, true, "permission_policy_" + ++hack_count); + UmlAssociation perm_pol = (UmlAssociation) Model.getCoreFactory().buildAssociation( + newUmlPermission, true, policy, true, policyWrapper.getName() + "_permission_" + ++hack_count); + + perm_pol.setNamespace(permissionPackage); + +// System.out.println("assoc connection count: " +perm_pol.getConnection().size()); +// +// Object assE1 = Model.getCoreFactory().buildAssociationEnd(newUmlPermission, perm_pol); +// System.out.println("XX1: " + assE1.getClass().toString()); +// +// +// Object assE2 = Model.getCoreFactory().buildAssociationEnd(policy, perm_pol); +// System.out.println("XX2: " + assE2.getClass().toString()); +// +// System.out.println("assoc connection count: " +perm_pol.getConnection().size()); + + logger.info("added association to policy " + policyWrapper.getName() + " result: " + perm_pol.getClass().toString()); + aLog.debug("added association to policy " + policyWrapper.getName() + " result: " + perm_pol.getClass().toString()); + +// System.out.println(perm_pol + " ## " + newUmlPermission); +// AssociationEnd newAss = (AssociationEnd) Model.getCoreFactory().buildAssociationEnd(perm_pol, newUmlPermission ); + + + CoreFactory coreFact = Model.getCoreFactory(); + + + List newEnds = perm_pol.getConnection(); + + try { + for (AssociationEnd end : newEnds ) { + if (end.getParticipant().equals(newUmlPermission)) { + aLog.debug("found association end: " + end + "\nnavigateable: " + end.isNavigable() + " " + end.getAggregation()); + + //newUmlPermission.getConnection().add(end); + } + else { + aLog.debug("not the right end... " + end.getParticipant()); + } + } + } catch(Exception e) { + aLog.error("Error at adding association end: ", e); + e.printStackTrace(); + } + + + +// try { +// +// AssociationEnd newAss = (AssociationEnd) coreFact.buildAssociationEnd(newUmlPermission.getConnection().get(0).getParticipant(), perm_pol); +// //AssociationEnd newAss = (AssociationEnd) coreFact.buildAssociationEnd(newUmlPermission, perm_pol); +// //AssociationEnd newAss = (AssociationEnd) coreFact.buildAssociationEnd(policy, perm_pol); +// //newUmlPermission.get +// aLog.debug("Created AssociationEnd: " + newAss); +// aLog.debug("getParticipant: " + newAss.getParticipant()); +// +// newUmlPermission.getConnection().add(newAss); +// aLog.debug("Added AssociationEnd to new permission"); +// +// //newUmlPermission.getConnection(). +// //perm_pol.getConnection().add(newAss); +// +// } catch (Exception e) { +// aLog.error("Could not create/add AssociationEnd: " + e.getClass() + ": " + e.getMessage()); +// System.out.println("####################################################"); +// e.printStackTrace(); +// +// aLog.error(e); +// } + + + +// AssociationEnd newAss = (AssociationEnd) Model.getCoreFactory().buildAssociationEnd( +// perm_pol, +// "assEnd_" + ++hack_count2, +// newUmlPermission, +// +// +// +// +// assoc - The associaton this end will be part of +// name - The name of the association end +// type - The type (classifier) the end will connect. The end is a connection piece between an association and a classifier +// multi - The multiplicity +// stereo - The stereotype +// navigable - The navigability. True if this association end can be 'passed' from the other classifier. +// order - Ordering of the association +// aggregation - the aggregationkind +// scope - the scope kind +// changeable - the changeablekind +// visibility - the visibilitykind +// newUmlPermission.getConnection().add(newAss); + + + + + +// for ( AssociationEnd assEnd : perm_pol.getConnection() ) { +// Classifier classf = assEnd.getParticipant(); +// +// +// if ( classf != policy ) { +// newUmlPermission.getConnection().add(assEnd); +// } +// //classf. +// +// //AssociationClass (perm_pol) bzw. +// //UmlClass (policy) +// +// //policy.get +// +// +// //aLog.debug(classf + " == " + ( classf == policy ) + " equals " + (classf.equals(policy))+ " ### == " + ( classf == perm_pol ) + " equals " + (classf.equals(perm_pol))); +// } + aLog.debug("PERMISSION:"); + for ( AssociationEnd assEnd : newUmlPermission.getConnection() ) { + aLog.debug(" with AssociationEnd " + assEnd); + } + + aLog.debug("POLICY: " + policy); + +// ModelElement asdf = null; +// asdf. + //UmlClass policyUml = (UmlClass) policy; + + + +// for ( AssociationEnd assEnd : ( (UmlClass) policy)..getOwnedElement()..getConnection() ) { +// aLog.debug(" with AssociationEnd " + assEnd); +// } + + + } + + } catch (Exception e) { + logger.logException(e); + } + } + + /** + * @param actionShortname + * @return the action classifier + */ + private Classifier getOrCreateActionType(String actionShortname, + Namespace ns) { + try { + Classifier actionType = modelmap.getActionClass(actionShortname); + + if (actionType == null) { +// Namespace secureUmlNs = helper.findNamespaceByName(ns, +// "SecureUML"); + Namespace secureUmlNs = GenericDialectModelMapper.getInstance().getSecUMLPackage(); + + if (secureUmlNs != null) + ns = secureUmlNs; + + actionType = (UmlClass) Model.getCoreFactory().createClass(); + + Stereotype actionTypeStereotype = getOrCreateStereotype( + actionType, + SecureUmlConstants.STEREOTYPE_SECUML_ACTIONTYPE, ns); + + actionType.setName(actionShortname); + actionType.setNamespace(ns); + actionType.getStereotype().add(actionTypeStereotype); + } + return actionType; + } catch (Exception e) { + logger.logException(e); + return null; + } + } + + /** + * If Stereotype with the passed name exists (-> is stored in the Modelmap), + * return it. Otherwise, create new Stereotype in the Namespace passed as + * Argument + * + * @param name + * @param ns + * @return the stereotype + */ + public Stereotype getOrCreateStereotype(ModelElement modelElementObject, + String name, Namespace ns) { + Stereotype stereotype = modelmap.getStereotype(name); + + if (stereotype == null) { + stereotype = (Stereotype) Model.getExtensionMechanismsFactory() + .buildStereotype(modelElementObject, name, ns); + } + + + + return stereotype; + } + + + public Stereotype getOrCreateStereotype(String name, UmlPackage secUMLPackage, String base) { + Stereotype stereotype = modelmap.getStereotype(name); + + if (stereotype == null) { + stereotype = (Stereotype) Model.getExtensionMechanismsFactory().buildStereotype(name, secUMLPackage); + if ( base != null ) { + stereotype.getBaseClass().add(base); + } + //Model.getCoreHelper().setOwner(stereotype, secUMLPackage); + modelmap.putStereotype(stereotype); + } + + return stereotype; + + } + + + + /** + * @param resourceUml + */ + private String getPermissionAttributeName(ModelElement resourceUml) { + // String resourceName = resourceUml.getName(); + try { + String resourcePath = helper.getResourcePath(resourceUml); + return resourcePath; + } catch (Exception e) { + logger.logException(e); + } + return ""; + } + + private String getActionStereotype(Object resourceUml) { + try { + ModelElement umlModelElement = (ModelElement) resourceUml; + ResourceType rt = helper.getResourceType(umlModelElement); + return rt.getActionStereotype(); + } catch (Exception e) { + logger.logException(e); + return null; + } + } + + /** + * To add a permission-Attribute to a Permission AssociationClass + * + * copied from org.argouml.ui.targetmanager.ActionWrapperAddAttribute + * + */ + public Object addAttribute(Classifier classifier, String name, + Classifier type) { + Attribute attribute = (Attribute) Model.getCoreFactory() + .createAttribute(); + attribute.setName(name); + attribute.setType(type); + classifier.getFeature().add(attribute); + + return attribute; + } + + /** + * Adds a new Permission with the first ActionWrapper of the permission + * Argument to the underlying Uml Model + */ + public void addPermission(PermissionWrapper permissionWrapper) { + try { + ActionWrapper actionWrapper = permissionWrapper.getActionWrapper(); + if (actionWrapper == null) { + logger.error(logger.MODELMAPPER, + "added Permission contains no action " + + "-> abort adding"); + } else { + RoleWrapper roleWrapper = permissionWrapper.getRoleWrapper(); + addPermission(actionWrapper, roleWrapper, permissionWrapper.getPolicyWrappers()); + } + } catch (Exception e) { + logger.logException(e); + } + } + + //XXX +// /** +// * @param actionWrapper +// * @param roleWrapper +// */ +// public void addPermission(ActionWrapper actionWrapper, +// RoleWrapper roleWrapper) { +// ResourceWrapper resourceWrapper = actionWrapper.getResourceWrapper(); +// +// ModelElement resourceUml = (ModelElement) modelmap +// .getUmlElement(actionWrapper.getResource()); +// ModelElement anchorUml = helper.findAnchor(resourceUml); +// +// logger.info("addPermission(anchor: " + anchorUml.getName() +// + ", resource: " + resourceUml.getName() + ", action: " +// + actionWrapper.getName()); +// +// Object suAnchor = modelmap.getElement(anchorUml); +// NamedModelElementWrapper anchorWrapper = new NamedModelElementWrapper( +// suAnchor); +// +// String permissionName = "" + roleWrapper.getName() +// // + resourceWrapper.getName() +// // +anchorWrapper.getName() +// + anchorUml.getName() +// // + getNewPermissionSuffix(); +// + SecureUmlConstants.NEW_PERMISSION_SUFFIX; +// +// createPermission(resourceWrapper, roleWrapper, permissionName, +// actionWrapper); +// } + + + + /** + * @param actionWrapper + * @param roleWrapper + */ + public void addPermission(ActionWrapper actionWrapper, + RoleWrapper roleWrapper, Set policies) { + ResourceWrapper resourceWrapper = actionWrapper.getResourceWrapper(); + + ModelElement resourceUml = (ModelElement) modelmap + .getUmlElement(actionWrapper.getResource()); + ModelElement anchorUml = helper.findAnchor(resourceUml); + + logger.info("addPermission(anchor: " + anchorUml.getName() + + ", resource: " + resourceUml.getName() + ", action: " + + actionWrapper.getName()); + + Object suAnchor = modelmap.getElement(anchorUml); + NamedModelElementWrapper anchorWrapper = new NamedModelElementWrapper( + suAnchor); + + String permissionName = "" + roleWrapper.getName() + // + resourceWrapper.getName() + // +anchorWrapper.getName() + + anchorUml.getName() + // + getNewPermissionSuffix(); + + SecureUmlConstants.NEW_PERMISSION_SUFFIX; + + createPermission(resourceWrapper, roleWrapper, permissionName, + actionWrapper, policies); + } + + public void deletePermission(PermissionWrapper permissionWrapper) { + + deletePermissionViaModelUml(permissionWrapper); + + } + + public UmlClass createRole(String roleName, Namespace namespace) { + try { + // check if Class + // with same Name already exists! + String newRoleName = roleName + Util.getNewPermissionNumber(); + + Collection classifiers = Model.getCoreHelper().getAllClassifiers( + namespace); + boolean isNameAlreadyUsed = false; + + do { + isNameAlreadyUsed = false; + for (Iterator iter = classifiers.iterator(); iter.hasNext();) { + Classifier classifier = (Classifier) iter.next(); + + if (classifier.getName().equalsIgnoreCase(newRoleName)) { + isNameAlreadyUsed = true; + + logger.info(logger.MODELWRITER, "Class with Name " + + newRoleName + " already exists -> " + + "incrementing sequence Number"); + + newRoleName = roleName + Util.getNewPermissionNumber(); + break; + } + } + } while (isNameAlreadyUsed); + + // END - found unique Name for the new role + + UmlClass newRole = (UmlClass) Model.getCoreFactory().buildClass( + newRoleName); + + Stereotype secumlRole = getOrCreateStereotype(newRole, + SecureUmlConstants.STEREOTYPE_SECUML_ROLE, newRole + .getNamespace()); + newRole.getStereotype().add(secumlRole); + newRole.setNamespace(namespace); + newRole.setActive(true); + + return newRole; + } catch (Exception e) { + logger.logException(e); + return null; + } + } + + public UmlClass createPolicy(String policyName, Namespace namespace) { + // TODO assure that the policy does not exist + + aLog.debug("createPolicy: Model.getCoreFactory().buildClass(policyName)"); + UmlClass newPolicy = (UmlClass) Model.getCoreFactory().buildClass( + policyName); + + aLog.debug("get stereotype"); + Stereotype secumlPolicy = getOrCreateStereotype(newPolicy, + SecureUmlConstants.STEREOTYPE_SECUML_POLICY, newPolicy.getNamespace()); + newPolicy.getStereotype().add(secumlPolicy); + newPolicy.setNamespace(namespace); + newPolicy.setActive(true); + + return newPolicy; + } + + public UmlClass createOclType(String name, Set superTypes) { + UmlClass newOcl = (UmlClass) Model.getCoreFactory().buildClass(name); + + + Namespace namespace = GenericDialectModelMapper.getInstance().getOclPackage(); + + newOcl.setNamespace(namespace); +// Stereotype oclType = getOrCreateStereotype(newOcl, SecureUmlConstants.STEREOTYPE_OCL_TYPE, namespace); +// newOcl.getStereotype().add(oclType); + + + if ( superTypes != null && superTypes.size() > 0 ) { + for ( UmlClass superType : superTypes ) { + Object asdf = Model.getCoreFactory().buildGeneralization(newOcl, superType, superType.getName() + "__" + name); + aLog.debug("build gen. " + asdf.getClass()); + } + } + + + return newOcl; + } + + public UmlClass createPolicy(String policyName, Set refined_by, Namespace namespace) { + +// if (refined_by == null || refined_by.size() == 0) { +// throw new InvalidParameterException( +// "refined_by may not be null or empty"); +// } +// aLog.debug("start ModelWriter.createPolicy"); +// PolicyWrapper asdf = refined_by.iterator().next(); +// aLog.debug("XXXX1: " + asdf ); +// Namespace namespace = ((UmlClass) modelmap.getUmlElement(asdf.getModelElement())).getNamespace(); +// aLog.debug("XXXX2"); + + UmlClass newPolicy = createPolicy(policyName, namespace); + + aLog.debug("buildGeneralizations"); + for (PolicyWrapper ref : refined_by) { + aLog.debug(ref.getName()); + UmlClass refinedBy_class = (UmlClass) modelmap.getUmlElement(ref + .getModelElement()); + Model.getCoreFactory().buildGeneralization(refinedBy_class, newPolicy); + } + + return newPolicy; + } + + /** + * @param permissionWrapper + */ + private void deletePermissionViaModelUml(PermissionWrapper permissionWrapper) { + try { + /* + * A SecureUmlPermission corresponds to an Attribute of an + * AssociationClass in the Uml Model + */ + RefObject permission = (RefObject) permissionWrapper + .getModelElement(); + + // logger.info("Deleting Permission " + permission); + Attribute permissionAttribute = (Attribute) modelmap + .getUmlElement(permission); + + AssociationClass permissionClass = (AssociationClass) permissionAttribute + .getOwner(); + // logger.log(logger.INFORMATIONAL, logger.MODELWRITER, + // "Deleting PermissionAttribute " + permissionAttribute); + // logger.log(logger.INFORMATIONAL, logger.MODELWRITER, + // corresponds to Permission: " + permissionClass + " )"); + /* + * delete the attribute (stated like this in the cookbook + */ + // String permissionName = + // permissionAttribute.getName().substring(0); + permissionAttribute.refDelete(); + + if (permissionClass.getFeature() == null + || permissionClass.getFeature().size() == 0) { + // logger.log(logger.INFORMATIONAL, logger.MODELWRITER, + // "would delete permission AssociationClass " + + // permissionClass); + permissionClass.refDelete(); + } + // logger.log(logger.INFORMATIONAL, logger.MODELWRITER, + // "Permission deleted: " + permissionName); + } catch (Exception e) { + logger.error(logger.MODELWRITER, "deleting Permission failed"); + logger.logException(e); + } + } + + public void deleteModelElement(Object modelElement) { + Project p = ProjectManager.getManager().getCurrentProject(); + p.moveToTrash(modelElement); + } + + public void setPermissionName(Object permission, String name) { + if (permission == null) { + logger.error(logger.MODELWRITER, "setPermissionName(): " + + "permission Argument must not be 'null'!"); + return; + } + try { + UmlAssociation permissionAssociation = (UmlAssociation) modelmap + .getUmlElement(permission); + + if (name == null || name.length() == 0) + logger.error(logger.MODELWRITER, "setPermissionName(): " + + " new Permission Name is null or empty " + + "-> leaving unchanged"); + else + permissionAssociation.setName(name); + + } catch (Exception e) { + logger.logException(e); + } + + } + + public void setAuthorizationConstraint(PermissionDummy permissionDummy, + String constraint) { + if (permissionDummy == null) { + logger.error(logger.MODELWRITER, "setAuthorizationConstraint(): " + + "permission Argument must not be 'null'!"); + return; + } + try { + AssociationClass permissionAssociation = (AssociationClass) modelmap + .getUmlElement(permissionDummy); + + if (constraint == null || constraint.length() == 0) { + // remove TaggedValue + Model + .getExtensionMechanismsHelper() + .removeTaggedValue( + permissionAssociation, + SecureUmlConstants.TAG_DEFINITION_AUTHORIZATION_CONSTRAINT); + } else { + // set Tagged Value + Model + .getCoreHelper() + .setTaggedValue( + permissionAssociation, + SecureUmlConstants.TAG_DEFINITION_AUTHORIZATION_CONSTRAINT, + constraint); + } + } catch (Exception e) { + logger.logException(e); + } + + } + + /* Util methods */ + public String getActionType(Object action) { + if (action != null) { + ActionType actionType = GenericDialectHelper.getInstance() + .getActionType(action); + + return actionType.getShortName(); + + } else { + return null; + } + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/PathNameResolver.java b/src/ch/ethz/infsec/secureumlgui/modelmapping/PathNameResolver.java new file mode 100644 index 0000000..5a317d2 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/PathNameResolver.java @@ -0,0 +1,129 @@ +package ch.ethz.infsec.secureumlgui.modelmapping; + +import java.util.Collection; + +import org.argouml.model.Model; +import org.omg.uml.foundation.core.Classifier; +import org.omg.uml.foundation.core.ModelElement; +import org.omg.uml.behavioralelements.statemachines.StateMachine; +import org.omg.uml.behavioralelements.statemachines.Transition; + +//import tudresden.ocl20.core.MetaModelConst.MetaModelInfo; + +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.DialectMetaModelInfo; + +@Deprecated +public class PathNameResolver { + + private static MultiContextLogger logger = new MultiContextLogger(); + + + + + /** + * Finds an element with the given name inside its containing + * object. + * + * @param elem + * @param name + * @return the found element + */ + @SuppressWarnings("unchecked") + private static ModelElement findInAnchor(ModelElement elem, String name) { + if (elem instanceof Classifier) { + Classifier anchor = (Classifier) elem; + // search attributes + + /* TODO: inserted manually 5 */ + Collection attributes = Model.getCoreHelper().getAllAttributes(anchor); + ModelElement result = find(attributes, name); + //ModelElement result = find(anchor.allAttributes(), name); + if (result != null) { + return result; + } + // search operations + /* TODO: inserted manually 6 */ + Collection operations = Model.getFacade().getOperations(anchor); + result = find(operations, name); + + //result = find(anchor.allOperations(), name); + + if (result != null) { + return result; + } + // search statemachine states and transitions + for (ModelElement ownedElem : (Collection) anchor + .getOwnedElement()) { + if (ownedElem instanceof StateMachine) { + StateMachine sm = (StateMachine) ownedElem; + for (Transition t : (Collection) sm + .getTransitions()) { + // search transitions + // transitions are addressed by their trigger (event) name + if (t.getTrigger() != null && t.getTrigger().getName().equals(name)) { + return t; + } + // search states + if (t.getSource() != null &&t.getSource().getName().equals(name)) { + return t.getSource(); + } + if (t.getTarget() != null && t.getTarget().getName().equals(name)) { + return t.getTarget(); + } + } + } + } + } else { + logger.error("unknown anchor type " + + elem.getClass().getSimpleName()); + } + return null; + } + + private static ModelElement find(Collection elems, String name) { + for (ModelElement elem : elems) { + if (elem.getName().equals(name)) { + return elem; + } + } + return null; + } + + /** + * Find a resource in a modelelement according to the given pathName. + * + * @param pathName + * @param anchor + * @return the found element + */ + @SuppressWarnings("unchecked") + public static ModelElement resolve(String pathName, ModelElement anchor) { + String[] components = pathName.split("\\."); + if (components.length == 0) { + logger.error("invalid path expression: " + pathName); + return null; + } + int pathOffset = 0; + if (components[pathOffset].equals(anchor.getName())) { + if (components.length == 1) { + // path name denotes the anchor, return it + return anchor; + } else { + // path name has an anchor prefix, skip it + pathOffset = 1; + } + } + ModelElement result = anchor; + // follow path to find resource + while (pathOffset < components.length) { + result = findInAnchor(result, components[pathOffset]); + pathOffset++; + } + if (result == null) { + logger.error("invalid path expression: " + pathName); + } + return result; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/SecureUmlModelMapper.java b/src/ch/ethz/infsec/secureumlgui/modelmapping/SecureUmlModelMapper.java new file mode 100644 index 0000000..d4cf8c5 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/SecureUmlModelMapper.java @@ -0,0 +1,606 @@ +package ch.ethz.infsec.secureumlgui.modelmapping; + +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import javax.jmi.reflect.RefObject; +import javax.jmi.reflect.RefPackage; + +//import org.argouml.ui.secureuml.modelmanagement.ModelConst; +import org.apache.log4j.Logger; +import org.omg.uml.foundation.core.AssociationEnd; +import org.omg.uml.foundation.core.Attribute; +import org.omg.uml.foundation.core.Classifier; +import org.omg.uml.foundation.core.Feature; +import org.omg.uml.foundation.core.Generalization; +import org.omg.uml.foundation.core.ModelElement; +import org.omg.uml.foundation.core.Stereotype; +import org.omg.uml.foundation.core.AssociationClass; +import org.omg.uml.foundation.core.TaggedValue; +import org.omg.uml.foundation.core.UmlClass; + +//import tudresden.ocl20.core.MetaModelConst; +import ch.ethz.infsec.secureumlgui.main.SecureUmlConstants; +import ch.ethz.infsec.secureumlgui.Util; +import ch.ethz.infsec.secureumlgui.modelmapping.counters.SecureUmlMappingCounter; +//import ch.ethz.infsec.secureumlgui.oclconstraintloader.ConstraintLoader; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.DialectMetaModelInfo; +import ch.ethz.infsec.secureumlgui.util.PermissionDummy; +import ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PermissionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PolicyWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.ResourceWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.RoleWrapper; + +import ch.ethz.infsec.secureumlgui.securemodelimpl.SecureModelFactory; + +/** + * Abstract class for mapping the SecureUML (non-dialect) elements. + * + * Subclasses will do the mapping for the dialect specific elements. + * + * @version 1.0 + */ +public abstract class SecureUmlModelMapper extends ModelMapper { + + private static final boolean verbose = true; + + @Deprecated + protected static final String STEREOTYPE_SECUML_ROLE = SecureUmlConstants.STEREOTYPE_SECUML_ROLE; + + @Deprecated + protected static final String STEREOTYPE_SECUML_PERMISSION = SecureUmlConstants.STEREOTYPE_SECUML_PERMISSION; + + private Collection permissionAnchors = new ArrayList(); + + // private ConstraintLoader constraintLoader; + + public DialectMetaModelInfo dialectMetaModelInfo; + + GenericDialectHelper helper = GenericDialectHelper.getInstance(); + + private SecureUmlMappingCounter counter = new SecureUmlMappingCounter(); + + + private static Logger aLog = Logger.getLogger(SecureUmlModelMapper.class); + + public SecureUmlModelMapper() { + logger.info("SecureUmlModelMapper"); + } + + public void init() { + super.init(); + + counter = new SecureUmlMappingCounter(); + + permissionAnchors.clear(); + } + + // public static String join(final Collection objs, final String + // delimiter) { + // + // return null; + // } + // + // public static void test() { + // Collection asdf = null; + // + // String result = join(asdf, ";"); + // } + + /* mapping of general uml elements (identification of stereotyped elements) */ + + @SuppressWarnings("unchecked") + public void transform() { + super.transform(); + logger.info(counter.toString()); + } + + public void examineUmlClass(UmlClass umlClass) { + if (isOfType(umlClass, SecureUmlConstants.STEREOTYPE_SECUML_ROLE)) { + transformRole(umlClass); + } else if (isOfType(umlClass, + SecureUmlConstants.STEREOTYPE_SECUML_POLICY)) { + transformPolicy(umlClass); + } + } + + protected void examineUmlGeneralization(Generalization generalization) { + if (isOfType(generalization.getChild(), + SecureUmlConstants.STEREOTYPE_SECUML_ROLE) + && isOfType(generalization.getParent(), + SecureUmlConstants.STEREOTYPE_SECUML_ROLE)) { + transformRoleInheritance(generalization); + } + } + + @SuppressWarnings("unchecked") + protected void examineAssociationClass(AssociationClass associationClass) { + if (isOfType(associationClass, + SecureUmlConstants.STEREOTYPE_SECUML_PERMISSION)) { + transformPermissionClass(associationClass); + } + } + + /* mapping of stereotyped elements */ + + @SuppressWarnings("unchecked") + protected void transformPermissionClass(AssociationClass associationClass) { + Classifier roleClassifier = null; + Classifier policyClassifier = null; + Classifier anchorClassifier = null; + + Object role = null; + Object policy = null; + Object anchor = null; + + // if (verbose) + // logger.info("-- permission: " + // + associationClass.getName()); + + // association ends => role and anchor + for (AssociationEnd end : associationClass.getConnection()) { + Classifier participant = end.getParticipant(); + if (isOfType(participant, SecureUmlConstants.STEREOTYPE_SECUML_ROLE)) { + roleClassifier = participant; + aLog.debug("found role " + roleClassifier); +// } else if (isOfType(participant, +// SecureUmlConstants.STEREOTYPE_SECUML_POLICY)) { +// policyClassifier = participant; +// aLog.debug("found policy " + policyClassifier); + } else if (!isOfType(participant, + SecureUmlConstants.STEREOTYPE_SECUML_PERMISSION)) { + anchorClassifier = participant; + aLog.debug("found anchor " + anchorClassifier); + } else { + aLog.debug("what did i find?" + participant); + } + } + + policyClassifier = GenericDialectModelMapper.getInstance().getPolicy(associationClass); + + + + + // fail if either role or anchor are missing + if (roleClassifier == null) { + logger.error("no role associated with permission " + + associationClass.getName()); + return; + } else { + role = map.getElement(roleClassifier); + aLog.debug("permission "+associationClass.getName()+ " associatied with Role "+role); + } + + if (policyClassifier == null) { + aLog.debug("no policyClassifier found for permission " + + associationClass.getName() ); +// policy = GenericDialectModelMapper.getInstance().getDefaultPolicy(); + } else { + + policy = map.getElement(policyClassifier); + aLog.debug("found policy for permission: " + policy); + } + + if (anchorClassifier == null) { + logger.error("no anchor associated with permission " + + associationClass.getName()); + return; + } else { + anchor = map.getElement(anchorClassifier); + // logger.info("permission "+associationClass.getName()+" + // associatied with Anchor "+anchor); + } + // logger.info("role: " + role + // + "anchor:" + anchor); + // if(role==null){logger.error("role not found while transforming + // permission "+associationClass.getName());} + // if(anchor==null){logger.error("anchor not found while transforming + // permission "+associationClass.getName());} + counter.incPermissionClassCount(); + // may happen if the anchor wasn't in the mapping scope: + if (anchor == null) + return; + // constraint => constraint for all permissions + String constraint = getAuthorizationConstraint(associationClass); + Object authorizationConstraint = null; + if (constraint != null && constraint.length() > 0) { + authorizationConstraint = SecureModelFactory.getInstance() + .createAuthorizationConstraint(constraint); + } + + PermissionDummy permissionDummy = new PermissionDummy(associationClass + .getName()); + + // RoleWrapper roleWrapper = new RoleWrapper(role); + // ResourceWrapper anchorWrapper = new ResourceWrapper(anchor); + + permissionDummy.setRole(role); + if (policy != null ) { + permissionDummy.setPolicy(policy); + } + permissionDummy.setAnchor(anchor); + permissionDummy.setAuthorizationConstraint(authorizationConstraint); + + map.put(associationClass, permissionDummy); + + // attributes => the permissions + //for (Object o : (List) associationClass.getFeature()) + for (Feature feature : associationClass.getFeature()) + // .allAttributes()) + { + if (feature instanceof Attribute) { + Attribute a = (Attribute) feature; + + transformPermission(associationClass.getName(), a, + anchorClassifier, roleClassifier, policyClassifier, + authorizationConstraint); + + Object permission = map.getElement(a); + + if (permission != null) { + PermissionWrapper pw = new PermissionWrapper(permission); + pw.setAuthorizationConstraint(authorizationConstraint); + + //PermissionWrapper permissionWrapper = new PermissionWrapper(permission); + //aLog.debug("permissionWrapper " + pw.getName() + " with policy: " + (pw.getPolicyWrapper() == null ? "NULL" : pw.getPolicyWrapper().getName())); + + permissionDummy.addPermissionWrapper(pw); + } + } + } + // map.addForDeletion(associationClass); + // map.printMap(); + } + + /** + * looks for the proper tagged value of the assocation class. + */ + private String getAuthorizationConstraint(AssociationClass associationClass) { + String constraint = ""; + Collection taggedValues = associationClass.getTaggedValue(); + if (taggedValues != null && taggedValues.size() > 0) { + for (Iterator iter = taggedValues.iterator(); iter.hasNext();) { + TaggedValue taggedValue = (TaggedValue) iter.next(); + + if (taggedValue != null && taggedValue.getDataValue() != null + && taggedValue.getDataValue().size() > 0) { + logger.info("### TaggedValue found( type: " + + taggedValue.getType().getName() + ", dataValue: " + + taggedValue.getDataValue().iterator().next()); + + if (taggedValue != null + && taggedValue.getType().getName() != null + && taggedValue + .getType() + .getName() + .equals( + SecureUmlConstants.TAG_DEFINITION_AUTHORIZATION_CONSTRAINT)) { + + constraint = taggedValue.getDataValue().iterator() + .next().toString(); + + } + } + } + } + return fixSpacing(constraint); + } + + /** + * replace " . " by "." + * + * @param constraint + * @return the transformed string + */ + private String fixSpacing(String constraint) { + if (constraint == null) { + return null; + } + return constraint.replaceAll("\\s\\.\\s", "\\."); + } + + @SuppressWarnings("unchecked") + protected void transformPermission(String permissionName, Attribute attr, + Classifier anchorClassifier, Classifier roleClassifier, Classifier policyClassifier, + Object constraint) { + // TODO: + + // find the resource by resolving the attribute name, which is the + // path name of the resource inside the anchor + ModelElement targetResource = + // PathNameResolver.resolve( + helper.resolvePath(attr.getName(), anchorClassifier); + + // String attributeName = a.getName(); + + // logger.info("transforming Permission on Resource '" + // + targetResourceName + // + "' for action'" + // + attributeType); + + if (targetResource != null && attr != null && attr.getType() != null) { + String attributeType = attr.getType().getName(); + String targetResourceName = targetResource.getName(); + // if (verbose) + // logger.info(" resource: " + targetResourceName + // + ", action: " + a.getType().getName()); + + // create the permission + // TODO: + // Permission suPermission = null; + // = target.getSecureUml().getPermission() + // .createPermission(permissionName); + // connect with role + + RefObject permission = SecureModelFactory + .getInstance() + .createPermission(attr.getName() + "_" + attr.getType().getName()); + + // logger.info("Permission "+ a.getName() + "_" + + // a.getType().getName() + " created"); + + + + // permission.setRole((Role) map.getElement(role)); + Util + .setProperty(permission, "role", map + .getElement(roleClassifier)); + + Util.setProperty(permission, "name", permissionName); + + Object suPolicy = map.getElement(policyClassifier); + + if ( suPolicy != null ) { + +// Util.setProperty(permission, "policy", suPolicy); +// aLog.debug("SET POLICY " + suPolicy + " to PERMISSION " + permission); + PermissionWrapper perm = new PermissionWrapper(permission); + + perm.setPolicy(suPolicy); + + + Set pol = perm.getPolicyWrappers(); + aLog.debug("check: " + (pol == null ? "NULL" : pol.size())); + } + + map.put(attr, permission); + + // instantiate the corresponding action + RefObject suTargetResource = (RefObject) map.getElement(targetResource); + + // ResourceWrapper rw = new ResourceWrapper(suTargetResource); + // rw.get + if (suTargetResource == null) + logger.error("suTargetResource = null, targetResource = " + + targetResource + " " + targetResourceName + + ", permission = " + permissionName); + + RefObject suAction = getOrCreateAction(suTargetResource, attr + .getType().getName()); + + // RefObject suAction = + // ActionInstantiator.initializeAction(a.getType().getName(), + // suAction, + // suTargetResource); + + if (suAction == null) { + logger.error("instantiation of action " + attr.getType().getName() + + " failed"); + return; + } + + ActionWrapper aw = ActionWrapper.createActionWrapper(suAction); + aw.addPermission(permission); + + Object suRole = map.getElement(roleClassifier); + RoleWrapper roleWrapper = new RoleWrapper(suRole); + + roleWrapper.addPermission(permission); + + PermissionWrapper permissionwrapper = new PermissionWrapper( + permission); + permissionwrapper.setRole(suRole); + permissionwrapper.setAction(suAction); + if ( suPolicy != null ) { + aLog.debug("set policy for permission " + permissionwrapper.getName() + " policy " + suPolicy + " " + new PermissionWrapper(suPolicy).getName()); + permissionwrapper.setPolicy(suPolicy); + } + + ResourceWrapper resourceWrapper = new ResourceWrapper( + suTargetResource); + resourceWrapper.getAction().add(suAction); + + //PolicyWrapper policy = new PolicyWrapper(suPolicy); + //policy. + + + + + + + + + // logger.info("Transformed Permission for Role: " + // + roleWrapper.getName() + // + ", permission: " + // + permissionwrapper.getName() + // + " on Action: " + // + permissionwrapper.getActionWrapper().getName()); + + // TODO: connect the permission with the action + // permission.getAction().add(suAction); + + // Util.setProperty(permission, "action", suAction); + + // connect the Action with the Resource + + if (constraint != null) { + Util.setProperty(permission, "authorizationConstraint", + constraint); + + Util.setProperty(constraint, "permission", permission); + + } + + permissionAnchors.add(anchorClassifier); + counter.incPermissionCount(); + } else { + logger.error("target resource not found"); + } + } + + /** creates a SecureUML role with the name of the UML class */ + protected void transformRole(Classifier roleClass) { + if (map.mapContainsKey(roleClass)) + return; + + // if (verbose) + // logger.info("-- role: " + roleClass.getName()); + // RefObject role = createRole(roleClass.getName()); + + RefObject role = SecureModelFactory.getInstance().createRole( + roleClass.getName()); + + // TODO + // target.getSecureUml().getRole().createRole(); + + // role.setName(roleClass.getName()); + + String propertyName = "name"; + + Util.setProperty(role, propertyName, roleClass.getName()); + + map.put(roleClass, role); + // map.addForDeletion(roleClass); + counter.incRoleCount(); + } + + protected void transformPolicy(Classifier policyClass) { + if (map.mapContainsKey(policyClass)) { + return; + } + + RefObject policy = SecureModelFactory.getInstance().createPolicy(policyClass.getName()); + + //redundant? + Util.setProperty(policy, "name", policyClass.getName()); + + map.put(policyClass, policy); + + counter.incPolicyCount(); + } + + @SuppressWarnings("unchecked") + protected void transformRoleInheritance(Generalization generalization) { + if (map.mapContainsKey(generalization)) + return; + + Object child = /* (Role) */map.getElement(generalization.getChild()); + Object parent = /* (Role) */map.getElement(generalization.getParent()); + + if (child != null && parent != null) { + // if (verbose) + // logger.info("-- role inheritance: " + Util.getProperty(parent, + // "name") + "-" + // + Util.getProperty(child, "name")); + + // child.getSuperroles().add(parent); + Util.setProperty(child, "superroles", parent); + + // parent.getSubroles().add(child); + Util.setProperty(parent, "subroles", child); + + counter.incRoleInheritance(); + } + } + + protected void transformPolicyInheritance(Generalization generalization) { + if (map.mapContainsKey(generalization)) { + return; + } + + Object child = /* (Policy) */ map.getElement(generalization.getChild()); + Object parent = /* (Policy) */map.getElement(generalization.getParent()); + + if ( child != null && parent != null ) { + +// Method[] methods = child.getClass().getMethods(); +// for (Method method : methods) { +// System.out.print(method.getReturnType() + " " + method.getName() + "("); +// for ( Class paramType : method.getParameterTypes() ) { +// System.out.print(paramType + ","); +// } +// System.out.println(")"); +// } + + Util.setProperty(child, SecureUmlConstants.POLICY_INHERITANCE_REFINEDBY, parent); + Util.setProperty(parent, SecureUmlConstants.POLICY_INHERITANCE_REFINES, child); + + counter.incPolicyInheritanceCount(); + } + } + + /* utility methods */ + + protected boolean isOfType(ModelElement element, String stereotype) { + if (element == null || stereotype == null) + return false; + + Collection stereotypes = element.getStereotype(); + int nofStereotypes = stereotypes.size(); + + if (stereotypes == null || stereotypes.size() == 0) + return false; + + for (Iterator it = stereotypes.iterator(); it.hasNext();) { + Stereotype s = (Stereotype) it.next(); + if (s.getName().equals(stereotype)) { + return true; + } + } + return false; + } + + protected boolean isOfType(Collection elements, + String stereotype) { + for (ModelElement elem : elements) { + if (!isOfType(elem, stereotype)) { + return false; + } + } + return true; + } + + protected boolean endsAreOfTypes(List e, String s1, + String s2) { + if (e.size() != 2) { + logger.warning("expecting 2 collection elements"); + return false; + } else { + return ((isOfType(e.get(0).getParticipant(), s1) && isOfType(e.get( + 1).getParticipant(), s2)) || (isOfType(e.get(0) + .getParticipant(), s2) && isOfType(e.get(1) + .getParticipant(), s1))); + } + } + + // abstract public RefObject createRole(String name); + + // abstract public RefObject createPermission(String name); + + // abstract public RefObject createAuthorizationConstraint(String + // constraint); + + abstract public RefObject getOrCreateAction(RefObject resource, + String shortActionName); + + public Collection getPermissionAnchors() { + return permissionAnchors; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/counters/Counter.java b/src/ch/ethz/infsec/secureumlgui/modelmapping/counters/Counter.java new file mode 100644 index 0000000..ab1a85c --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/counters/Counter.java @@ -0,0 +1,13 @@ +package ch.ethz.infsec.secureumlgui.modelmapping.counters; + +public class Counter { + + protected String sinPlur(int number, String singular, String plural) { + if (number == 1) { + return singular; + } else { + return plural; + } + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/counters/SecureUmlMappingCounter.java b/src/ch/ethz/infsec/secureumlgui/modelmapping/counters/SecureUmlMappingCounter.java new file mode 100644 index 0000000..970d763 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/counters/SecureUmlMappingCounter.java @@ -0,0 +1,82 @@ +package ch.ethz.infsec.secureumlgui.modelmapping.counters; + +public class SecureUmlMappingCounter extends Counter { + + private int permissionCount = 0; + + private int permissionClassCount = 0; + + private int roleCount = 0; + + private int roleInheritanceCount = 0; + + private int policyCount = 0; + + private int policyInheritanceCount = 0; + + public int getPermissionClassCount() { + return permissionClassCount; + } + + public void incPermissionClassCount() { + this.permissionClassCount++; + } + + public int getPermissionCount() { + return permissionCount; + } + + public void incPermissionCount() { + this.permissionCount++; + } + + public int getRoleCount() { + return roleCount; + } + + public void incRoleCount() { + this.roleCount++; + } + + public int getRoleInheritanceCount() { + return roleInheritanceCount; + } + + public void incRoleInheritance() { + roleInheritanceCount++; + } + + public int getPolicyCount() { + return policyCount; + } + + public void incPolicyCount() { + this.policyCount++; + } + + public int getPolicyInheritanceCount() { + return policyInheritanceCount; + } + + public void incPolicyInheritanceCount() { + this.policyInheritanceCount++; + } + + public String toString() { + StringBuffer buf = new StringBuffer(); + buf.append(" SecureUML\n"); + buf.append(" " + getRoleCount() + " role class" + + sinPlur(getRoleCount(), "", "es") + "\n"); + buf.append(" " + getRoleInheritanceCount() + + " role inheritance relation" + + sinPlur(getRoleInheritanceCount(), "", "s") + "\n"); + buf.append(" " + getPermissionClassCount() + " permission class" + + sinPlur(getPermissionClassCount(), "", "es") + "\n"); + buf.append(" " + getPermissionCount() + " permission" + + sinPlur(getPermissionCount(), "", "s") + "\n"); + return buf.toString(); + } + + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/package.html b/src/ch/ethz/infsec/secureumlgui/modelmapping/package.html new file mode 100644 index 0000000..b42fee8 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/package.html @@ -0,0 +1,9 @@ + + + + + +Calculating the correspondence between SecureUML (dialect) elements +and their UML counterparts. + + diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/ActionPermissionSet.java b/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/ActionPermissionSet.java new file mode 100644 index 0000000..d447778 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/ActionPermissionSet.java @@ -0,0 +1,165 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.modelmapping.permissions; + +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; + +import org.apache.log4j.Logger; + +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.HierarchicalPermissionsExplorer.CHANGES; +import ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PermissionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PolicyWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.RoleWrapper; + + +/** + * the set of permissions for role {@link #explicitRoleWrapper} on + * action {@link #explicitActionWrapper}. + * + */ +public class ActionPermissionSet +{ + Map permissions = new HashMap(); + + private PolicyPermissionSet defaultPermissions; + + + private static Logger aLog = Logger.getLogger(ActionPermissionSet.class); + private boolean inserted_default = false; //Very, very bad hack.. + + + public ActionPermissionSet() { + + PolicyWrapper defaultPolicy = HierarchicalPolicyExplorer.getInstance().getDefaultPolicyWrapper(); + + defaultPermissions = new PolicyPermissionSet(defaultPolicy); + + if ( defaultPolicy != null ) { + permissions.put(defaultPolicy.getModelElement(), defaultPermissions); + inserted_default = true; + } + } + + + public void addExplicitDefaultPermission(PermissionValue permissionValue) { + defaultPermissions.addExplicitPermission(permissionValue); + } + + public void addExplicitPermission(PolicyWrapper policy, PermissionValue permissionValue) { + getPolicyPermissionSet(policy).addExplicitPermission(permissionValue); + } + + public void addDefaultPermission(PermissionValue permissionValue, CHANGES changeReason) { + + defaultPermissions.addPermission(permissionValue, changeReason); + } + + + public void addPermission(PolicyWrapper policy, PermissionValue permissionValue, CHANGES changeReason) { + + //aLog.debug("addPermission to policy " +( policy == null ? "NULL" : policy.getName()+ "_" + policy.getModelElement()) + "(" + permissions.size() + ")" ); + + getPolicyPermissionSet(policy).addPermission(permissionValue, changeReason); + } + + + public PolicyPermissionSet getDefaultPolicyPermissionSet() { + return defaultPermissions; + } + + public PolicyPermissionSet getPolicyPermissionSet(PolicyWrapper policy) { + + if ( policy == null ) { + return getDefaultPolicyPermissionSet(); + } + + if ( ! inserted_default ) { + PolicyWrapper defaultPolicy = HierarchicalPolicyExplorer.getInstance().getDefaultPolicyWrapper(); + if ( defaultPolicy != null ) { + permissions.put(defaultPolicy.getModelElement(), defaultPermissions); + inserted_default = true; + } + } + + + if ( permissions.containsKey(policy.getModelElement())) { + return permissions.get(policy.getModelElement()); + } else { + PolicyPermissionSet policyPermissionSet = new PolicyPermissionSet(policy); + permissions.put(policy.getModelElement(), policyPermissionSet); + return policyPermissionSet; + } + } + + + public Collection getPermissions(PolicyWrapper policy) { + + //aLog.debug("getPermissions of policy " +( policy == null ? "NULL" : policy.getName()+ "_" + policy.getModelElement()) + "(" + permissions.size() + ")" ); + + + return getPolicyPermissionSet(policy).getPermissions(); + } + + + + private RoleWrapper explicitRoleWrapper; + private ActionWrapper explicitActionWrapper; + + + public RoleWrapper getExplicitRoleWrapper() + { + return explicitRoleWrapper; + } + + public void setExplicitRoleWrapper(RoleWrapper explicitRoleWrapper) + { + this.explicitRoleWrapper = explicitRoleWrapper; + } + + + + public ActionWrapper getExplicitActionWrapper() + { + return explicitActionWrapper; + } + + public void setExplicitActionWrapper(ActionWrapper explicitActionWrapper) + { + this.explicitActionWrapper = explicitActionWrapper; + } + + public boolean isExplicitPermitted(PolicyWrapper policy) { + return getPolicyPermissionSet(policy).isExplicitPermitted(); + } + + public PermissionWrapper getExplicitPermittedPermission(PolicyWrapper policy) { + return getPolicyPermissionSet(policy).getExplicitPermittedPermission(); + } + + +// public boolean isPermitted() { +// for (PermissionValue permission : permissions ) { +// if ( ! permission.isConstrained()) { +// return true; +// } +// } +// return false; +// } +// +// public boolean isConstrainedPermitted() { +// if (permissions.size() > 0 ) +// return true; +// else +// return false; +// +// } + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/CompositePermission.java b/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/CompositePermission.java new file mode 100644 index 0000000..6b24762 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/CompositePermission.java @@ -0,0 +1,137 @@ +package ch.ethz.infsec.secureumlgui.modelmapping.permissions; + +import java.util.Collection; +import java.util.List; + +import javax.jmi.reflect.RefClass; +import javax.jmi.reflect.RefException; +import javax.jmi.reflect.RefFeatured; +import javax.jmi.reflect.RefObject; +import javax.jmi.reflect.RefPackage; + +import ch.ethz.infsec.secureumlgui.securemodel.secureuml.AuthorizationConstraint; +import ch.ethz.infsec.secureumlgui.securemodel.secureuml.Permission; +import ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role; + +public class CompositePermission implements Permission { + + //public CompositePermission(String name, + + public Collection getAction() { + // TODO Auto-generated method stub + return null; + } + + public AuthorizationConstraint getAuthorizationConstraint() { + // TODO Auto-generated method stub + return null; + } + + public String getName() { + // TODO Auto-generated method stub + return null; + } + + public Role getRole() { + // TODO Auto-generated method stub + return null; + } + + public void setAuthorizationConstraint(AuthorizationConstraint newValue) { + // TODO Auto-generated method stub + + } + + public void setName(String newValue) { + // TODO Auto-generated method stub + + } + + public void setRole(Role newValue) { + // TODO Auto-generated method stub + + } + + public RefClass refClass() { + // TODO Auto-generated method stub + return null; + } + + public void refDelete() { + // TODO Auto-generated method stub + + } + + public RefFeatured refImmediateComposite() { + // TODO Auto-generated method stub + return null; + } + + public boolean refIsInstanceOf(RefObject arg0, boolean arg1) { + // TODO Auto-generated method stub + return false; + } + + public RefFeatured refOutermostComposite() { + // TODO Auto-generated method stub + return null; + } + + public Object refGetValue(RefObject arg0) { + // TODO Auto-generated method stub + return null; + } + + public Object refGetValue(String arg0) { + // TODO Auto-generated method stub + return null; + } + + public Object refInvokeOperation(RefObject arg0, List arg1) + throws RefException { + // TODO Auto-generated method stub + return null; + } + + public Object refInvokeOperation(String arg0, List arg1) + throws RefException { + // TODO Auto-generated method stub + return null; + } + + public void refSetValue(RefObject arg0, Object arg1) { + // TODO Auto-generated method stub + + } + + public void refSetValue(String arg0, Object arg1) { + // TODO Auto-generated method stub + + } + + public RefPackage refImmediatePackage() { + // TODO Auto-generated method stub + return null; + } + + public RefObject refMetaObject() { + // TODO Auto-generated method stub + return null; + } + + public String refMofId() { + // TODO Auto-generated method stub + return null; + } + + public RefPackage refOutermostPackage() { + // TODO Auto-generated method stub + return null; + } + + public Collection refVerifyConstraints(boolean arg0) { + // TODO Auto-generated method stub + return null; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/HierarchicalPermissionsExplorer.java b/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/HierarchicalPermissionsExplorer.java new file mode 100644 index 0000000..fc2d80c --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/HierarchicalPermissionsExplorer.java @@ -0,0 +1,481 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.modelmapping.permissions; + +import java.util.Collection; +import java.util.Date; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.omg.uml.UmlPackage; +import org.omg.uml.foundation.core.UmlClass; + +import ch.ethz.infsec.secureumlgui.ModuleController; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PermissionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PolicyWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.ResourceWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.RoleWrapper; + +/** + * Explore the permission hierarchy generated by role inheritance and + * action composition. + * + */ +public class HierarchicalPermissionsExplorer +{ + MultiContextLogger logger = MultiContextLogger.getDefault(); + + private static Logger aLog = Logger.getLogger(HierarchicalPermissionsExplorer.class); + + private static HierarchicalPolicyExplorer policyExplorer = HierarchicalPolicyExplorer.getInstance(); + + public enum CHANGES { + EXPLICIT, INHERITED, IMPLICIT_SUB, IMPLICIT_SUPER, INHERITED_POLIY + } + + public void collectNonExplicitPermissions(ResourceWrapper resource, PermissionSet permissions) { + + aLog.debug("collectNonExplicitPermissions: (roles: " + permissions.getAllRoleWrappers().size() + ")"); + + Date start = new Date(); + + //List policies = policyExplorer.getSortedPolicies(); + List policies = policyExplorer.getSortedPolicies(); +// PolicyWrapper defaultPolicy = HierarchicalPolicyExplorer.getInstance().getDefaultPolicy(); +// +// if ( defaultPolicy == null ) { +// policies.add(0, defaultPolicy); +// } + + for ( UmlClass policyClass : policies) { + + PolicyWrapper policy = new PolicyWrapper(ModuleController.getInstance().getModelMap().getElement(policyClass)); + + aLog.debug("collecting directly policy-inherited permissions for resruce " + resource + " and policy: " + policy.getName()); + collectPolicyInheritedPermissions(resource, permissions, policy); + + aLog.debug("collecting directly implicit, from explicit, permissions for resource " + resource + " and policy: " + policy.getName()); + //collect implicit permissions, without taking into account dependencies between implicit and inheritied + collectImplicitPermissions(resource, permissions, policy); + + aLog.debug("colling directly inherited, from explicit, permissions for resource " + resource + " and policy: " + policy.getName()); + collectInheritedPermissions(resource, permissions, policy); + + aLog.debug("collection directly permission END"); + // + PermissionSet next, last; + + //create an empty next set + next = new PermissionSet(); + //for the first run, iterate over all permissions + aLog.debug("collecting indirect implicit permissions, iterating over all permissions"); + collectImplicitPermissions(policy, resource, permissions, permissions, next); + + while (true) { + last = next; + next = new PermissionSet(); + if ( last.getAllRoleWrappers().size() == 0 ) { //nothing changed, finished + aLog.debug("recursion did not find any further permissions by collecting implicit permissions... DONE!"); + break; + } else { + if ( aLog.isDebugEnabled() ) { + aLog.debug("starting with search of indirectly inherited permissions, number of roles: " + next.getAllRoleWrappers().size()); + } + collectInheritedPermissions(policy, resource, last, permissions, next ); + } + + last = next; + next = new PermissionSet(); + if ( last.getAllRoleWrappers().size() == 0 ) { //nothing changed, finished + aLog.debug("recursion did not find any further permissions by collecting inherited permissions... DONE!"); + break; + } else { + if ( aLog.isDebugEnabled() ) { + aLog.debug("starting with search of indirectly implicit permissions, number of roles: " + next.getAllRoleWrappers().size()); + } + collectImplicitPermissions(policy, resource, last, permissions, next ); + } + } + + } + + long duration = new Date().getTime() - start.getTime(); + aLog.debug("needed: " + duration); + } + + private void collectPolicyInheritedPermissions(ResourceWrapper resource, PermissionSet permissions, PolicyWrapper policy) { + aLog.debug("collectPolicyInheritedPermissions for policy (" + policy.getName() + ") START"); + + Collection refinedBy = policy.getRefinedBy(); + if ( refinedBy != null && refinedBy.size() > 0 ) { + for ( PolicyWrapper supPol : policy.getRefinedByWrappers() ) { + aLog.debug("start with policy " + supPol.getName()); + + for ( RoleWrapper role : permissions.getAllRoleWrappers() ) { + + ResourcePermissionsSet resourcePermissions = permissions.getResourcePermissionsSet(role); + + for (ActionWrapper action : resource.getActionWrapper()) { + ActionPermissionSet actionPermissions = resourcePermissions.getPermissions(action); + + for (PermissionValue permission : actionPermissions.getPermissions(supPol)) { + actionPermissions.addPermission(policy, PermissionValue.createInheritedPolicy(permission), CHANGES.INHERITED_POLIY); + } + } + } + aLog.debug("end with policy " + supPol.getName()); + } + } + + + aLog.debug("collectPolicyInheritedPermissions END"); + } + + /** + * collects all permissions, which are DIRECTLY IMPLICIT from the explicit permissions + * @param resource + * @param permissions + */ + private void collectImplicitPermissions(ResourceWrapper resource, PermissionSet permissions, PolicyWrapper policy) { + aLog.debug("collectImplicitPermissions START"); + //PermissionSet superactionResourcePermissions = getExplicitPermissions(resource); + // for a fixed resource, iterate over ALL roles + for (RoleWrapper role : permissions.getAllRoleWrappers()) { + aLog.debug(" role: " + role.getName()); + ResourcePermissionsSet resourcePermissions = permissions.getResourcePermissionsSet(role); + //iterate over all actions of the fixed resource and get the permissions assigned to this action and role, saved in actionPermissions + for (ActionWrapper action : resource.getActionWrapper()) { + aLog.debug(" action: " + action.getName()); + ActionPermissionSet actionPermissions = resourcePermissions.getPermissions(action); + //iterate over all super actions (i.e., all composite actions of which this action is part of), => implicit permission from SUPER actions + for ( ActionWrapper superAction : getSuperActionWrappersDeep(action) ) { + //and get all explicit permissions assigned to this resource (any role and action?) + + Collection superActionPermissions = + permissions.getResourcePermissionsSet(role).getPermissions(superAction).getPermissions(policy); +// Collection superActionPermissions = +// superactionResourcePermissions.getResourcePermissionsSet(role).getPermissions(superAction).getPermissions(policy); +// if ( aLog.isDebugEnabled() ) { +// aLog.debug(" superAction: " + superAction.getName() + " with " + superActionPermissions.size() + " permissions"); +// } + for (PermissionValue permission : superActionPermissions) { + actionPermissions.addPermission(policy, PermissionValue.createImplicite(permission), CHANGES.IMPLICIT_SUPER); + } + } + + //implicit permissions from SUB actions + if ( action.hasSubActions() && isPermittedImplicitBySubactions ( permissions, role, action, policy ) ) { + + aLog.debug("IMPLICIT BY SUBACTION: " + role.getName() + " on " + action.getName()); + + PermissionValue composite = PermissionValue.createComposite(null, action, role); + + actionPermissions.addPermission(policy, composite, CHANGES.IMPLICIT_SUB); + } + } + } + aLog.debug("collectImplicitPermissions END"); + } + + /** + * collects all permissions, which are DIRECTLY INHERITED from explicit permissions + * @param resource + * @param permissions + */ + private void collectInheritedPermissions(ResourceWrapper resource, PermissionSet permissions, PolicyWrapper policy) { + aLog.debug("collectInheritedPermissions START"); + // for a fixed resource, iterate over ALL roles + for (RoleWrapper role : permissions.getAllRoleWrappers()) { + aLog.debug(" role: " + role.getName()); + ResourcePermissionsSet resourcePermissions = permissions.getResourcePermissionsSet(role); + // get super Roles for this role + Set superRoles = getSuperRoleWrappersDeep(role); + //iterate over all actions of the fixed resources and get the permissions assigned to this action and role, saved in actionPermissions + for (ActionWrapper action : resource.getActionWrapper()) { + aLog.debug(" action: " + action.getName()); + ActionPermissionSet actionPermissions = resourcePermissions.getPermissions(action); + //iterate over all super Roles for the current role + for (RoleWrapper superRole : superRoles ) { + Collection superRolePermissions = + permissions.getResourcePermissionsSet(superRole).getPermissions(action).getPermissions(policy); +// if ( aLog.isDebugEnabled() ) { +// aLog.debug(" superRole: " + superRole.getName() + " with " + superRolePermissions.size() + " permissions"); +// } + aLog.debug("for superrole " + superRole.getName() + " found " + superRolePermissions.size() + " permissions"); + //iterate over all permissions, the superrole has and assign as inherited to current role + for (PermissionValue permission : superRolePermissions) { + permission = PermissionValue.createInheritedRole(permission); + //use permission of super role to create an inherited permission for current role + actionPermissions.addPermission(policy, permission, CHANGES.INHERITED); + } + } + } + } + aLog.debug("collectInheritedPermissions END"); + } + + /** + * collects all permissions, which are INDIRECT IMPLICIT + * @param resource + * @param permissions_last contains the elements which have changed in the last round, i.e., where it is required to look at a second time + * @param permissions_dst contains ALL the permissions which have been calculated so far (i.e., which are the end result and are required to come to a decision if something is permitted or not) + * @param permissions_next in this, the information are stored, which element have to be treated in the next round + */ + private void collectImplicitPermissions(PolicyWrapper policy, ResourceWrapper resource, PermissionSet permissions_last, + PermissionSet permissions_dst, PermissionSet permissions_next) { + aLog.debug("collectImplicitPermissions INDIRECT START"); + for (RoleWrapper role : permissions_last.getAllRoleWrappers()) { + aLog.debug(" role: " + role.getName()); + ResourcePermissionsSet resourcePermissions = permissions_last.getResourcePermissionsSet(role); + + for (Object action : resourcePermissions.getActions()) { + ActionWrapper actionWrapper = ActionWrapper.createActionWrapper(action); + aLog.debug(" action: " + actionWrapper.getName()); + ActionPermissionSet actionPermissions = permissions_dst.getResourcePermissionsSet(role).getPermissions(actionWrapper); + + for ( ActionWrapper superAction : getSuperActionWrappersDeep(actionWrapper) ) { + + Collection superActionPermissions = permissions_dst.getResourcePermissionsSet(role).getPermissions(superAction).getPermissions(policy); +// if ( aLog.isDebugEnabled() ) { +// aLog.debug(" superAction: " + superAction.getName() + " with " + superActionPermissions.size() + " permissions"); +// } + + for (PermissionValue permission : superActionPermissions) { + //permission = PermissionValue.create(PermissionValue.IMPLICIT, permission.getPermissionWrapper()); //TODO add info about etc + permission = PermissionValue.createImplicite(permission); + + actionPermissions.getPolicyPermissionSet(policy).addPermission(permission, permissions_next, CHANGES.IMPLICIT_SUPER, superAction, role); + } + } + + //implicit permissions from SUB actions + if ( actionWrapper.hasSubActions() && isPermittedImplicitBySubactions ( permissions_dst, role, actionWrapper, policy ) ) { + aLog.debug("IMPLICIT BY SUBACTION: " + role.getName() + " on " + actionWrapper.getName()); + + PermissionValue composite = PermissionValue.createComposite(null, actionWrapper, role); + //TODO is there a problem caused throw actionWrapper received from permissions_last? + + actionPermissions.getPolicyPermissionSet(policy).addPermission(composite, permissions_next, CHANGES.IMPLICIT_SUB, actionWrapper, role); + } + } + } + aLog.debug("collectImplicitPermissions INDIRECT END"); + } + + /** + * collects all permissions, which are INDIRECT INHERITED + * @param resource + * @param permissions_last + * @param permissions_dst + * @param permissions_next + */ + private void collectInheritedPermissions(PolicyWrapper policy, ResourceWrapper resource, PermissionSet permissions_last, + PermissionSet permissions_dst, PermissionSet permissions_next) { + aLog.debug("collectInheritedPermissions INDIRECT START"); + for (RoleWrapper role : permissions_last.getAllRoleWrappers()) { + ResourcePermissionsSet resourcePermissions = permissions_last.getResourcePermissionsSet(role); + aLog.debug(" role: " + role.getName()); + + for (Object action : resourcePermissions.getActions()) { + ActionWrapper actionWrapper = ActionWrapper.createActionWrapper(action); + aLog.debug(" action: " + actionWrapper.getName()); + ActionPermissionSet actionPermissions = permissions_dst.getResourcePermissionsSet(role).getPermissions(actionWrapper); + + for (RoleWrapper superRole : getSuperRoleWrappersDeep(role)) { + Collection superRolePermissions = permissions_dst.getResourcePermissionsSet(superRole).getPermissions(action).getPermissions(policy); + if ( aLog.isDebugEnabled() ) { + aLog.debug(" superRole: " + superRole.getName() + " with " + superRolePermissions.size() + " permissions"); + } + + for (PermissionValue permission : superRolePermissions) { + permission = PermissionValue.createInheritedRole(permission); + //use permission of super role to create an inherited permission for current role + actionPermissions.getPolicyPermissionSet(policy).addPermission(permission, permissions_next, CHANGES.INHERITED, actionWrapper, role); + } + } + } + } + aLog.debug("collectInheritedPermissions INDIRECT END"); + } + + +// public PermissionSet getExplicitPermission(ResourceWrapper resource, PolicyWrapper policy) { +// return null; +// } + + + + + public PermissionSet getExplicitPermissions(ResourceWrapper resource) + { + PermissionSet result = new PermissionSet(); + + PolicyWrapper defaultPolicy = HierarchicalPolicyExplorer.getInstance().getDefaultPolicyWrapper(); + + for (ActionWrapper action : resource.getActionWrapper()) { + for ( PermissionWrapper permission : action.getPermissionWrappers()) { + RoleWrapper role = permission.getRoleWrapper(); + + if(role != null) { + + PolicyWrapper policy = null; + + Set policies = permission.getPolicyWrappers(); + + if (policies != null || policies.size() > 0) { + policy = policies.iterator().next(); + + if (policies.size() > 1 ) { + aLog.error("ignoring all policies except first one.. TODO"); + } + + } + + + + if ( policy == null ) { + policy = defaultPolicy; + } + + result.getResourcePermissionsSet(role).addPermission(action, PermissionValue.createGranted(permission), policy); + + try { + aLog.debug("H: add explicit permission: " + role.getName() + " on " + action.getName() + " on policy " + (policy == null ? "NULL" : policy.getName() + "_" + policy.getModelElement())); + } catch (Exception e) { + aLog.debug("error at creating log mesasge: " + e.getClass() + "; " + e.getMessage()); + } + + + ResourcePermissionsSet rps = result.getResourcePermissionsSet( + new RoleWrapper(role.getModelElement())); + + ActionPermissionSet aps = rps.getPermissions(action.getName()); + + aps.setExplicitRoleWrapper(role); + } + } + } + return result; + } + + /** gets all direct and indirect superroles + * + * @param roleWrapper + * @return the set of superroles + */ + public Set getSuperRoleWrappersDeep(RoleWrapper roleWrapper) { + Set result = new LinkedHashSet(); + + collectSuperroles(roleWrapper, result); + + aLog.debug("for role " + roleWrapper.getName() + " found " + result.size() + " superroles"); + return result; + } + + private static void collectSuperroles(RoleWrapper role, Set roles) { + if(roles != null && role.getSuperroles() != null) { + for ( RoleWrapper superRole : role.getSuperrolesWrappers() ) { + roles.add(superRole); + + // recursion + collectSuperroles(superRole, roles); + } + } + } + + public static Set getSubRoleWrapperDeep(RoleWrapper roleWrapper) { + Set result = new LinkedHashSet(); + + collectSubRoles(roleWrapper, result); + + return result; + } + + private static void collectSubRoles(RoleWrapper role, Set roles) { + if (roles != null && role.getSubroles() != null ) { + for ( RoleWrapper subRole : role.getSubrolesWrappers() ) { + roles.add(subRole); + + collectSubRoles(subRole, roles); + } + } + + } + + /** gets all direct and indirect superactions + * + * @param action + * @return the set of superactions. + */ + public static Set getSuperActionWrappersDeep(ActionWrapper action) { + Set result = new LinkedHashSet(); + + collectSuperActions(action, result); + + return result; + } + + public static Set getSubActionWrappersDeep(ActionWrapper action) { + Set result = new LinkedHashSet(); + + collectSubActions(action, result); + + return result; + + } + + public static Set getSubAndSuperActionWrappersDeep(ActionWrapper action) { + + Set result = getSuperActionWrappersDeep(action); + collectSubActions(action, result); + + return result; + } + + private static void collectSuperActions(ActionWrapper action, Set result) { + if(action.getSuperActions() != null) { + for ( ActionWrapper superAction : action.getSuperActionWrappers()) { + result.add(superAction); + + collectSuperActions(superAction, result); + } + } + } + + private static void collectSubActions(ActionWrapper action, Set result) { + if ( action .getSubActions() != null ) { + for ( ActionWrapper superAction : action.getSubActionWrappers()) { + result.add(superAction); + + collectSubActions(superAction, result); + } + } + } + + + private boolean isPermittedImplicitBySubactions(PermissionSet permissions, RoleWrapper role, ActionWrapper action, PolicyWrapper policy) { + //check if explicit permitted + if ( permissions.getResourcePermissionsSet(role).getPermissions(action).getPolicyPermissionSet(policy).isPermitted()) { + return true; + } + else { //check, if implicit permitted by all permitted subactions + Set subActions = action.getSubActionWrappers(); + if ( subActions != null && subActions.size() > 0 ) { + for (ActionWrapper subAction : action.getSubActionWrappers()) { + if ( ! isPermittedImplicitBySubactions(permissions, role, subAction, policy) ) { + return false; + } + } + return true; + } + else { + return false; + } + } + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/HierarchicalPolicyExplorer.java b/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/HierarchicalPolicyExplorer.java new file mode 100644 index 0000000..54a2145 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/HierarchicalPolicyExplorer.java @@ -0,0 +1,328 @@ +package ch.ethz.infsec.secureumlgui.modelmapping.permissions; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.omg.uml.foundation.core.Namespace; +import org.omg.uml.foundation.core.UmlClass; + +import ch.ethz.infsec.secureumlgui.ModuleController; +import ch.ethz.infsec.secureumlgui.main.SecureUmlConstants; +import ch.ethz.infsec.secureumlgui.modelmapping.GenericDialectModelMapper; +import ch.ethz.infsec.secureumlgui.transformation.ModelMap; +import ch.ethz.infsec.secureumlgui.wrapper.PolicyWrapper; + +public class HierarchicalPolicyExplorer { + + private static Logger aLog = Logger.getLogger(HierarchicalPolicyExplorer.class); + + + private static HierarchicalPolicyExplorer INSTANCE; + + static { + INSTANCE = new HierarchicalPolicyExplorer(); + } + + public static HierarchicalPolicyExplorer getInstance() { + return INSTANCE; + } + + private HierarchicalPolicyExplorer() { + + } + + //private PolicyWrapper defaultPolicy; + private UmlClass defaultPolicy; + + public UmlClass getDefaultPolicy() { + aLog.debug("getDefaultPolicy"); + if ( defaultPolicy == null ) { + ModuleController moduleController = ModuleController.getInstance(); + if ( moduleController != null ) { + + Set unrefined = getUnrefinedPolicies(); + aLog.debug("got " + unrefined.size() + " unrefined policies"); + + if ( unrefined != null && unrefined.size() > 0) { + PolicyWrapper pol = unrefined.iterator().next(); + aLog.debug("First name: " + pol.getName()); + if ( unrefined.size() == 1 && pol.getName().equals(SecureUmlConstants.DEFAULT_POLICY_NAME)) { + aLog.debug("default policy already defined"); + //pol.get + defaultPolicy = (UmlClass) ModuleController.getInstance().getModelMap().getUmlElement(pol.getModelElement()); + } + } + + if ( defaultPolicy == null ) { +// Namespace nm; +// if ( unrefined != null && unrefined.size() > 0) { +// nm = ((UmlClass) unrefined.iterator().next().getModelElement()).getNamespace(); +// } else { +// nm = GenericDialectModelMapper.getInstance().getInitNamespace(); +// } + + try { + aLog.debug("#############################################"); + aLog.debug("START ModuleController.getInstance().createPolicy"); + defaultPolicy = ModuleController.getInstance().createPolicy(SecureUmlConstants.DEFAULT_POLICY_NAME, unrefined, GenericDialectModelMapper.getInstance().getSecUMLPackage()); + //as long as the model object of defaultPolicy is null... + //defaultPolicy = null; + aLog.debug("END ModuleController.getInstance().createPolicy: " + defaultPolicy); + aLog.debug("#############################################2"); + + } catch(Exception e) { + aLog.error("error at creating default policy: " + e.getClass().toString() + ": " + e.getMessage(), e); + } + } + } else + aLog.debug("ModuleController.getInstance() == null"); + } + if (aLog.isDebugEnabled()) { + aLog.debug("getDefaultPolicy: " + (defaultPolicy == null ? "NULL" : defaultPolicy.getName())); + } + + return defaultPolicy; + } + +// public UmlClass getDefaultPolicy() { +// aLog.debug("getDefaultPolicy"); +// if ( defaultPolicy == null ) { +// ModuleController moduleController = ModuleController.getInstance(); +// if ( moduleController != null ) { +// +// Set unrefined = getUnrefinedPolicies(); +// aLog.debug("got " + unrefined.size() + " unrefined policies"); +// if ( unrefined != null && unrefined.size() > 0) { +// PolicyWrapper pol = unrefined.iterator().next(); +// aLog.debug("First name: " + pol.getName()); +// if ( unrefined.size() == 1 && pol.getName().equals(SecureUmlConstants.DEFAULT_POLICY_NAME)) { +// aLog.debug("default policy already defined"); +// //pol.get +// defaultPolicy = (UmlClass) ModuleController.getInstance().getModelMap().getUmlElement(pol.getModelElement()); +// //defaultPolicy = pol; +// } else { +// try { +// aLog.debug("#############################################"); +// aLog.debug("START ModuleController.getInstance().createPolicy"); +// defaultPolicy = ModuleController.getInstance().createPolicy(SecureUmlConstants.DEFAULT_POLICY_NAME, unrefined); +// //as long as the model object of defaultPolicy is null... +// //defaultPolicy = null; +// aLog.debug("END ModuleController.getInstance().createPolicy: " + defaultPolicy); +// aLog.debug("#############################################2"); +// +// } catch(Exception e) { +// aLog.error("error at creating default policy: " + e.getClass().toString() + ": " + e.getMessage(), e); +// } +// } +// } else { +// aLog.error("TODO create default policy and get namespace from somewhere different... "); +// } +// } else +// aLog.debug("ModuleController.getInstance() == null"); +// } +// if (aLog.isDebugEnabled()) { +// aLog.debug("getDefaultPolicy: " + (defaultPolicy == null ? "NULL" : defaultPolicy.getName())); +// } +// +// return defaultPolicy; +// } + + public PolicyWrapper getDefaultPolicyWrapper() { + return new PolicyWrapper(ModuleController.getInstance().getModelMap().getElement(getDefaultPolicy())); + } + + + + + private Set getUnrefinedPolicies() { + ModuleController moduleController = ModuleController.getInstance(); + if (moduleController != null) { + List allPolicies = moduleController.getAllPolicies(); + aLog.debug("found " + allPolicies.size() + " polices"); + + Set policies = new HashSet(); + + boolean default_exists = false; + + for ( Object policy : allPolicies) { + PolicyWrapper policyWrapper = new PolicyWrapper(policy); + Collection refinedBy = policyWrapper.getRefinedBy(); + if ( policyWrapper.getRefinedBy() == null || refinedBy.size() == 0 ) { + policies.add(policyWrapper); + } + if (SecureUmlConstants.DEFAULT_POLICY_NAME.equals(policyWrapper.getName())) { + default_exists = true; + if ( policyWrapper.getRefinedBy() != null && policyWrapper.getRefinedBy().size() > 0) { + aLog.error("INVALID DEFAULT POLICY! Policy with name " + SecureUmlConstants.DEFAULT_POLICY_NAME + " must not have a refining policy: " + policyWrapper.getRefinedByWrappers().iterator().next().getName() + "!"); + } + } + + } + if ( default_exists && policies.size() != 1) { + aLog.error("INVALID DEFAULT POLICY! Policy with name " + SecureUmlConstants.DEFAULT_POLICY_NAME + " must be the only one not being refined!"); + } + return policies; + } else { + return null; + } + } + + //public List getSortedPolicies() { + public List getSortedPolicies() { + + PolicyWrapper defaultPolicyWrapper = getDefaultPolicyWrapper(); + + + //list which contains the end result + List sortedPolicies = new ArrayList(); + //hash set for fast lookup, if a policy is already inserted + Set alreadyInserted = new HashSet(); + + if (defaultPolicyWrapper == null) { + aLog.debug("no default policy found... adding unrefined policies"); + + //hack... currently the adding of the policy requires a reload.. should be eleminated sooner or later.. + alreadyInserted = getUnrefinedPolicies(); + + sortedPolicies.add(null); + + for (PolicyWrapper pol : alreadyInserted) { + sortedPolicies.add(pol); + } + } else { + sortedPolicies.add(defaultPolicyWrapper); + alreadyInserted.add(defaultPolicyWrapper);//?? needed? + } + + + int start, end; + end = 0; + boolean added = true; + boolean allIn; + + //as long as a policy has been added, restart a new round + while (added) { + // do only bother the policies inserted in the last round + start = end; + end = sortedPolicies.size(); + added = false; + //clear all marks + + // for every policy in the last round + for (int i = start; i < end; ++i) { + //get the policies which refine this policy + Collection refinesPolicies = sortedPolicies.get(i).getRefinesWrappers(); + if ( refinesPolicies != null && refinesPolicies.size() > 0 ) { + //for all refining polices + for ( PolicyWrapper refines : refinesPolicies) { + //if the policy only is refined by one policy, we can add it + if ( refines.getRefinedBy().size() == 1) { + sortedPolicies.add(refines); + added = true; + } else { + allIn = true; + for ( PolicyWrapper supPol : refines.getRefinedByWrappers() ) { + if ( ! alreadyInserted.contains(supPol) ) { + allIn = false; + } + } + if ( allIn ) { + sortedPolicies.add(refines); + added = true; + } + } + } + } + } + //last, we add all this round added policies in the "lookup" set: + //we cannot add them during the main loop, as this would result in wrong loopups + // L0 + // / | \ + // L1 L2 L3 + // | | | + // L4 | L5 + // \ / + // L6 + //should result in L0 -> L1 -> L2 -> L3 -> L4 -> L5 -> L6 + // if we add L4 to alreadyInserted in the loop, the lookup for L6 says, that all + // refinedBy policies are already inserted, i.e., L6 is inserted (before L3) + // resulting in L0 -> L1 -> L2 -> L3 -> L4 -> L6 -> L5 + if ( added ) { + for ( int i = end; i < sortedPolicies.size(); ++i ) { + alreadyInserted.add(sortedPolicies.get(i)); + } + } + } + aLog.debug("getSortedPolicies: return " + sortedPolicies.size() + " policies"); + + //hack + ModelMap map = ModuleController.getInstance().getModelMap(); + + List sortedPoliciesResolved = new ArrayList(); + for ( PolicyWrapper policy : sortedPolicies) { + sortedPoliciesResolved.add((UmlClass) map.getUmlElement(policy.getModelElement())); + } + + return sortedPoliciesResolved; + } + + +// public static List getSortedPolicies() { +// +// ModuleController moduleController = ModuleController.getInstance(); +// +// if ( moduleController == null ) { +// aLog.error("Received null for ModuleController"); +// return new ArrayList(); +// } +// +// List allPolicies = moduleController.getAllPolicies(); +// aLog.debug("found " + allPolicies.size() + " polices"); +// +// Set policies = new HashSet(); +// +// for ( Object policy : allPolicies) { +// PolicyWrapper policyWrapper = new PolicyWrapper(policy); +// if ( policyWrapper.getRefined_by() != null ) { +// policies.add(policyWrapper); +// } +// } +// aLog.debug("found " + policies.size() + " not beeing refined"); +// +// +// +// //TODO get default policy ? +// //GenericDialectModelMapper.getInstance().getDefaultPolicyWrapper(); +// +// List sortedPolicies = new ArrayList(); +// +// +// for ( PolicyWrapper policy : policies ) { +// sortedPolicies.add(policy); +// } +// +// int start, end; +// end = 0; +// boolean added = true; +// +// while (added) { +// start = end; +// end = sortedPolicies.size(); +// for (int i = start; i < end; ++i) { +// for ( PolicyWrapper refines : sortedPolicies.get(i).getRefinesWrappers()) { +// if ( ! policies.contains(refines) ) { +// sortedPolicies.add(refines); +// policies.add(refines); +// added = true; +// } +// } +// } +// } +// return sortedPolicies; +// } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/PermissionSet.java b/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/PermissionSet.java new file mode 100644 index 0000000..1bf0fd1 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/PermissionSet.java @@ -0,0 +1,78 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.modelmapping.permissions; + +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.Map; +import java.util.Set; + +import ch.ethz.infsec.secureumlgui.wrapper.RoleWrapper; + +/** + * A mapping from Roles to {@link ResourcePermissionsSet}s. In the + * end, this gives a mapping from roles and actions to the list of + * permissions the role has for the action. + * + *
+ * PermissionSet
+ *
+ *    ||
+ *
+ * Role -> {@link ResourcePermissionsSet}
+ *
+ *                 ||
+ *
+ *          Action -> {@link ActionPermissionSet}
+ *
+ *                           ||
+ *
+ *                    List<{@link PermissionValue}>
+ *                    {@link RoleWrapper}
+ *                    {@link ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper}
+ * 
+ * + */ +public class PermissionSet +{ + Map permissions = + new LinkedHashMap(); + + + /** + * returns the resource permission set associated to the roleWrapper's UML model element. + * creates a new, empty one, if necessary. + */ + public ResourcePermissionsSet getResourcePermissionsSet(RoleWrapper roleWrapper) + { + ResourcePermissionsSet result = permissions.get(roleWrapper.getModelElement()); + if(result == null) + { + result = new ResourcePermissionsSet(); + permissions.put(roleWrapper.getModelElement(), result); + } + + + return result; + } + + /** + * creates a (copy) of the set of all role wrappers. + */ + public Set getAllRoleWrappers() + { + Set roleWrappers = + new LinkedHashSet(); + + for (Iterator iter = permissions.keySet().iterator(); iter.hasNext();) + { + Object role = (Object) iter.next(); + + roleWrappers.add(new RoleWrapper(role)); + } + + return roleWrappers; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/PermissionValue.java b/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/PermissionValue.java new file mode 100644 index 0000000..4e3d42a --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/PermissionValue.java @@ -0,0 +1,564 @@ +package ch.ethz.infsec.secureumlgui.modelmapping.permissions; + +import java.util.LinkedHashMap; +import java.util.LinkedList; +import java.util.Set; +import java.util.Stack; + +import org.apache.log4j.Logger; + +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.securemodelimpl.SecureModelFactory; +import ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PermissionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.RoleWrapper; + +/** + * The value of a Permission (i.e., denied, granted, inherited, etc). + * + */ +public class PermissionValue implements Comparable +{ + /** + * not permitted + */ + public static final int INT_DENIED = 0; + /** + * is permitted + */ + public static final int INT_GRANTED = 0x1; + /** + * is permitted, if the corresponding policy is active + */ + public static final int INT_EMERGENCY = 0x2; + /** + * inherited from a super role + */ + public static final int INT_INHERITED_ROLE = 0x10; + /** + * inherited from a super policy + */ + public static final int INT_INHERITED_POLICY = 0x100; //inherited + /** + * is inherited == INT_INHERITED_ROLE | INT_INHERITED_POLICY + */ + public static final int INT_INHERITED = INT_INHERITED_ROLE | INT_INHERITED_POLICY; + /** + * implicit, as a super action is permitted + */ + public static final int INT_IMPLICIT = 0x20; + /** + * implicit, as all sub actions are permitted + */ + public static final int INT_COMPOSITE = 0x40; + /** + * to the permission a constrained is assigned + */ + public static final int INT_CONSTRAINED = 0x80000000; + + + private int flags; + + protected MultiContextLogger logger = MultiContextLogger.getDefault(); + + protected PermissionWrapper permission; + + // may only be != null if INT_COMPOSITE + private Set permittedSubActions; + /* + * may only be != null if + * => permission is NOT an explicit permission + * => OR cannot be DIRECTLY derivated form a explicit permissions + * ATTENTION: may be null AND permission cannot be derivated form a explicit permissions: + * this is the case, if the permission is COMPOSITE => permittedSubActions must be != null + */ + private LinkedHashMap permissionDerivation; + + private static Logger aLog = Logger.getLogger(PermissionValue.class); + //counter for tmp permissions + private static int tmp_perm = 0; + + + @Override + public String toString() { + if (permission == null ) { + return "NO_PERMISSION"; + } + + StringBuffer buffer = new StringBuffer(); + buffer.append(permission.getName()); + + buffer.append(" Role: "); + RoleWrapper role = permission.getRoleWrapper(); + if ( role == null ) { + buffer.append("null"); + } else { + buffer.append(role.getName()); + } + + buffer.append(" Action: "); + ActionWrapper action = permission.getActionWrapper(); + if ( action == null ) { + buffer.append("null"); + } else { + buffer.append(action.getName()); + } + + buffer.append(" flags: 0x"); + buffer.append(Integer.toHexString(flags)); + + buffer.append(" subActions: "); + if (permittedSubActions == null) { + buffer.append("null"); + } else { + buffer.append(permittedSubActions.size()); + } + + buffer.append(" derivationStack: "); + if (permissionDerivation == null) { + buffer.append("null"); + } else { + buffer.append(permissionDerivation.size()); + } + + return buffer.toString(); + } + + /** + * creates a new GANTED permission + * @param permission + */ + public PermissionValue(PermissionWrapper permission) { + this.flags = INT_GRANTED; + this.permission = permission; + checkConstrained(); + } + + /** + * creates a new permission + * @param flags + * @param permission + */ + public PermissionValue(int flags, PermissionWrapper permission) { + this.flags = flags; + this.permission = permission; + checkConstrained(); + } + + private PermissionValue() { + + } + + /** + * create a new GRANTED Permission + * @param permission + * @return + */ + public static PermissionValue createGranted(PermissionWrapper permission) { + return new PermissionValue(permission); + } + /** + * creates a INHERITED BY ROLE Permission + * @param template + * @return + */ + public static PermissionValue createInheritedRole(PermissionValue template) { + return createDerived(template, INT_INHERITED_ROLE); + } + /** + * creates a INHERITED BY POLICY Permission + * @param template + * @return + */ + public static PermissionValue createInheritedPolicy(PermissionValue template) { + return createDerived(template, INT_INHERITED_POLICY); + } + /** + * creates a IMPLICIT Permission + * @param template + * @return + */ + public static PermissionValue createImplicite(PermissionValue template) { + return createDerived(template, INT_IMPLICIT); + } + /** + * creates a COMPOSITE Permission + * @param resourcePermissions currently unsed, but could be needed to calcuclate a correct flags + * @param action + * @param role + * @return + */ + public static PermissionValue createComposite(ResourcePermissionsSet resourcePermissions, ActionWrapper action, RoleWrapper role) { + //create a new SecureUML Permission and assign role and action + PermissionWrapper newPermission = new PermissionWrapper(SecureModelFactory.getInstance().createPermission("tmp_perm_" + ++tmp_perm)); + newPermission.setAction(action.getModelElement()); + newPermission.setRoleWrapper(role); + + PermissionValue newPermVal = new PermissionValue(); + newPermVal.permittedSubActions = action.getSubActionWrappers(); + newPermVal.flags = INT_COMPOSITE; + newPermVal.permission = newPermission; + +// //TODO collect the flags of the subactions! is not distinct... +// for ( ActionWrapper subaction : newPermVal.permittedSubActions ) { +// ActionPermissionSet actionPermissions = resourcePermissions.getPermissions(subaction); +// for ( PermissionValue permValue : actionPermissions.getPermissions() ) { +// newPermVal.flags |= permValue.flags; +// } +// } +// newPermVal.flags = ~(~newPermVal.flags | INT_GRANTED); + + newPermVal.checkConstrained(); + + return newPermVal; + } + + + private static PermissionValue createDerived(PermissionValue template, int flag) { + int templ_flags = template.getFlags(); + if ( (templ_flags & INT_GRANTED) > 0 ) { //can be directly derived from a explicit permission + return createByTemplate(template, ~(~templ_flags | INT_GRANTED) | flag); + } + else { + PermissionValue newPermVal = new PermissionValue(); + + newPermVal.permission = template.permission; + newPermVal.flags = template.flags | flag; + if (template.permissionDerivation != null ) { + newPermVal.permissionDerivation = (LinkedHashMap) template.permissionDerivation.clone(); + } else { + newPermVal.permissionDerivation = new LinkedHashMap(); + } + newPermVal.permissionDerivation.put(template, new Integer(flag)); + + return newPermVal; + } + } + + private static PermissionValue createByTemplate(PermissionValue template, int flag) { + return new PermissionValue(template.flags | flag, template.getPermissionWrapper()); + } + + + + +// public static PermissionValue createInheritedRole(PermissionValue template) { +// int templ_flags = template.getFlags(); +// if ( (templ_flags & INT_GRANTED) > 0 ) { //can be directly derived from a explicit permission +// return createByTemplate(template, ~(~templ_flags | INT_GRANTED) | INT_INHERITED_ROLE); +// } +// else { // +// PermissionValue newPermVal = new PermissionValue(); +// newPermVal.flags = template.flags | INT_INHERITED_ROLE; +// //newPermVal.permissionDerivation = new LinkedHashMap(); +// if (template.permissionDerivation != null ) { +// newPermVal.permissionDerivation = (LinkedHashMap) template.permissionDerivation.clone(); +//// for (PermissionValue permVal : template.permissionDerivation) { +//// newPermVal.permissionDerivation.add(permVal); +//// } +// } else { +// newPermVal.permissionDerivation = new LinkedHashMap(); +// } +// newPermVal.permissionDerivation.put(template, new Integer(INT_INHERITED_ROLE)); +// +// +// +// } +// +// +// return createByTemplate(template, INT_INHERITED_ROLE); +//} +//public static PermissionValue createInheritedPolicy(PermissionValue template) { +//return createByTemplate(template, INT_INHERITED_POLICY); +//} + + + + + public int getFlags() { + return flags; + } + + @Deprecated + public int getValue() { + if ( (flags & INT_IMPLICIT ) > 0) { + return INT_IMPLICIT; + } else if ( (flags & INT_COMPOSITE) > 0) { + return INT_COMPOSITE; + } else if ( (flags & INT_INHERITED_ROLE) > 0) { + return INT_INHERITED_ROLE; + } else if ( (flags & INT_GRANTED ) > 0) { + return INT_GRANTED; + } + return flags; + } + +// public void setFlags(int value) +// { +// this.flags = value; +// } + +// public void addFlags(int flags) { +// this.flags |= flags; +// } + + /** + * @return the suPermission + */ + public PermissionWrapper getPermissionWrapper() + { + return permission; + } + + /** + * @param permissionWrapper the PermissionWrapper to set + */ + public void setPermissionWrapper(PermissionWrapper permissionWrapper) + { + this.permission = permissionWrapper; + } + + + /** + * checks if the encapsulated permission has a constrained + */ + private void checkConstrained() { + if ( (flags & INT_COMPOSITE) > 0 || permittedSubActions != null) { + boolean anyActionContrained = false; + for ( ActionWrapper action : permittedSubActions ) { + boolean anyPermissionUnConstrained = false; + for ( PermissionWrapper permission : action.getPermissionWrappers() ) { + if ( ! permission.isConstrained() ) { + anyPermissionUnConstrained = true; + break; + } + } + if ( ! anyPermissionUnConstrained ) { + anyActionContrained = true; + break; + } + } + if ( anyActionContrained ) { + flags |= INT_CONSTRAINED; + } + } + + + if ( permission.getAuthorizationConstraint() != null ) { + String constraint = permission.getAuthorizationConstraintWrapper().getConstraint(); + if(constraint != null && constraint.length() != 0) + { + flags |= INT_CONSTRAINED; + } + } + } + + + /* (non-Javadoc) + * @see java.lang.Comparable#compareTo(java.lang.Object) + */ + public int compareTo(PermissionValue o) + { + return new Integer(flags).compareTo(new Integer(o.getValue())); + + } + +// /* (non-Javadoc) +// * @see java.lang.Object#equals(java.lang.Object) +// */ +// @Override +// public boolean equals(Object obj) +// { +// if (obj instanceof PermissionValue) { +// PermissionValue pv = (PermissionValue) obj; +// +// return (getValue() == pv.getValue()); //TODO realy? no matter of the permission? +// } +// else { +// return super.equals(obj); +// } +// } + + @Override + public boolean equals(Object obj) { + if ( obj instanceof PermissionValue) { + PermissionValue pv = (PermissionValue) obj; + return (flags == pv.flags && permission.equals(pv.permission)); + } + else { + return super.equals(obj); + } + } + + + + + + public boolean isConstrained() + { + if ( (flags & PermissionValue.INT_CONSTRAINED) > 0 ) + return true; + else { + return false; + } + } + + public void setConstrained(boolean constrained) + { + if ( constrained ) { + flags |= INT_CONSTRAINED; + } else { + flags = ~( (~flags) | INT_CONSTRAINED); //TODO there must be a better way + } + } + + public String getDescription() { + StringBuffer buffer = new StringBuffer(); + + String name; + + if ( (flags & INT_COMPOSITE) > 0 ) { + buffer.append("COMPOSITE Permission, "); + } else if ( permission != null && (name = permission.getName()) != null && name.length() > 0 ) { + buffer.append(name); + buffer.append(" Permission, "); + } + + if ( (flags & INT_INHERITED_ROLE) > 0 ) { + buffer.append("inherited from role: "); + buffer.append(permission.getRoleWrapper().getName()); + buffer.append(", "); + } + + if ( (flags & INT_INHERITED_POLICY) > 0 ) { + buffer.append("inherited from policy: "); + //buffer.append(permission.getPolicyWrapper().getName()); //TODO hel fix nullpointer + buffer.append(", "); + } + + if ( (flags & INT_IMPLICIT) > 0 ) { + buffer.append("implicit from action: "); + buffer.append(permission.getActionWrapper().getResourceWrapper().getResourcePath()); + buffer.append("."); + buffer.append(permission.getActionWrapper().getName()); + buffer.append(", "); + } + + if ( (flags & INT_COMPOSITE) > 0 ) { + buffer.append("implicit from all permitted subactions"); + } + + if(isConstrained()) { + buffer.append(" with Authorization Constraint"); + } + + return buffer.toString(); + } + + public Set getPermittedSubActions() { + + return permittedSubActions; + } + + public void setPermittedSubActions(Set permittedSubActions) { + if ( (flags & INT_COMPOSITE ) == 0 ) { + aLog.warn("Setting permittedSubActions, but Permission is not permitted through permitted subactions!"); + } + this.permittedSubActions = permittedSubActions; + } + + + + + + + @Deprecated + public static PermissionValue create(PermissionValue template, + PermissionWrapper permissionWrapper, boolean constrained) { + PermissionValue pv = null; + + pv = new PermissionValue( + template.getName(), template.getValue()); + + pv.setPermissionWrapper(permissionWrapper); + + pv.setConstrained(constrained); + + return pv; + } + + @Deprecated + public static PermissionValue create(PermissionValue template, + PermissionWrapper permissionWrapper) { + boolean constrained = false; + + if(permissionWrapper.getAuthorizationConstraint() != null) + { + String constraint = permissionWrapper.getAuthorizationConstraintWrapper().getConstraint(); + if(constraint != null && constraint.length() != 0) + { + constrained = true; + } + } + return create(template, permissionWrapper, constrained); + } + + @Deprecated + public String getName() + { + if ( (flags & INT_GRANTED ) > 0) { + return "Explicit"; + } else if ( (flags & INT_INHERITED_ROLE) > 0) { + return "Inherited"; + } else if ( (flags & INT_IMPLICIT) > 0) { + return "Implicit"; + } else if ( (flags & INT_COMPOSITE ) > 0) { + return "Composite"; + } + return "TODO_UNDEFIEND"; + } + + @Deprecated + public void setName(String name) + { + this.name = name; + } + + @Deprecated + private String name; + + @Deprecated + private boolean constrained = false; + + + @Deprecated + protected PermissionValue(String name, int value) { + this.name = name; + this.flags = value; + } + + @Deprecated + public static final PermissionValue GRANTED = + new PermissionValue("Explicit", INT_GRANTED); + + @Deprecated + public static final PermissionValue DENIED = + new PermissionValue("Denied", INT_DENIED); + + // inherited from a super-role + @Deprecated + public static final PermissionValue INHERITED = + new PermissionValue("Inherited", INT_INHERITED_ROLE); + + // implicitly granted by a composite action + @Deprecated + public static final PermissionValue IMPLICIT = + new PermissionValue("Implicit", INT_IMPLICIT); + + // implicitly there, because permissions for all subactions are there (but not the composite action itself) + @Deprecated + public static final PermissionValue COMPOSITE = + new PermissionValue("Composite", INT_COMPOSITE); + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/PolicyPermissionSet.java b/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/PolicyPermissionSet.java new file mode 100644 index 0000000..defa76c --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/PolicyPermissionSet.java @@ -0,0 +1,220 @@ +package ch.ethz.infsec.secureumlgui.modelmapping.permissions; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Set; + +import org.apache.log4j.Logger; + +import ch.ethz.infsec.secureumlgui.modelmapping.permissions.HierarchicalPermissionsExplorer.CHANGES; +import ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PermissionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PolicyWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.RoleWrapper; + +public class PolicyPermissionSet { + + Collection permissions = + new LinkedList(); + + private static Logger aLog = Logger.getLogger(PolicyPermissionSet.class); + + private PolicyWrapper policy; + + + private PolicyWrapper explicitPolicyWrapper; + + + public PolicyPermissionSet(PolicyWrapper policy) { + this.policy = policy; + } + + public void addPermission(PermissionValue permissionValue, CHANGES changeReason) + { + aLog.debug("add permission: " + permissionValue.getPermissionWrapper().getActionWrapper().getName() + " " + permissionValue.getPermissionWrapper().getRoleWrapper().getName() + " " + changeReason); + for (PermissionValue value : permissions ) { + if ( value.equals(permissionValue)) { + aLog.debug("Omitting redundant permission: already \nsaved: " + value + " \nnew: " + permissionValue); + return; //alredy here... + } + } + if ( changeReason == CHANGES.IMPLICIT_SUPER //if this is a new permission + && isPermitted() + && (permissionValue.getFlags() & PermissionValue.INT_GRANTED) == 0 ) { + aLog.debug("Omitting an implicit super permission: action already permitted and implicit super permission is not explicit!"); + return; + } + permissions.add(permissionValue); + } + + public void addExplicitPermission(PermissionValue permissionValue) { + addPermission(permissionValue); + } + + private void addPermission(PermissionValue permissionValue) { + permissions.add(permissionValue); + } + + public void addPermission(PermissionValue permissionValue, PermissionSet permissions_next, CHANGES changeReason, ActionWrapper action, RoleWrapper role) { + + for (PermissionValue value : permissions ) { + if ( value.equals(permissionValue)) { + aLog.debug("Omitting redundant permission: already \nsaved: " + value + " \nnew: " + permissionValue); + return; //alredy here... + } + } + + if ( changeReason == CHANGES.IMPLICIT_SUPER //if this is a new permission + && isPermitted() + && (permissionValue.getFlags() & PermissionValue.INT_GRANTED) == 0 ) { + aLog.debug("Omitting an implicit super permission: action already permitted and implicit super permission is not explicit!"); + return; + } + + if ( aLog.isDebugEnabled() ) { + aLog.debug(" addPermission to action: " + permissionValue + " changeReason: " + changeReason + " isPermitted: " + isPermitted()); + } + + PermissionWrapper permission = permissionValue.getPermissionWrapper(); + + switch ( changeReason ) { + case INHERITED: + //if change was caused by inerhitance, the implicit may change, i.e., + Set relatedActions = HierarchicalPermissionsExplorer.getSubAndSuperActionWrappersDeep(permission.getActionWrapper()); + //RoleWrapper inh_role = permission.getRoleWrapper(); + for ( ActionWrapper inh_action : relatedActions) { + aLog.debug(" Adding permission to next; action = " + inh_action.getName() + " role = " + role.getName()); + //permissions_next.getResourcePermissionsSet(inh_role).getPermissions(inh_action).addPermission(permissionValue); + //TODO is CHANGES.INHERITED correct? not sure for now... + permissions_next.getResourcePermissionsSet(role).getPermissions(inh_action).addPermission(policy, permissionValue, changeReason); + } + + break; + case IMPLICIT_SUPER://TODO for IMPLICIT_SUB we could "reroute" back and add a listener to do same stuff as inherited? +// relatedActions = HierarchicalPermissionsExplorer.getSubActionWrappersDeep(permission.getActionWrapper()); +// inh_role = permission.getRoleWrapper(); +// for ( ActionWrapper inh_action : relatedActions) { +// aLog.debug(" Adding permission to next; action = " + inh_action.getName()); +// permissions_next.getResourcePermissionsSet(inh_role).getPermissions(inh_action).addPermission(permissionValue); +// } + +// //NO BREAK! need to add "indicators" for sub roles too! + case IMPLICIT_SUB: + //if change was caused by an implicit, the inheritance may change, i.e., + Set superRoles = HierarchicalPermissionsExplorer.getSubRoleWrapperDeep(permission.getRoleWrapper()); + //ActionWrapper imp_action = permission.getActionWrapper(); + for ( RoleWrapper imp_role : superRoles ) { + aLog.debug(" Adding permission to next; role = " + imp_role.getName() + " action = " + action.getName()); + //permissions_next.getResourcePermissionsSet(imp_role).getPermissions(imp_action).addPermission(permissionValue); + //TODO as above - is changeReson correct? not sure + permissions_next.getResourcePermissionsSet(imp_role).getPermissions(action).addPermission(policy, permissionValue, changeReason); + } + break; + } + + //finally, add permission + permissions.add(permissionValue); + } + + + + +// /** returns GRANTED if the permission was explicitly defined, +// * DENIED in all other cases. +// */ +// public PermissionValue getExplicitPermission() +// { +// PermissionValue result = PermissionValue.DENIED; +// +// for (PermissionValue pv : permissions) +// { +// //TODO ordering????? if ordering is not relevant, function can return in case of GRANTED +// if(pv.getValue() == PermissionValue.GRANTED.getValue() +// || pv.getValue() == PermissionValue.DENIED.getValue()) { +// result = pv; +// } +// } +// return result; +// } + + public boolean isExplicitPermitted() { + for ( PermissionValue permission : permissions) { + if ( permission.getFlags() == PermissionValue.INT_GRANTED) { + return true; + } + } + return false; + } + + public PermissionWrapper getExplicitPermittedPermission() { + for ( PermissionValue permission : permissions) { + if ( permission.getFlags() == PermissionValue.INT_GRANTED) { + return permission.getPermissionWrapper(); + } + } + return null; + } + + + public boolean isPermitted() { + //TODO only on default permissions + if (permissions.size() > 0 ) + return true; + else + return false; + + } + + + public Collection getPermissions() + { + //TODO only default permissions + return permissions; + } + + + + + public PolicyWrapper getExplicitPolicyWapper() { + return explicitPolicyWrapper; + } + + public void setExplicitPolicyWrapper(PolicyWrapper eplicitPolicyWrapper) { + this.explicitPolicyWrapper = eplicitPolicyWrapper; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + String resultString = "**"; + + for (Iterator iter = getPermissions().iterator(); iter.hasNext();) + { + PermissionValue pv = (PermissionValue) iter.next(); + + if(pv.equals(pv.GRANTED)) + { + if(pv.isConstrained()) + resultString += "(?)"; + } + } + + for (Iterator iter = getPermissions().iterator(); iter.hasNext();) + { + PermissionValue pv = (PermissionValue) iter.next(); + + if(!pv.equals(pv.GRANTED)) + { + resultString += pv.getName().charAt(0); + if(pv.isConstrained()) + resultString += "(?)"; + } + } + return resultString; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/ResourcePermissionsSet.java b/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/ResourcePermissionsSet.java new file mode 100644 index 0000000..b3e2f10 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/ResourcePermissionsSet.java @@ -0,0 +1,80 @@ +package ch.ethz.infsec.secureumlgui.modelmapping.permissions; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; + +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; + +import ch.ethz.infsec.secureumlgui.wrapper.ActionWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.PolicyWrapper; + +/** + * A mapping from actions to {@link ActionPermissionSet}s + * + * + */ +public class ResourcePermissionsSet { + Map resourcePermissions = new LinkedHashMap(); + + MultiContextLogger logger = MultiContextLogger.getDefault(); + + public void addPermission(ActionWrapper actionWrapper, + PermissionValue permissionValue, PolicyWrapper policy) { + ActionPermissionSet actionPermissions = getPermissions(actionWrapper); + + if (actionPermissions == null) { + actionPermissions = new ActionPermissionSet(); + resourcePermissions.put(actionWrapper.getModelElement(), + actionPermissions); + } + actionPermissions.addPermission(policy, permissionValue, HierarchicalPermissionsExplorer.CHANGES.EXPLICIT); + } + + public ActionPermissionSet getPermissions(Object action) { + ActionPermissionSet result = resourcePermissions.get(action); + + if (result == null) { + result = new ActionPermissionSet(); + resourcePermissions.put(action, result); + + result.setExplicitActionWrapper(new ActionWrapper(action)); + } + + return result; + } + + public ActionPermissionSet getPermissions(ActionWrapper actionWrapper) { + ActionPermissionSet result = resourcePermissions.get(actionWrapper + .getModelElement()); + + if (result == null) { + result = new ActionPermissionSet(); + resourcePermissions.put(actionWrapper.getModelElement(), result); + } + + return result; + } + + public Collection getActions() { + return resourcePermissions.keySet(); + } + + public ActionPermissionSet getPermissions(String actionShortname) { + for (Iterator iter = resourcePermissions.keySet().iterator(); iter + .hasNext();) { + ActionWrapper actionWrapper = ActionWrapper + .createActionWrapper(iter.next()); + if (actionWrapper == null) + logger.error("actionWrapper == null"); + if (actionShortname != null + && actionShortname.equals(actionWrapper.getName())) { + return getPermissions(actionWrapper); + } + } + + return new ActionPermissionSet(); + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/package.html b/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/package.html new file mode 100644 index 0000000..1b7124d --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/permissions/package.html @@ -0,0 +1,8 @@ + + + + + +Deals with Permissions and their hierarchy. + + diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/strategies/MapSelf.java b/src/ch/ethz/infsec/secureumlgui/modelmapping/strategies/MapSelf.java new file mode 100644 index 0000000..1acb8ff --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/strategies/MapSelf.java @@ -0,0 +1,32 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.modelmapping.strategies; + +import java.util.LinkedHashSet; +import java.util.Set; + +import org.omg.uml.foundation.core.ModelElement; + +/** + * + * Mapping only the ModelElement itself - too simple. + * This way, composite actions cannot be considered + */ +public class MapSelf extends MappingScopeStrategy +{ + /** + * @see ch.ethz.infsec.secureumlgui.modelmapping.strategies.MappingScopeStrategy#getMappingScope(org.omg.uml.foundation.core.ModelElement) + * + * @return Collection containing the @param modelElement as the only Member + */ + @Override + public Set getMappingScope(ModelElement modelElement) + { + LinkedHashSet result = new LinkedHashSet(); + + result.add(modelElement); + + return result; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/strategies/MapSelfAndAssociatedResources.java b/src/ch/ethz/infsec/secureumlgui/modelmapping/strategies/MapSelfAndAssociatedResources.java new file mode 100644 index 0000000..2b314c9 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/strategies/MapSelfAndAssociatedResources.java @@ -0,0 +1,567 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.modelmapping.strategies; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.Set; + +import org.apache.log4j.Logger; +import org.argouml.model.Model; +import org.omg.uml.foundation.core.AssociationClass; +import org.omg.uml.foundation.core.Classifier; +import org.omg.uml.foundation.core.Generalization; +import org.omg.uml.foundation.core.ModelElement; +import org.omg.uml.foundation.core.Namespace; +import org.omg.uml.behavioralelements.statemachines.State; +import org.omg.uml.behavioralelements.statemachines.Transition; + + +import ch.ethz.infsec.secureumlgui.Util; +import ch.ethz.infsec.secureumlgui.modelmapping.GenericDialectHelper; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.AssociationEnd; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.DialectMetaModelInfo; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.InterResourceAssociation; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.MetaModelClass; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ResourceType; + +/** + * + */ +public class MapSelfAndAssociatedResources + extends SecureUmlMappingScopeStrategy +{ + + /** + * + */ + public MapSelfAndAssociatedResources(DialectMetaModelInfo mmInfo) + { + this.mmInfo = mmInfo; + } + + DialectMetaModelInfo mmInfo; + + /* (non-Javadoc) + * @see ch.ethz.infsec.secureumlgui.modelmapping.MappingScopeStrategy#getMappingScope(tudresden.ocl20.core.jmi.uml15.core.ModelElement) + */ + + private int currentNavigationDepth = 6; + + private int navigationDepth = 6; + + public int getNavigationDepth() + { + return navigationDepth; + } + + public void setNavigationDepth(int navigationDepth) + { + this.navigationDepth = navigationDepth; + this.currentNavigationDepth = navigationDepth; + } + + Set result; + + private static Logger aLog = Logger.getLogger(MapSelfAndAssociatedResources.class); + + @Override + public Set getMappingScope( + ModelElement startingPoint) + { + + System.out.println("---------------------------------"); + if(currentNavigationDepth == navigationDepth) + result = super.getMappingScope(startingPoint); + + + currentNavigationDepth--; + // logger.info("navigationDepth = "+ navigationDepth); + // logger.info("currentNavigationDepth = "+ currentNavigationDepth); + + if(currentNavigationDepth <= 0) + return new LinkedHashSet(); + + result.add(startingPoint); + + ResourceType rt = helper.getResourceType(startingPoint); + MetaModelClass mmc = null; + if(rt != null) + mmc = rt; + else + mmc = helper.getMetaModelClass(startingPoint); + + aLog.debug("getMappingScope: " + startingPoint + ";" + rt); + + if(helper.isSecureUmlRole(startingPoint)) + { + Classifier roleClass = (Classifier) startingPoint; + Collection ends = Model.getFacade().getAssociationEnds(roleClass); + for (Iterator iter = ends.iterator(); iter.hasNext();) + { + org.omg.uml.foundation.core.AssociationEnd end = (org.omg.uml.foundation.core.AssociationEnd) iter.next(); + + org.omg.uml.foundation.core.AssociationEnd otherEnd = null; + + Collection associationsEnds = end.getAssociation().getConnection(); + for (Iterator iterator = associationsEnds.iterator(); iterator + .hasNext();) + { + org.omg.uml.foundation.core.AssociationEnd associationEnd = (org.omg.uml.foundation.core.AssociationEnd) iterator.next(); + + if(end != associationEnd) otherEnd = associationEnd; + } + if(otherEnd != null) + { + result.add(otherEnd); + + Classifier otherParticipant = otherEnd.getParticipant(); + + //result.add(otherParticipant); + addMappingScope(otherParticipant, result); + + } + } + Collection g = Model.getFacade().getGeneralizations(roleClass); + for(Iterator iter = g.iterator(); iter.hasNext();) { + Generalization gen = (Generalization) iter.next(); + Classifier parent = (Classifier) gen.getParent(); + Classifier child = (Classifier) gen.getChild(); + if(parent!=roleClass && helper.isSecureUmlRole(parent)) { + addMappingScope(parent, result); + } + if(child!=roleClass && helper.isSecureUmlRole(child)) { + addMappingScope(child, result); + } + } + } + else if (helper.isSecureUmlPolicy(startingPoint)) { + Classifier policyClass = (Classifier) startingPoint; + Collection ends = Model.getFacade().getAssociationEnds(policyClass); + for (org.omg.uml.foundation.core.AssociationEnd end : ends) { + + org.omg.uml.foundation.core.AssociationEnd otherEnd = null; + for (org.omg.uml.foundation.core.AssociationEnd associationEnd : end.getAssociation().getConnection()) { + if ( end != associationEnd ) { + otherEnd = associationEnd; + } + } + if ( otherEnd != null ) { + result.add(otherEnd); + Classifier otherParticipant = otherEnd.getParticipant(); + + addMappingScope(otherParticipant, result); + } + } + Collection g = Model.getFacade().getGeneralizations(policyClass); + for (Generalization gen : g) { + Classifier parent = (Classifier) gen.getParent(); + Classifier child = (Classifier) gen.getChild(); + + if ( parent != policyClass && helper.isSecureUmlPolicy(parent)) { + addMappingScope(parent, result); + } + if (child != policyClass && helper.isSecureUmlPolicy(child)) { + addMappingScope(child, result); + } + } + } + else if(helper.isSecureUmlPermission(startingPoint)) + { + AssociationClass permissionAssociationClass = + (AssociationClass) startingPoint; + + Collection ends = permissionAssociationClass.getConnection(); + for (Iterator iter = ends.iterator(); iter.hasNext();) + { + org.omg.uml.foundation.core.AssociationEnd end = + (org.omg.uml.foundation.core.AssociationEnd) iter.next(); + + Classifier participant = end.getParticipant(); + + if(participant != null) + { + //result.add(participant); + addMappingScope(participant, result); + } + } + } + + else if (mmc != null) + { + Collection associatedAssociations = helper.getDialectMetaModelInfo() + .getInterResourceAssociations(mmc); + + // logger.info("found "+associatedAssociations.size()+" associations"); + for (Iterator iter = associatedAssociations.iterator(); iter.hasNext();) + { + Object item = iter.next(); + + if (item instanceof InterResourceAssociation) + { + InterResourceAssociation association = (InterResourceAssociation) item; + + AssociationEnd otherEnd = association.getOtherEnd(rt); + + Collection c = helper.navigateAssociation(startingPoint, otherEnd); + +// if (c instanceof Collection) +// { + if( c != null && c.size() > 0) + addModelElementsToScope(otherEnd, c); + +// } +// else if (o instanceof ModelElement) +// { +// ModelElement associatedModelElement = (ModelElement) o; +// +// try +// { +// addModelElementToScope(otherEnd, associatedModelElement); +// } +// catch (Exception e) +// { +// ; +// } +// +// } + else //if (c == null) + { + logger.info("Association could not be navigated"); + try + { + // Association could not be navigated + // - try it the other way round + + AssociationEnd end = association + .getOtherEnd((MetaModelClass) otherEnd.getType()); + + Collection allElementsInNamespace = new LinkedList(); + Namespace n = startingPoint.getNamespace(); + if(n==null) { + //startingPoint doesn't have a namespace, so it has to be contained somewhere else: + //not complete, of course. + if(startingPoint instanceof State) { + n = ((State) startingPoint).getStateMachine().getNamespace(); + } else if (startingPoint instanceof Transition) { + n = ((Transition) startingPoint).getStateMachine().getNamespace(); + } + } + Collection c1 = n.getOwnedElement(); + for (Iterator iterator = c1.iterator(); iterator.hasNext();) + { + Object temp = (Object) iterator.next(); + + allElementsInNamespace.add(temp); + } + if(startingPoint instanceof Namespace) { + logger.info("starting points is instance of Namespace"); + Collection c2 = ((Namespace) startingPoint).getOwnedElement(); + for (Iterator iterator = c2.iterator(); iterator.hasNext();) { + Object temp = (Object) iterator.next(); + allElementsInNamespace.add(temp); + } + + } +// logger.info( +// "try to navigate backwards from " +// + allElementsInNamespace.size() +// + " elements"); + Set visitedElements = + tryNavigateBackwards(otherEnd, end, + allElementsInNamespace);//, getNavigationDepth()); + logger.info("found "+visitedElements.size()+" elements by navigating backwards"); + result.addAll(visitedElements); + //result.addAll(allElementsInNamespace); + } + catch (Exception e) + { + logger.logException(e); + } + } + } + } + + // TODO: follow the associations defined in the metamodel + // along the umlGetter paths + } + else { + //logger.error("mmc = null"); + } + +// try +// { +// Set additionalScope = new LinkedHashSet(); +// for (Iterator iter = result.iterator(); iter.hasNext();) +// { +// ModelElement item = (ModelElement) iter.next(); +// +// Collection subScope = getMappingScope(item); +// +// additionalScope.addAll(subScope); +// } +// result.addAll(additionalScope); +// } +// catch (Exception e) +// { +// logger.logException(e); +// } + + + currentNavigationDepth++; + return result; + + } + + /* recursively find all Elements in mappingScope + * + */ + public void addMappingScope(ModelElement modelElement, Set mappingScope) + { + if(mappingScope.contains(modelElement)) + return; + + aLog.debug("adding modelElement "+ modelElement + " to mapping scope"); + mappingScope.add(modelElement); + + Collection additionalMappingScope = + getMappingScope(modelElement); + + //mappingScope.addAll(additionalMappingScope); + + for (Iterator iter = additionalMappingScope.iterator(); iter.hasNext();) + { + ModelElement m = (ModelElement) iter.next(); + + if(mappingScope.contains(m)) + continue; + else + { + aLog.debug("adding modelElement_"+ m + " to mapping scope"); + mappingScope.add(m); + //addMappingScope(m, mappingScope); + } + } + } + + /** + * @param otherEnd + * @param associatedModelElement + */ + private void addModelElementToScope(AssociationEnd otherEnd, ModelElement associatedModelElement) + { + if (helper.hasType(associatedModelElement, + ((MetaModelClass) otherEnd.getType()).getUmlClassName())) + { + //result.add(associatedModelElement); + addMappingScope(associatedModelElement, result); + //addMappingScope(associatedModelElement, result); + } + else + ; // not the right Type + } + + /** + * @param otherEnd + * @param c + */ + private void addModelElementsToScope(AssociationEnd otherEnd, Collection c) + { + //Collection c = (Collection) o; + for (Iterator iterator = c.iterator(); iterator.hasNext();) + { + ModelElement associatedModelElement = (ModelElement) iterator + .next(); + + try + { + addModelElementToScope(otherEnd, associatedModelElement); + } + catch (Exception e) + { + logger.logException(e); + } + } + } + + + /** + * @param otherEnd + * @param end + * @param modelElements + */ + private Set tryNavigateBackwards( + AssociationEnd otherEnd, + AssociationEnd end, + Collection modelElements)//,int maxDepth) + { + Set visitedElements = new LinkedHashSet(); + tryNavigateBackwards(otherEnd, end, modelElements, visitedElements); + + return visitedElements; + } + + /** + * @param otherEnd + * @param end + * @param modelElements + */ + private void tryNavigateBackwards(AssociationEnd otherEnd, AssociationEnd end, Collection modelElements, Set visitedElements) + { + +// if(maxDepth <= 0) +// return; + + if(modelElements == null || modelElements.size() == 0) + return; + +// logger.info(logger.MODELMAPPER_DETAILLED, +// "Try to navigate Association the other way round - " +// + "iterating over all ModelElements in the Namespace - n = " +// + modelElements.size()); + + + for (Iterator iterator = modelElements.iterator(); iterator + .hasNext();) + { + Object object = iterator.next(); + +// if (object instanceof Namespace) +// { +// Namespace ns = (Namespace) object; +// tryNavigateBackwards(otherEnd, end, ns.getOwnedElement()); +//// +//// Util.addAllSave(allElementsInNamespace, ns.getOwnedElement()); +// } + // TODO: replace this hardcoded hack by a generic solution + + if (object instanceof ModelElement) + { + + ModelElement m = (ModelElement) object; + + if(visitedElements.contains(m)) + return; + else + visitedElements.add(m); + + + if (helper.hasType(m, otherEnd.getType().getName())) + { + logger + .info("try to navigate Association in reverse Direction " + + "from end: " + + otherEnd.getName()); + + Collection coll = helper.navigateAssociation(m, end); + String s = "... leads to: "; + if(coll.size()>1) + s = s + " Collection containing: "; + + if(coll.size() > 0) + s = s + Util.getProperty(coll.iterator().next(), "name");//+ coll); + + logger.info(s); +// if (coll instanceof Collection) +// { + if(coll != null) + { + //Collection c1 = (Collection) coll; + + //addModelElementsToScope(otherEnd, coll); + addModelElementToScope(otherEnd, m); + } +// else if (c1 instanceof ModelElement) +// { +// try +// { +// addModelElementToScope(otherEnd, m); +// } +// catch (Exception e) +// { +// ; +// } +// +// } + + } + else + { + + // +// if(m instanceof Association) +// { +// Association a = (Association) m; +// +// tryNavigateBackwards(otherEnd, end, a.getConnection(), maxDepth/1); +// +//// +//// Util.addAllSave(allElementsInNamespace, a.getConnection()); +// } + + +// logger.info("wrong type: " +// + m.getClass().getSimpleName() +// + " : " + m.getName()); + +// logger.info( +// "can't reach the ModelElement directly, " + +// "try to reach it in several hops..."); + + // but can try to reach the source ModelElement via + // more than one step + + MetaModelClass mmClass = helper.getMetaModelClass(m); + + if(mmClass != null && mmClass.getUmlClassName() != null) + { +// logger.info("...from: " +// + m.getClass().getSimpleName() +// + " : " +// + m.getNameA()); + + Collection associations = mmInfo.getInterResourceAssociations(mmClass); + + if(associations != null) + { + for (Iterator iter = associations.iterator(); iter.hasNext();) + { + InterResourceAssociation association = (InterResourceAssociation) iter.next(); + + + Object result = helper.navigateAssociation(m, association.getOtherEnd(mmClass)); + Collection coll; + if (result instanceof Collection) + { + coll = (Collection) result; + + } + else + { + coll = new LinkedList(); + coll.add(result); + } + + + visitedElements.addAll(coll); + + //tryNavigateBackwards(otherEnd, end, coll, maxDepth-1); + tryNavigateBackwards(otherEnd, end, coll, visitedElements); + } + } + + + } + + + } + } + } + } + + GenericDialectHelper helper = GenericDialectHelper.getInstance(); + +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/strategies/MappingScopeStrategy.java b/src/ch/ethz/infsec/secureumlgui/modelmapping/strategies/MappingScopeStrategy.java new file mode 100644 index 0000000..57df7fb --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/strategies/MappingScopeStrategy.java @@ -0,0 +1,36 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.modelmapping.strategies; + +import java.util.LinkedHashSet; +import java.util.Set; + +import org.omg.uml.foundation.core.ModelElement; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; + +/** + * + */ +public abstract class MappingScopeStrategy +{ + + /** Method returns a Collection containing all ModelElements + * that need to be mapped when analyzing Permissions on the + * ModelElement @param modelElement + * + * + * @param startingPoint The analyzed ModelElement + * @return All ModelElements that need to be mapped + */ + public Set getMappingScope(ModelElement startingPoint) + { + LinkedHashSet result = + new LinkedHashSet(); + + return result; + } + + + MultiContextLogger logger = MultiContextLogger.getDefault(); +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/strategies/SecureUmlMappingScopeStrategy.java b/src/ch/ethz/infsec/secureumlgui/modelmapping/strategies/SecureUmlMappingScopeStrategy.java new file mode 100644 index 0000000..59359fc --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/strategies/SecureUmlMappingScopeStrategy.java @@ -0,0 +1,55 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.modelmapping.strategies; + +import java.util.Collection; +import java.util.Iterator; +import java.util.Set; + +import org.argouml.model.Model; +import org.omg.uml.foundation.core.ModelElement; + + +/** + * + */ +public class SecureUmlMappingScopeStrategy + extends MappingScopeStrategy +{ + + /* (non-Javadoc) + * @see ch.ethz.infsec.secureumlgui.modelmapping.MappingScopeStrategy#getMappingScope(tudresden.ocl20.core.jmi.uml15.core.ModelElement) + */ + @Override + public Set getMappingScope( + ModelElement startingPoint) + { + //if(modelElement != null) + { + // TODO: search for the Roles / Permissions to lie in Namespaces, too + Set result = super.getMappingScope(startingPoint); + + //Collection elementsInNamespace = modelElement.getNamespace().getOwnedElement(); + + + // logger.info("There are " + elementsInNamespace.size() + // + " ModelElements in the Namespace where the Permissions / Roles lie"); + // + // for (Iterator iter = elementsInNamespace.iterator(); iter.hasNext();) + // { + // + // + // ModelElement m = (ModelElement) iter.next(); + // + // logger.info(" - " + m.getName()); + // + // } + + + return result; + } + //else return null; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/modelmapping/strategies/package.html b/src/ch/ethz/infsec/secureumlgui/modelmapping/strategies/package.html new file mode 100644 index 0000000..f1fd9ac --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/modelmapping/strategies/package.html @@ -0,0 +1,7 @@ + + + + +Strategies that calculate which elements have to be mapped. + + diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/SecureModelPackage.java b/src/ch/ethz/infsec/secureumlgui/securemodel/SecureModelPackage.java new file mode 100644 index 0000000..d3a11bd --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/SecureModelPackage.java @@ -0,0 +1,19 @@ +package ch.ethz.infsec.secureumlgui.securemodel; + +import javax.jmi.reflect.RefPackage; + +/** + * SecureModel package interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface SecureModelPackage extends RefPackage +{ + /** + * Returns nested package SecureUml. + * @return Proxy object related to nested package SecureUml. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.SecureUmlPackage getSecureUml(); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/ActionKind.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/ActionKind.java new file mode 100644 index 0000000..7a0c5b8 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/ActionKind.java @@ -0,0 +1,22 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel; + +/** + * + */ +public class ActionKind +{ + /** + * + */ + private ActionKind() + { + // TODO Auto-generated constructor stub + } + + public static ActionKind ATOMIC = new ActionKind(); + + public static ActionKind COMPOSITE= new ActionKind(); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/ActionResourceAssociation.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/ActionResourceAssociation.java new file mode 100644 index 0000000..419972c --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/ActionResourceAssociation.java @@ -0,0 +1,58 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel; + +/** + * + */ +public class ActionResourceAssociation extends MetaModelAssociation +{ + /** + * + */ + public ActionResourceAssociation(String shortName, ResourceType resourceType, ActionType actionType) + { + super(shortName); + + this.shortname = shortName; + this.resourceType = resourceType; + this.actionType = actionType; + } + + private String shortname; + + public String getShortname() + { + return shortname; + } + + public void setShortname(String name) + { + this.shortname = name; + } + + private ResourceType resourceType; + + public ResourceType getResourceType() + { + return resourceType; + } + + public void setResourceType(ResourceType resourceType) + { + this.resourceType = resourceType; + } + + private ActionType actionType; + + public ActionType getActionType() + { + return actionType; + } + + public void setActionType(ActionType actionType) + { + this.actionType = actionType; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/ActionType.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/ActionType.java new file mode 100644 index 0000000..941886d --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/ActionType.java @@ -0,0 +1,48 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel; + +/** + * + */ +public class ActionType extends MetaModelEntity +{ + /** + * + */ + protected ActionType() + { + + } + + private String shortName = null; + + public String getShortName() + { + return shortName; + } + + public void setShortName(String shortName) + { + this.shortName = shortName; + } + + private String subactionsDefinition = null; + + public String getSubactionsDefinition() + { + return subactionsDefinition; + } + + public void setSubactionsDefinition(String subactionsDefinition) + { + this.subactionsDefinition = subactionsDefinition; + } + + + public String toString() + { + return getShortName(); + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/AssociationEnd.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/AssociationEnd.java new file mode 100644 index 0000000..de0c792 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/AssociationEnd.java @@ -0,0 +1,127 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel; + +import ch.ethz.infsec.secureumlgui.Util; + +/** + * + */ +public class AssociationEnd extends MetaModelEntity +{ + public AssociationEnd() + { + + } + /** + * + */ + public AssociationEnd(String name) + { + this.setName(name); + } + + + private boolean multiple; + + public boolean isMultiple() + { + return multiple; + } + + public void setMultiple(boolean multiple) + { + this.multiple = multiple; + } + + private InterResourceAssociation owner; + + public InterResourceAssociation getOwner() + /** The Association the AssociationEnd belongs to + * + */ + { + return owner; + } + + public void setOwner(InterResourceAssociation association) + { + this.owner = association; + } + + + private MetaModelClass type; + + public MetaModelClass getType() + /** The Classifier the Association End + * is attached to + * + */ + { + return type; + } + + public void setType(MetaModelClass type) + { + this.type = type; + } + + private String umlPropertyGetter; + + public String getUmlPropertyGetter() + { + return umlPropertyGetter; + } + + public void setUmlPropertyGetter(String umlPropertyGetter) + { + this.umlPropertyGetter = umlPropertyGetter; + } + + + /** + * @return The name of the Getter Method of this AssociationName + * (for the SecureUML Model) + */ + public String getGetterName() + { + if(getName() != null && getName().length() > 0) + return "get" + Util.capitalize(getName()); + else + return null; + } + + /** + * @return The name of the Setter Method of this AssociationEnd + * (for the SecureUML Model) + */ + public String getSetterName() + { + if(isMultiple()) + // AssociationEnd is a Collection -> no Setter + return null; + else + return "set" + Util.capitalize(getName()); + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + String string = ""; + if(isMultiple()) + string = string + "(*)"; + else + string = string + "(1)"; + + string = string + + "(" + getName() + ") [" + + getUmlPropertyGetter() + + "]" ; + + return string; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/AtomicActionType.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/AtomicActionType.java new file mode 100644 index 0000000..9a3447a --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/AtomicActionType.java @@ -0,0 +1,12 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel; + +/** + * + */ +public class AtomicActionType extends ActionType +{ + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/CompositeActionType.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/CompositeActionType.java new file mode 100644 index 0000000..aec77ac --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/CompositeActionType.java @@ -0,0 +1,13 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel; + +/** + * + */ +public class CompositeActionType extends ActionType +{ + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/ContainmentAssociation.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/ContainmentAssociation.java new file mode 100644 index 0000000..1345975 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/ContainmentAssociation.java @@ -0,0 +1,73 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel; + +import java.util.ArrayList; +import java.util.Collection; + +/** + * + */ +@Deprecated +public class ContainmentAssociation extends InterResourceAssociation +{ + /** + * + */ + public ContainmentAssociation(String name, + AssociationEnd containerEnd, AssociationEnd contentsEnd) + { + super(name, containerEnd, contentsEnd); + + + this.setName(name); + + this.containerEnd = containerEnd; + this.contentsEnd = contentsEnd; + } + + private AssociationEnd containerEnd; + + public AssociationEnd getContainerEnd() + { + return containerEnd; + } + + public void setContainerEnd(AssociationEnd containerEnd) + { + this.containerEnd = containerEnd; + } + + private AssociationEnd contentsEnd; + + public AssociationEnd getContentsEnd() + { + return contentsEnd; + } + + public void setContentsType(AssociationEnd contentsEnd) + { + this.contentsEnd = contentsEnd; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + String string = + getContainerEnd().getType().getName() + + + getContainerEnd().toString() + + " ----" + + getName() + + "----> " + + getContentsEnd().toString() + + + getContentsEnd().getType().getName(); + + return string; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/DialectMetaModelInfo.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/DialectMetaModelInfo.java new file mode 100644 index 0000000..e562d3b --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/DialectMetaModelInfo.java @@ -0,0 +1,426 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; + +import javax.jmi.model.MofPackage; +import ch.ethz.infsec.secureumlgui.Util; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; + +/** + * + */ +public class DialectMetaModelInfo +{ + MultiContextLogger logger = MultiContextLogger.getDefault(); + + /* Invariants: + * - Collections are never null + * - for each ResourceType in resourceTypes, there is a Mapping + * in actionTypesOfResourceType with a non-null value (Collection) + */ + + + /** the name of the design modeling language (e.g., ComponentUML, ControllerUML). */ + private String dialectName = null; + + public String getDialectName() + { + return dialectName; + } + + public void setDialectName(String dialectName) + { + this.dialectName = dialectName; + } + + /** the extent in which dialect metamodel instances are stored. */ + private Object dialectExtent; + + public Object getDialectExtent() + { + if(dialectExtent==null) + logger.error("dialectExtent = null"); + return dialectExtent; + + } + + public void setDialectExtent(Object dialectExtent) + { + this.dialectExtent = dialectExtent; + } + + /** + * Get the dialectMetaExtent value. + * + * @return a MofPackage value + */ + public final MofPackage getDialectMetaExtent() { + return dialectMetaExtent; + } + + /** + * Set the dialectMetaExtent value. + * + * @param newDialectMetaExtent The new DialectMetaExtent value. + */ + public final void setDialectMetaExtent(final MofPackage newDialectMetaExtent) { + this.dialectMetaExtent = newDialectMetaExtent; + } + + /** + * The extent for the dialect metamodel. Use this as a parameter + * for MDRepository.createExtent() to create an instanc of the + * dialect metamodel. + */ + private MofPackage dialectMetaExtent; + + private Collection resourceTypes = new ArrayList(); + + public Collection getResourceTypes() + { + return resourceTypes; + } + + /** + * + */ + public ResourceType getResourceType(Object secureUmlElement) + { + if(secureUmlElement == null) + return null; + + + String umlClassName = secureUmlElement.getClass().getSimpleName(); + + for (ResourceType rt : resourceTypes) + { + if(umlClassName.indexOf('$') >= 0) + umlClassName = umlClassName.split("\\$")[0]; + + if(rt.getName().equals(umlClassName)) + return rt; + } + return null; + } + +// public void setResourceTypes(Collection resourceTypes) +// { +// this.resourceTypes = resourceTypes; +// } + + private Collection metaModelClasses = + new ArrayList(); + + public Collection getMetaModelClasses() + { + return metaModelClasses; + } +// public Collection getMappableMetaModelClasses() +// { +// Collection result = new LinkedList(); +// +// for (Iterator iter = metaModelClasses.iterator(); iter.hasNext();) +// { +// MetaModelClass m = (MetaModelClass) iter.next(); +// +// if(m.getUmlClassName() != null) +// result.add(m); +// } +// +// return result; +// } + + public Collection getResourceTypesAndMetaModelClasses() + { + Collection result = new LinkedList(); + Util.addAllSave(result, getMetaModelClasses()); + Util.addAllSave(result, resourceTypes); + + return result; + } + +// +// public void setMetaModelClasses(Collection metaModelClasses) +// { +// this.metaModelClasses = metaModelClasses; +// } + + private Collection actionTypes = new ArrayList(); + + public Collection getActionTypes() + { + return actionTypes; + } + +// public void setActionTypes(Collection actionTypes) +// { +// this.actionTypes = actionTypes; +// } + + private Collection atomicActionTypes = new ArrayList(); + + public Collection getAtomicActionTypes() + { + return atomicActionTypes; + } + +// public void setAtomicActionTypes(Collection atomicActionTypes) +// { +// this.atomicActionTypes = atomicActionTypes; +// } + + private Collection compositeActionTypes = new ArrayList(); + + public Collection getCompositeActionTypes() + { + return compositeActionTypes; + } + + + public ActionType getActionTypeByName(String name) + { + for (Iterator iter = actionTypes.iterator(); iter.hasNext();) + { + ActionType actiontype = (ActionType) iter.next(); + + if(actiontype.getName().equals(name)) + { + return actiontype; + } + } + logger.info("action type "+name+" not found in DialectMetaModelInfo"); + return null; + } + +// public void setCompositeActionTypes(Collection compositeActionTypes) +// { +// this.compositeActionTypes = compositeActionTypes; +// } + + private Map> actionAssociationsOfResourceType = new LinkedHashMap>(); + + public Collection getResourceActionAssociations(ResourceType resourceType) + { + return actionAssociationsOfResourceType.get(resourceType); + } + + public ResourceType getResourceTypeOfActionType(ActionType actionType) + { + return getResourceActionDependency(actionType).getResourceType(); + } + + private Map> + interResourceAssociationsByEntity = + new LinkedHashMap>(); + + + /** + * @return the interResourceAssociations + */ + public Collection getInterResourceAssociations(MetaModelClass metaModelClass) + { + if(metaModelClass == null) + return null; + + Set result = + interResourceAssociationsByEntity.get(metaModelClass); +// if(result == null) +// { +// result = new LinkedHashSet(); +// interResourceAssociationsByEntity.put(metaModelClass, result); +// } + + return result; + } + + /** + * @return all InterResourceAssociations + * - in a newly created Collection + * (copied references to all Values from + * the Map 'interResourceAssociationsByEntity') + */ + public Collection getInterResourceAssociations() + { + Collection interResourceAssociations = new LinkedList(); + + for (Iterator iter = interResourceAssociationsByEntity.keySet().iterator(); iter + .hasNext();) + { + MetaModelEntity key = (MetaModelEntity) iter.next(); + + Util.addAllSave(interResourceAssociations, interResourceAssociationsByEntity.get(key)); + } + + return interResourceAssociations; + } + + /** + * + * @param name + * @return the created InterResourceAssociation + */ + public InterResourceAssociation addInterResourceAssociation(String name, MetaModelEntity anchor1, MetaModelEntity anchor2) + { + //logger.info("Adding inter-resource Association: " + name); + AssociationEnd end1 = new AssociationEnd();//containerEndName); + AssociationEnd end2 = new AssociationEnd();//contentsEndName); + + + // Default values - valid for UMLClasses +// containerEnd.setUmlPropertyGetter("getOwner"); +// contentsEnd.setUmlPropertyGetter("getFeature"); + + InterResourceAssociation m = new InterResourceAssociation(name, end1, end2); + + // add mapping for anchor 1 + Set mas = interResourceAssociationsByEntity.get(anchor1); + + if(mas == null) + { + mas = new LinkedHashSet(); + interResourceAssociationsByEntity.put(anchor1, mas); + } + mas.add(m); + + // add mapping for anchor 2 + mas = interResourceAssociationsByEntity.get(anchor2); + if(mas == null) + { + mas = new LinkedHashSet(); + interResourceAssociationsByEntity.put(anchor2, mas); + } + mas.add(m); + + + + return m; + //logger.info("added ContainmentAssociation: " + name); + } + + + + +// public void setActionTypesOfResourceTypes(Collection actionTypesOfResourceType) +// { +// this.actionTypesOfResourceType = actionTypesOfResourceType; +// } + + private Map dependencyOfActionType = new LinkedHashMap(); + + + public ActionResourceAssociation getResourceActionDependency(ActionType actionType) + { + return dependencyOfActionType.get(actionType); + } + + public Collection getExplicitActionTypesOfResourceType(ResourceType resourceType) + { + Collection associations = getResourceActionAssociations(resourceType); + + Collection actionTypes = new ArrayList(); + + if(associations != null) + { + for (Iterator iter = associations.iterator(); iter.hasNext();) + { + ActionResourceAssociation dependency = (ActionResourceAssociation) iter.next(); + + actionTypes.add(dependency.getActionType()); + } + } + return actionTypes; + } + + /** returns all ActionTypes defined for the + * resourceType, including the ActionTypes + * inherited from its parent ResourceType + * + */ + public Collection getActionTypesOfResourceType(ResourceType resourceType) + { + Collection actionTypes = getExplicitActionTypesOfResourceType(resourceType); + + if(resourceType != null && resourceType.getParentResourceType() != null) + { + Collection inheritedActionTypes = + getActionTypesOfResourceType(resourceType.getParentResourceType()); + + actionTypes.addAll(inheritedActionTypes); + } + return actionTypes; + } + + public ActionType getActionType(ResourceType resourceType, String shortname) + { + Collection actionTypes = getActionTypesOfResourceType(resourceType); + + for (Iterator iter = actionTypes.iterator(); iter.hasNext();) + { + ActionType actionType = (ActionType) iter.next(); + if(actionType.getShortName().equals(shortname)) + return actionType; + } + return null; + } + + public void addResourceType(ResourceType r) + { + resourceTypes.add(r); + + actionAssociationsOfResourceType.put(r, new ArrayList()); + + //interResourceAssociationsByEntity.put(r, new LinkedHashSet()); + } + + public void addMetaModelClass(MetaModelClass c) + { + metaModelClasses.add(c); + + //actionAssociationsOfResourceType.put(c, new ArrayList()); + + interResourceAssociationsByEntity.put(c, new LinkedHashSet()); + } + + public void addAtomicActionType(AtomicActionType a) + { + atomicActionTypes.add(a); + + actionTypes.add(a); + } + + public void addCompositeActionType(CompositeActionType c) + { + compositeActionTypes.add(c); + + actionTypes.add(c); + } + + public void addResourceActionAssociation(String name, ResourceType r, ActionType a) + { + if(dependencyOfActionType.containsKey(a)) + { + logger.warn("Overwriting existing ResourceActionDependency!"); + } + + ActionResourceAssociation dependency = new ActionResourceAssociation(name, r, a); + + dependencyOfActionType.put(a, dependency); + + actionAssociationsOfResourceType.get(r).add(dependency); + } + + + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/InterResourceAssociation.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/InterResourceAssociation.java new file mode 100644 index 0000000..62367f0 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/InterResourceAssociation.java @@ -0,0 +1,87 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel; + +/** + * + */ +public class InterResourceAssociation extends MetaModelAssociation +{ + /** + * + */ + public InterResourceAssociation(String name, AssociationEnd end1, AssociationEnd end2) + { + super(name); + + this.end1 = end1; + this.end2 = end2; + + end1.setOwner(this); + end2.setOwner(this); + + } + + + + private AssociationEnd end1; + + public AssociationEnd getEnd1() + { + return end1; + } + + public void setEnd1(AssociationEnd end1) + { + this.end1 = end1; + end1.setOwner(this); + } + + private AssociationEnd end2; + + public AssociationEnd getEnd2() + { + return end2; + } + + public void setEnd2(AssociationEnd end2) + { + this.end2 = end2; + end2.setOwner(this); + } + + /** + * + * @param mmClass + * @return the Association End which is + * not associated to mmEntity or 'null' if + * mmEntity is not an anchor of this Association + */ + public AssociationEnd getOtherEnd(MetaModelClass mmClass) + { + if(end1.getType() == mmClass) + return end2; + else if(end2.getType() == mmClass) + return end1; + else + return null; + } + + public String toString() + { + String string = + getEnd1().getType().getName() + + + getEnd1().toString() + + " ----" + + getName() + + "---- " + + getEnd2().toString() + + + getEnd2().getType().getName(); + + return string; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelAssociation.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelAssociation.java new file mode 100644 index 0000000..354c683 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelAssociation.java @@ -0,0 +1,19 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel; + +/** + * + */ +public class MetaModelAssociation extends MetaModelEntity +{ + /** + * + */ + public MetaModelAssociation(String name) + { + super(name); + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelClass.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelClass.java new file mode 100644 index 0000000..31dd639 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelClass.java @@ -0,0 +1,68 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; + +/** + * A Metamodel Class which corresponds t an UML Class + * + * the corresponding UMLClass needs to be specified in the + * Metamodel by the Tag 'umlClassName' + * + * + */ +public class MetaModelClass extends MetaModelEntity +{ + + private String umlClassName; + + public String getUmlClassName() + { + return umlClassName; + } + + public void setUmlClassName(String umlClassName) + { + this.umlClassName = umlClassName; + } + + private Collection attributes = + new LinkedList(); + + public Collection getAttributes() + { + return attributes; + } + +// public void setAttributes(Collection attributes) +// { +// this.attributes = attributes; +// } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + String resourceString = getName(); + + resourceString = resourceString + + "\n umlClassName: " + getUmlClassName(); + + resourceString = resourceString + "\n Attributes: \n"; + for (Iterator iter = getAttributes().iterator(); iter.hasNext();) + { + MetaModelClassAttribute rta = (MetaModelClassAttribute) iter.next(); + + resourceString = resourceString + " - " + rta.toString() + "\n"; + } + + return resourceString; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelClassAttribute.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelClassAttribute.java new file mode 100644 index 0000000..98ad504 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelClassAttribute.java @@ -0,0 +1,91 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel; + +import ch.ethz.infsec.secureumlgui.Util; + + + +/** + * + */ +public class MetaModelClassAttribute extends MetaModelEntity +{ + /** + * + */ + public MetaModelClassAttribute(String name) + { + super(name); + } + +// /** +// * @return The name of the Getter Method of this Attribute +// */ +// public String getUmlGetterName() +// { +// String getterPrefix; +// if(getTypeName().equals(MetaModelConst.TYPE_NAME_BOOLEAN)) +// { +// getterPrefix = "is"; +// } +// else +// { +// getterPrefix = "get"; +// } +// if(getUmlName() != null && getUmlName().length() > 0) +// return getterPrefix + Util.capitalize(getUmlName()); +// else if(getName() != null && getName().length() > 0) +// return getterPrefix + Util.capitalize(getName()); +// else +// return null; +// } +// /** +// * @return The name of the Setter Method of this Attribute +// */ +// public String getSetterName() +// { +// return "set" + Util.capitalize(getName()); +// } + + private String umlName; + + public String getUmlName() + { + return umlName; + } + + public void setUmlName(String umlName) + { + this.umlName = umlName; + } + + + private String typeName; + + /** Name of the Type of the Attribute (e.g. 'String') + * + * @return the name of the type of the attribute + */ + public String getTypeName() + { + return typeName; + } + + public void setTypeName(String typeName) + { + this.typeName = typeName; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + return getName() + " : " + getTypeName(); + + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelConst.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelConst.java new file mode 100644 index 0000000..d6a5728 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelConst.java @@ -0,0 +1,50 @@ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel; + +/** + * mainly contains names for tagged values that define the concrete + * syntax of a dialect metamodel. + * + * + */ +public class MetaModelConst +{ + public final static String TAG_METAMODEL = "metamodel"; + + public final static String TAG_MODELELEMENT_STEREOTYPE = + "modelElementStereotype"; + + public final static String TAG_ANCHOR_PATH = + "anchorPath"; + + public final static String TAG_ACTION_STEREOTYPE = + "actionStereotype"; + + + public final static String TAG_UML_PROPERTY_GETTER = + "umlPropertyGetter"; + + public final static String TAG_UML_CLASS_NAME = + "umlClassName"; + + public final static String TAG_RESOURCE_PATH = + "resourcePath"; + + public final static String TAG_ATTRIBUTE_UML_PROPERTY_NAME = + "umlPropertyName"; + + public final static String TAG_COMPOSITE_ACTION_SUBACTIONS_DEFINITION = + "subactionsDefinition"; + + public static final String TAG_SHORTNAME = "shortname"; + + public final static String SELF_PATH = "self"; + + public final static String MDR_IMPL_SUFFIX = "$Impl"; + public final static String MDR_IMPL_SUFFIX_REGEXP = "\\$Impl"; + + public final static String ROLE_CLASS_NAME = "Role"; + + public final static String TYPE_NAME_BOOLEAN = "Boolean"; + +} + diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelEntity.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelEntity.java new file mode 100644 index 0000000..c97564a --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelEntity.java @@ -0,0 +1,40 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel; + +/** + * + */ +public class MetaModelEntity +{ + /** + * + */ + public MetaModelEntity() + { + + } + + /** + * + */ + public MetaModelEntity(String name) + { + this.name = name; + } + + + private String name; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelFactory.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelFactory.java new file mode 100644 index 0000000..a420026 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/MetaModelFactory.java @@ -0,0 +1,52 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel; + +/** + * + */ +public class MetaModelFactory +{ + /** + * + */ + private MetaModelFactory() + { + + } + + private static MetaModelFactory instance; + + public static MetaModelFactory getInstance() + { + if(instance == null) + instance = new MetaModelFactory(); + + + return instance; + } + + +// public ActionType createActionType(ActionKind actionKind) +// { +// if(actionKind == ActionKind.ATOMIC) +// return new AtomicActionType(); +// else if(actionKind == ActionKind.COMPOSITE) +// return new CompositeActionType(); +// +// +// else return null; +// } + + public AtomicActionType createAtomicActionType() + { + return new AtomicActionType(); + } + + public CompositeActionType createCompositeActionType() + { + return new CompositeActionType(); + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/ResourceType.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/ResourceType.java new file mode 100644 index 0000000..1e75c21 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/ResourceType.java @@ -0,0 +1,109 @@ +/** +* +*/ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; + + +/** + * + */ +public class ResourceType extends MetaModelClass +{ + /* ResourceType is directly derived from the SecureUML + * Class "Resource" <==> parentResourceType == null */ + private ResourceType parentResourceType; + + public ResourceType getParentResourceType() + { + return parentResourceType; + } + + public void setParentResourceType(ResourceType parentResourceType) + { + this.parentResourceType = parentResourceType; + } + + private String modelElementStereotype; + + public String getModelElementStereotype() + { + return modelElementStereotype; + } + + public void setModelElementStereotype(String anchorStereotype) + { + this.modelElementStereotype = anchorStereotype; + } + + private String anchorPath; + + public String getAnchorPath() + { + return anchorPath; + } + + public void setAnchorPath(String anchorPath) + { + this.anchorPath = anchorPath; + } + + private String actionStereotype; + + public String getActionStereotype() + { + return actionStereotype; + } + + public void setActionStereotype(String actionStereotype) + { + this.actionStereotype = actionStereotype; + } + + private String resourcePath; + + public String getResoucePath() + { + return resourcePath; + } + + public void setResoucePath(String resourcePath) + { + this.resourcePath = resourcePath; + } + + + + public String toString() + { + String resourceString = this.getName(); + if(this.getParentResourceType() != null) + { + resourceString = resourceString + + " inherit " + + this.getParentResourceType().getName(); + } + resourceString = resourceString + + "\n Tags: " + + "\n umlClassName: " + getUmlClassName() + + "\n modelelementStereotype: " + getModelElementStereotype() + + "\n anchorPath: " + getAnchorPath() + + "\n actionStereotype: " + getActionStereotype() + + "\n resourcePath: " + getResoucePath(); + + + resourceString = resourceString + "\n Attributes:"; + for (Iterator iter = getAttributes().iterator(); iter.hasNext();) + { + MetaModelClassAttribute rta = (MetaModelClassAttribute) iter.next(); + + resourceString = resourceString + "\n - " + rta.toString(); + } + + return resourceString; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/TaggedValue.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/TaggedValue.java new file mode 100644 index 0000000..1914ca7 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/TaggedValue.java @@ -0,0 +1,44 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel; + +/** + * + */ +public class TaggedValue extends MetaModelEntity +{ + /** + * + */ + public TaggedValue(String name, String value) + { + this.name = name; + this.value = value; + } + + private String name; + + public String getName() + { + return name; + } + + public void setName(String name) + { + this.name = name; + } + + private String value; + + public String getValue() + { + return value; + } + + public void setValue(String value) + { + this.value = value; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/package.html b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/package.html new file mode 100644 index 0000000..9c7eb54 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/metamodel/package.html @@ -0,0 +1,8 @@ + + + + + +Represents the information in a SecureUML dialect metamodel. + + diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/DialectMetaModelAnalyzer.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/DialectMetaModelAnalyzer.java new file mode 100644 index 0000000..fc73967 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/DialectMetaModelAnalyzer.java @@ -0,0 +1,1587 @@ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser; + +import java.io.File; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; + +import javax.jmi.model.Association; +import javax.jmi.model.AssociationEnd; +import javax.jmi.model.Attribute; +import javax.jmi.model.Classifier; +import javax.jmi.model.Import; +import javax.jmi.model.ModelElement; +import javax.jmi.model.MofClass; +import javax.jmi.model.MofPackage; +import javax.jmi.model.Namespace; +import javax.jmi.model.Tag; +import javax.jmi.reflect.RefPackage; + +import org.apache.log4j.Logger; +import org.omg.uml.foundation.core.Stereotype; + +//import ch.ethz.infsec.secureumlgui.GenericDialectTester; +import ch.ethz.infsec.secureumlgui.Util; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ActionType; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.AtomicActionType; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.CompositeActionType; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.DialectMetaModelInfo; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.InterResourceAssociation; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.MetaModelClass; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.MetaModelClassAttribute; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.MetaModelConst; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.MetaModelEntity; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.MetaModelFactory; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ResourceType; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.TaggedValue; +import ch.ethz.infsec.secureumlgui.logging.LoggerContext; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.modelmanagement.ModelConst; +//import ch.ethz.infsec.secureumlgui.modelmapping.Util; +import ch.ethz.infsec.secureumlgui.transformation.MetaModelMap; +import ch.ethz.infsec.secureumlgui.wrapper.AttributeWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.ModelElementWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.MofClassWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.MofPackageWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.NamedModelElementWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.RefPackageWrapper; + +/** + * Analyzes a dialect metamodel. + * + */ +public class DialectMetaModelAnalyzer +{ + + + /** + * + */ + public DialectMetaModelAnalyzer( + Object dialectMetamodelPackage) + { + this.dialectMetamodelPackage = dialectMetamodelPackage; + } + + + MultiContextLogger logger = MultiContextLogger.getDefault(); + public static LoggerContext metamodelExamination = new LoggerContext("Examination of Metamodel Elements and Associations", " MetamodelExamination"); + public static LoggerContext metamodelValidation = new LoggerContext("Validation of Metamodel Structure and needed Elements", " MetamodelValidation"); + + File xmiFile; + + String metaModelName = "MOF14"; + // String metaModelName = tudresden.ocl20.core.MetaModelConst.MOF14; + + MetaModelMap modelmap = MetaModelMap.getDefault(); + + + /** the (SecureModel) package containing the dialect metamodel */ + Object dialectMetamodelPackage = null; + + MofPackageWrapper topPkg = null; + + MofPackageWrapper secureUmlPackageWrapper = null; + Object secureUmlPackage = null; + + private static Logger aLog = Logger.getLogger(DialectMetaModelAnalyzer.class); + + public String prefix = "-"; + + // Helper method. move somewhere else? + public MofClassWrapper findMofClassByName(MofPackageWrapper mofPackageWrapper, String name) + { + if(mofPackageWrapper == null || name == null) { + aLog.debug("findMofClassByName: wrapper or name == null"); + return null; + } + + //name = name;// + "Class"; + try + { + Collection elements = mofPackageWrapper.getContents(); + + aLog.debug("searching Class '" + name + "' among " + elements.size() + " Elements ... "); + +// logger.info(metamodelValidation, "searching Class '" +// + name + "' among " +// + elements.size() + " Elements ... "); + + Iterator it = elements.iterator(); + while(it.hasNext()) + { + Object me = (Object) it.next(); + NamedModelElementWrapper meWrapper = + new NamedModelElementWrapper(me); + + //if (Util.hasType(me, "MofClass"))//(me instanceof MofClass) + //{ + String meName = meWrapper.getName(); + //me.getClass().getSimpleName(); + + meName = meName.split(MetaModelConst.MDR_IMPL_SUFFIX_REGEXP)[0]; + + //Util.getProperty(me, "name").toString(); + try + { + + if(name.equals(meName)) + //((MofClass)me).getName().equals(name)) + { + Object resource = me; + aLog.debug( "found Class: "+name); + //logger.info(metamodelValidation, "found Class: "+name); + return new MofClassWrapper(resource); + } + else + { +// logger.error(metamodelValidation, " ! " +// + meName); + } + } + catch (Exception e) + { + + } + + + //} +// else +// { +// //logger.info("... not: " + me.getNameA()); +// } + } + } + catch (Exception e) + { + logger.logException(e); + aLog.error(e); + } + return null; + } + + // Helper method. move somewhere else? + public MofClass findMofClassByNamePart(MofPackageWrapper secureUmlPackage, String namePart) + { + try + { + Collection elements = secureUmlPackage.getContents(); + + aLog.debug("searching Class *" + namePart + "* among " + + elements.size() + " Elements ... "); + + logger.info("searching Class *" + namePart + "* among " + + elements.size() + " Elements ... "); + + Iterator it = elements.iterator(); + while(it.hasNext()) + { + ModelElement me = (ModelElement) it.next(); + + if(me instanceof MofClass) + { + if(((MofClass)me).getName().toLowerCase().contains(namePart.toLowerCase())) + { + MofClass resource = (MofClass)me; + + logger.info("... " + + me.getName() + " found"); + return resource; + } + + } + else + { + //logger.info("... not: " + me.getNameA()); + } + } + } + catch (Exception e) + { + logger.logException(e); + } + return null; + } + + + // moved to 'examineMetamodelClasses' +// public Package findPackageBySubstring(Package startPackage, String namePart) +// { +// try +// +// { +// Collection elements = startPackage.getOwnedElement(); +// +// logger.info("searching Package *" + namePart + "* among " +// + elements.size() + " Elements ... "); +// +// Iterator it = elements.iterator(); +// while(it.hasNext()) +// { +// ModelElement me = (ModelElement) it.next(); +// +// if(me instanceof Package) +// { +// Package p = (Package)me; +// logger.info("(" + p.getName() +")"); +// +// String packageName = p.getName().toLowerCase(); +// namePart = namePart.toLowerCase(); +// if(packageName.indexOf(namePart) != -1) +// { +// logger.info("... found: " + p.getName() + "/" + p.getNameA()); +// return p; +// +// } +// else +// return findPackageBySubstring(p, namePart); +// } +// } +// } +// catch (Exception e) +// { +// logger.logException(e); +// } +// return null; +// } + + + DialectMetaModelInfo mmInfo = null; + + + MofClassWrapper resourceMofClassWrapper = null; + MofClassWrapper atomicActionMofClassWrapper = null; + MofClassWrapper compositeActionMofClassWrapper = null; + Object secureModelPackage = null; + MofPackageWrapper secureModelPackageWrapper = null; +// Object dialectPackage = null; +// RefPackageWrapper dialectPackageWrapper = null; + Object dialectDialectPackage = null; + MofPackageWrapper dialectDialectPackageWrapper = null; + Stereotype StereotypeSecumlAction = null; + + public DialectMetaModelInfo analyzeDialect(Object startPackage) + { + MofPackageWrapper startPackageWrapper = + new MofPackageWrapper(startPackage); + + // logger.info(metamodelExamination,"Analyzing Dialect Metamodel in Package: " + // + startPackageWrapper.getName()); + //startPackage.getClass().getSimpleName()); + + boolean found = findDialectPackages(startPackageWrapper); + + if(found) // found + { + + found = findSecureUmlClasses(); + + if(found) + { + mmInfo = new DialectMetaModelInfo(); + //MofPackage mp; mp.getName() + String s = dialectDialectPackageWrapper.getName(); + //dialectDialectPackage.getClass().getSimpleName(); + s = s.split(MetaModelConst.MDR_IMPL_SUFFIX)[0]; + s = s.split(ModelConst.DIALECT_PACKAGE_SUFFIX)[0]; + + mmInfo.setDialectName(s); + //s.substring(0, s.length() - ModelConst.DIALECT_PACKAGE_SUFFIX.length())); + + // logger.info(metamodelExamination,"Dialect Name: " + mmInfo.getDialectName()); + + //examineMetamodel(startPackage); + examineMetamodel(secureModelPackageWrapper); + } + // Collection actionTypes = new LinkedList(); + // + // actionTypes.addAll(mmInfo.getAtomicActionTypes()); + // actionTypes.addAll(mmInfo.getCompositeActionTypes()); + // + + // printResourcesTypes(mmInfo.getResourceTypes()); + // + // printActionsTypes(mmInfo.getActionTypes()); + + + return mmInfo; + } + else + return null; + } + + /** + * + */ + private boolean findSecureUmlClasses() + { + boolean found = true; + + resourceMofClassWrapper = findMofClassByName(secureUmlPackageWrapper, ModelConst.SECUREUML_RESOURCE_NAME); + found = found && + ensureModelElementExistance(resourceMofClassWrapper); + + //MofClass actionMofClass = findMofClassByName(secureUmlPackage, ModelConst.SECUREUML_ACTION_NAME); + atomicActionMofClassWrapper = findMofClassByName(secureUmlPackageWrapper, ModelConst.SECUREUML_ATOMIC_ACTION_NAME); + found = found && + ensureModelElementExistance(atomicActionMofClassWrapper); + + compositeActionMofClassWrapper = findMofClassByName(secureUmlPackageWrapper, ModelConst.SECUREUML_COMPOSITE_ACTION_NAME); + found = found && + ensureModelElementExistance(compositeActionMofClassWrapper); + + return found; + } + + /** + * @param startPackage + */ + private boolean findDialectPackages(MofPackageWrapper startPackage) + { + boolean result = true; + + secureUmlPackage = findPackage(startPackage, ModelConst.SECUREUML_PACKAGE_NAME); + result = result && ensureModelElementExistance( + secureUmlPackage);//Wrapper.getModelElement()); + secureUmlPackageWrapper = new MofPackageWrapper(secureUmlPackage); + + + dialectDialectPackage = findPackage(startPackage, ModelConst.DIALECT_PACKAGE_NAME_PART); + result = result && ensureModelElementExistance( + dialectDialectPackage); + + dialectDialectPackageWrapper = new MofPackageWrapper(dialectDialectPackage); + + String dialectName = dialectDialectPackageWrapper.getName(); + dialectName = dialectName.split(MetaModelConst.MDR_IMPL_SUFFIX)[0]; + dialectName = dialectName.split(ModelConst.DIALECT_PACKAGE_SUFFIX)[0]; + // now, e.g. name = "ComponentUml" + +// dialectPackage = findPackage(startPackage, dialectName); +// result = result && ensureModelElementExistance( +// dialectDialectPackage); +// +// dialectPackageWrapper = new RefPackageWrapper(dialectDialectPackage); +// +// dialectPackage = ((RefPackage)dialectDialectPackage).refOutermostPackage(); +// dialectPackageWrapper = new RefPackageWrapper(dialectPackage); +// logger.info("DialectDialectPackage.refOutermostPackage: " +// + dialectPackageWrapper.getName()); + + secureModelPackage = findPackage(startPackage, ModelConst.SECUREMODEL_PACKAGE_NAME); + if(secureModelPackage == null) + { + secureModelPackage = + ((RefPackage)dialectDialectPackage).refOutermostPackage(); + //dialectPackageWrapper.getContainer(); + + } + + secureModelPackageWrapper = new MofPackageWrapper(secureModelPackage); + // logger.info(metamodelValidation,"found Package: " + // + secureModelPackageWrapper.getName()); + +// result = result && ensureModelElementExistance( +// secureModelPackage);//Wrapper.getModelElement()); +// + return result; + } + + private boolean ensureModelElementExistance(Object modelElement) + //throws Exception + { + if(modelElement == null || + (modelElement instanceof ModelElementWrapper + && ((ModelElementWrapper) + modelElement).getModelElement() == null)) + { + logger.error(metamodelValidation, + "... NOT found - this ModelElement needs to exist in the Dialect Metamodel! exiting..."); + //System.exit(0); + return false; + } + else + return true; + } + + /** + * @param startPackage + */ + private void examineMetamodel(MofPackageWrapper startPackage) + { + // workaround for a bug at unknown location + if(startPackage.getModelElement() + instanceof MofPackageWrapper) + startPackage = (MofPackageWrapper) + startPackage.getModelElement(); + + Collection actionResourceAssociations + = new LinkedList(); + Collection otherAssociations + = new LinkedList(); + + examineMetamodelElements(startPackage, mmInfo, actionResourceAssociations, otherAssociations); + + //logger.info(metamodelExamination,"Examining Metamodel Associations in Package: " + startPackage.getName()); + examineMetamodelAssociations(actionResourceAssociations, otherAssociations, mmInfo); + + examineMofClassTags(mmInfo); + } + + public boolean inheritsDirectlyFrom(Object mofClass, Object parentClass) + { + Object parent = null; + try + { + Collection parents = (Collection) + Util.getProperty(mofClass, "supertypes"); + parent = parents.iterator().next(); + //getParents().get(0); + } + catch (Exception e) + { + logger.logException(e); + } + + if(parent!= null && parent == parentClass) + { + return true; + } + else + { + return false; + } + } + + public boolean inheritsFrom(MofClassWrapper mofClassWrapper, MofClassWrapper parentClassWrapper) + { + MofClassWrapper currentClassWrapper = mofClassWrapper; + MofClassWrapper firstParentWrapper = null; + + + + String parentClassName = parentClassWrapper.getName(); + //Util.getProperty(parentClassWrapper, "name").toString(); + String mofClassName = mofClassWrapper.getName(); + + do + { + try + { + /* Note: getParents() and getSuperTypes() + * both return the superClasses of a MofClass + */ + Collection parents = (Collection) + currentClassWrapper.getSupertypes(); + //.getSupertypes().get(0); + //Collection supertypes = currentClass.getSupertypes(); + + if(parents != null && parents.size() > 0 ) + firstParentWrapper = new MofClassWrapper( + parents.iterator().next()); + else + { + //firstParent = null; + break; + } + //MofClass firstSupertype = (MofClass) supertypes.iterator().next(); + + String firstParentName = firstParentWrapper.getName(); + //String firstSupertypeString = firstSupertype.getName(); + // logger.info(metamodelExamination, + // "first Parent of '" + mofClassName + // + "' is: '" + firstParentName); + + + // In case of Single Inheritance, there is only one Parent + + if(parents.contains(parentClassWrapper.getModelElement())) + // || supertypes.contains(parentClass)) +// parent = (MofClass) currentClass.getParents().get(0); +// if(parent!= null +// && parent != currentClass +// && parent == parentClass) + { + return true; + } + else + { + currentClassWrapper = firstParentWrapper; + } + + } + catch (Exception e) + { + logger.logException(e); + } + } + while(firstParentWrapper != null); + + return false; + } + + + /* Traverses all the UML-Classes in the Metamodel-Package, + * extracts the Resource-Types, Action-Types, + * needed Stereotypes and the Dialect Package + * and stores these to the MetaModelInfo Instance passed as Argument mmInfo + */ + public void examineMetamodelElements(MofPackageWrapper startPackage, DialectMetaModelInfo mmInfo, Collection actionResourceAssociations, Collection otherAssociations) + { + // logger.info(metamodelExamination, + // "Examining Metamodel Elements in Package: " + // + startPackage.getName()); + + Iterator it = startPackage.getContents().iterator(); + + while(it.hasNext()) + { + try + { + Object item = it.next(); + //logger.info(" - " + item); + + Object me = (Object) item ; + + NamedModelElementWrapper meWrapper = new NamedModelElementWrapper(me); + + + if ( Util.hasType(me, "Association")) + { + // logger.info(metamodelExamination, + // "Association: " + meWrapper.getName() + " found"); + + Association association = (Association) me; + + if(meWrapper.getName().startsWith(ModelConst.ACTION_RESOURCE_ASSOCIATION_NAME)) + { + actionResourceAssociations.add(association); + } + else + { + otherAssociations.add(association); + } + // not of interest here + } +// // Stereotypes don't exist in MOF Model +// else if (me instanceof Stereotype) +// { +// +// logger.info("STEREOTYPE found: " + me.getNameA()); +// if(me.getNameA().equals(ModelConst.STEREOTYPE_SECUML_ACTION)) +// { +// StereotypeSecumlAction = (Stereotype) me; +// logger.info("Stereotype: "+ ModelConst.STEREOTYPE_SECUML_ACTION + " found"); +// } +// } + else if (Util.hasType(me, "MofClass")) + //( me instanceof MofClass ) + { + // logger.info(metamodelExamination, + // "MofClass: " + meWrapper.getName() + " found"); + + Object mofClass = me; + + MofClassWrapper mofClassWrapper = new MofClassWrapper(me); + + //mofClass.allSupertypes() + + //String name = mofClass.getNameA(); + + if(inheritsFrom(mofClassWrapper, this.resourceMofClassWrapper)) + { + if(mofClassWrapper.isAbstract()) + logger.info(metamodelExamination, + "Abstract Resource Class found: " + + mofClassWrapper.getName() + + " (-> don't create ResourceType)"); + else + { + ResourceType resourcetype = parseResourceTypeClass(mofClassWrapper); + + // todo: extract method and set parentResourceType Property + + mmInfo.addResourceType(resourcetype); + } + } + else if(inheritsFrom(mofClassWrapper, this.atomicActionMofClassWrapper)) + { + AtomicActionType actiontype = MetaModelFactory.getInstance(). + createAtomicActionType(); + actiontype.setName(mofClassWrapper.getName()); + + modelmap.put(mofClassWrapper.getModelElement(), actiontype); + + mmInfo.addAtomicActionType(actiontype); + } + else if(inheritsFrom( + mofClassWrapper, + this.compositeActionMofClassWrapper)) + { + CompositeActionType actiontype = MetaModelFactory.getInstance(). + createCompositeActionType(); + actiontype.setName(mofClassWrapper.getName()); + + modelmap.put(mofClassWrapper.getModelElement(), actiontype); + + mmInfo.addCompositeActionType(actiontype); + } + else + { + MetaModelClass metaModelClass = new MetaModelClass(); + initMetaModelClass(mofClassWrapper, metaModelClass); + + modelmap.put(mofClassWrapper.getModelElement(), metaModelClass); + + mmInfo.addMetaModelClass(metaModelClass); + } + //newNode = caseClassifier( (Classifier) me); + } + else if (Util.hasType(me, "Tag")) + //(me instanceof Tag) + { + Tag tag = (Tag) me; + + String name = tag.getName(); + String value = (String) tag.getValues().get(0); + + TaggedValue taggedValue = new TaggedValue(name, value); + + // logger.info(metamodelExamination, + // "Tag found: " + name + " -> " + value); + + modelmap.put(tag, taggedValue); + + + Collection elements = tag.getElements(); + + + for (Iterator iter = elements.iterator(); iter.hasNext();) + { + Object element = (Object) iter.next(); + + if(element instanceof ModelElement) + modelmap.putModelElementTaggedValue((ModelElement)element, taggedValue); + +// if(element instanceof ModelElement) +// modelmap.putModelElementTag((ModelElement)element, tag); + +// if (element instanceof Association) +// { +// Association association = (Association) element; +// +// modelmap.putAssociationTag(association, tag); +// } +// else if (element instanceof AssociationEnd) +// { +// AssociationEnd associationEnd = +// (AssociationEnd) element; +// +// modelmap.putAssociationEndTag(associationEnd, tag); +// } +// else if (element instanceof MofClass) +// { +// MofClass mofClass = (MofClass) element; +// modelmap.putMofClassTag((MofClass)element, tag); +// } + } + } + else if (Util.hasType(me, "MofPackage")) + //( me instanceof RefPackage ) + { + try + { + MofPackage p = (MofPackage)me; + + //String packageName = p.getName().toLowerCase(); + //String namePart = ModelConst.DIALECT_PACKAGE_NAME_PART; + +// // if dialectPackage not found yet && ... +// if(mmInfo.getDialectName() == null && +// packageName.indexOf(namePart) != -1) +// { +// logger.info("Dialect Package found: " + p.getName()); +// mmInfo.setDialectName(p.getName()); +// } + } + catch (Exception e) + { + e.printStackTrace(); + } + examineMetamodelElements( + new MofPackageWrapper((MofPackage)me), + mmInfo, + actionResourceAssociations, + otherAssociations); + } + else + { + //newNode = new DefaultMutableTreeNode("[???] " + me.getNameA() + " (" + me.getClass().getName() + ")"); + //logger.info(me.getNameA() + " skipped"); + } + } + catch (Exception e) + { + // TODO: handle exception + e.printStackTrace(); + } + } + } + + private void examineMofClassTags(DialectMetaModelInfo mmInfo) + { + try + { + //logger.info("### examining Tags of " + mmInfo.getResourceTypes().size() + " ResourceTypes"); + for (Iterator iter = mmInfo.getResourceTypesAndMetaModelClasses().iterator(); iter.hasNext();) + { + try + { + MetaModelClass metaModelClass = (MetaModelClass) iter.next(); + + if(!modelmap.containsReverseMapping(metaModelClass)) + continue; + + // logger.info(metamodelExamination, + // "### examining Tags of " + metaModelClass.getName()); + + + MofClass metaModelClassMofClass = (MofClass) modelmap.getMofElement(metaModelClass); + + Collection tags = + modelmap.getModelElementTaggedValues(metaModelClassMofClass); + //modelmap.getMofClassTags(resourceTypeClass); + + if(tags == null) + continue; + // else + + for (Iterator iterator = metaModelClass.getAttributes().iterator(); iterator + .hasNext();) + { + MetaModelClassAttribute rta = (MetaModelClassAttribute) iterator.next(); + + Collection attributeTags = + modelmap.getModelElementTaggedValues(metaModelClassMofClass); + + for (Iterator it = attributeTags.iterator(); it.hasNext();) + { + TaggedValue taggedValue = (TaggedValue) it.next(); + + String name = taggedValue.getName(); + String value = taggedValue.getValue().toString(); + + if(MetaModelConst.TAG_ATTRIBUTE_UML_PROPERTY_NAME.equals(name)) + { + rta.setUmlName(value); + //rta.setTypeName(typeName) + logger.info("found MMClass Attribute Tag with UML Property Name: " + value); + } + + } + + } + + + for (Iterator iterator = tags.iterator(); iterator.hasNext();) + { + TaggedValue taggedValue = (TaggedValue) iterator.next(); + + String name = taggedValue.getName(); + String value = taggedValue.getValue().toString(); + + if(name.equals(MetaModelConst.TAG_UML_CLASS_NAME)) + { + metaModelClass.setUmlClassName(value); + } + + if (metaModelClass instanceof ResourceType) + { + ResourceType resourceType = (ResourceType) metaModelClass; + + if(name.equals(MetaModelConst.TAG_ACTION_STEREOTYPE)) + { + resourceType.setActionStereotype(value); + } + else if(name.equals(MetaModelConst.TAG_ANCHOR_PATH)) + { + resourceType.setAnchorPath(value); + } + else if(name.equals(MetaModelConst.TAG_MODELELEMENT_STEREOTYPE)) + { + resourceType.setModelElementStereotype(value); + } + else if(name.equals(MetaModelConst.TAG_RESOURCE_PATH)) + { + resourceType.setResoucePath(value); + } + } + } + + } + catch (Exception e) + { + e.printStackTrace(); + //logger.logException(e); + } + } + + for (Iterator iter = mmInfo.getActionTypes().iterator(); iter.hasNext();) + { + ActionType actiontype = (ActionType) iter.next(); + + MofClass actiontypeMofClass = (MofClass) modelmap.getMofElement(actiontype); + + + TaggedValue subactionsDefinitionTag = + modelmap.getModelElementTaggedValue( + actiontypeMofClass, + MetaModelConst.TAG_COMPOSITE_ACTION_SUBACTIONS_DEFINITION); + if(subactionsDefinitionTag != null && actiontype instanceof CompositeActionType) + { + CompositeActionType compositeActiontype = + (CompositeActionType) actiontype; + String oclExpression = subactionsDefinitionTag.getValue(); + compositeActiontype.setSubactionsDefinition(oclExpression); + } + } + } + catch (Exception e) + { + e.printStackTrace(); + } + } + + + /** + * @param mofClassWrapper + * @return the resource type + */ + private ResourceType parseResourceTypeClass(MofClassWrapper mofClassWrapper) + { + ResourceType resourcetype = new ResourceType(); + + + initMetaModelClass(mofClassWrapper, resourcetype); + + + modelmap.put(mofClassWrapper.getModelElement(), resourcetype); + + return resourcetype; + } + + + + /** + * @param mofClass + * @param metaModelClass + */ + private void initMetaModelClass(MofClassWrapper mofClass, MetaModelClass metaModelClass) + { + + + metaModelClass.setName(mofClass.getName()); + + // parse the Attributes of the ResourceTypes + Collection attributes = mofClass.getContents();//allAttributes() + for (Iterator iter = attributes.iterator(); iter.hasNext();) + { + try + { + Object o = iter.next(); + if (o instanceof Attribute) + { + Attribute attribute = (Attribute) o; + + if(attribute.getContainer() == mofClass.getModelElement()) + // don't consider inherited attributes + { + + AttributeWrapper attributeWrapper = + new AttributeWrapper(attribute); + + MetaModelClassAttribute rta = + new MetaModelClassAttribute(attributeWrapper.getName()); + + modelmap.put(attributeWrapper.getModelElement(), rta); + + + metaModelClass.getAttributes().add(rta); + + Object attributeType = attributeWrapper.getType(); + String attributeTypeName = attributeType.getClass().getSimpleName(); + attributeTypeName = attributeTypeName.split(MetaModelConst.MDR_IMPL_SUFFIX_REGEXP)[0]; + rta.setTypeName(attributeTypeName); + } + + } + + } + catch (Exception e) + { + logger.logException(e); + } + } + } + + /* Parses & caches all Associations between Resources + * and Actions (with name "actionResource") + */ + protected void examineMetamodelAssociations(Collection actionResourceAssociations, Collection otherAssociations, DialectMetaModelInfo mmInfo) + { + examineActionResourceAssociations(actionResourceAssociations, mmInfo); + + examineResourceTypeHierarchies(mmInfo.getResourceTypes(), mmInfo); + + examineInterResourceAssociations(otherAssociations ,mmInfo); + } + + /** + * @param actionResourceAssociations + * @param mmInfo + */ + private void examineActionResourceAssociations(Collection actionResourceAssociations, DialectMetaModelInfo mmInfo) + { + try + { + for (Iterator iter = actionResourceAssociations.iterator(); iter + .hasNext();) + { + Association association = (Association) iter.next(); + + // logger.info(metamodelExamination, + // "### Association Contents: "); + + + ActionType actionType = null; + ResourceType resourceType = null; + + + // an Association contains 2 AssociationEnds + for (Iterator iterator = association.getContents().iterator(); iterator + .hasNext();) + { + Object item = iterator.next(); + if (item instanceof AssociationEnd) + { + AssociationEnd associationEnd = (AssociationEnd) item; + + try + { + Classifier classifier = associationEnd.getType(); + // logger.info("AssociationEnd.getTypeA().getNameA(): " + // + classifier.getNameA()); + // + MetaModelEntity metaModelEntity = + modelmap.getElement(classifier); + + if (metaModelEntity instanceof ResourceType) + { + resourceType = (ResourceType) metaModelEntity; + //logger.info(" - ResourceType: " + resourceType.toString()); + } + else if (metaModelEntity instanceof ActionType) + { + actionType = (ActionType) metaModelEntity; + //logger.info(" - ActionType: " + actionType.getName()); + } + + //Object[] qualifiers = associationEnd.getQualifiersA().toArray(); + //logger.info(""); + } + catch (Exception e) + { + logger.logException(e); + } + } + else + { + // logger.info(metamodelExamination, + // "- " + item.toString()); + } + + //logger.info("- " + element.toString()); + } + + + if(actionType != null && resourceType != null) + { + String shortname = actionType.getName(); + + //Collection tags = modelmap.getModelElementTags(association); + //modelmap.getAssociationTag(association); + + TaggedValue taggedValue = modelmap.getModelElementTaggedValue(association, MetaModelConst.TAG_SHORTNAME); + + // use the short name if available + try + { + if(taggedValue == null || taggedValue.getValue() == null || taggedValue.getValue().length() == 0) + { + logger.warn(metamodelExamination, + "no shortname defined for Association " + + association.getName()); + } + else //if(tag.getName().equals(ModelConst.TAG_SHORTNAME)) + // this is the case, because checked above + { + shortname = (String)taggedValue.getValue(); + } + actionType.setShortName(shortname); + } + catch (Exception e) + { + //logger.info("problem with Association " + association.getName() + + // " and Tag " + tag); + logger.logException(e); + } + + // logger.info(metamodelExamination, + // "ResourceAction Association: " + // + resourceType.getName() + // + " -> " + // + actionType.getName()); + + mmInfo.addResourceActionAssociation(shortname, resourceType, actionType); + } + } + } + catch (Exception e) + { + logger.logException(e); + } + } + + private void examineResourceTypeHierarchies(Collection resourceTypes, DialectMetaModelInfo mmInfo) + { + for (Iterator iter = resourceTypes.iterator(); iter.hasNext();) + { + try + { + ResourceType resourceType = (ResourceType) iter.next(); + MofClass resourceClass = (MofClass) + modelmap.getMofElement(resourceType); + + MofClass parentResourceClass = (MofClass) + resourceClass.getSupertypes().get(0);//getParents().get(0); + + if(modelmap.containsMapping(parentResourceClass) + && modelmap.getElement(parentResourceClass) + instanceof ResourceType) + { + ResourceType parentResourceType = (ResourceType) + modelmap.getElement(parentResourceClass); + resourceType.setParentResourceType(parentResourceType); + } + else + { + // parent == "Resource" or null + resourceType.setParentResourceType(null); + } + } + catch (Exception e) + { + logger.logException(e); + } + + } + + } + + private void examineInterResourceAssociations(Collection associations, DialectMetaModelInfo mmInfo) + /** Relations between ResourceTypes are examined + * and stored in a Map + * + */ + { + for (Iterator iter = associations.iterator(); iter.hasNext();) + { + Association mofAssociation = (Association) iter.next(); + + AssociationEnd end1 = null; + AssociationEnd end2 = null; + + // logger.info(metamodelExamination, + // "### Association '" + mofAssociation.getName() + + // "' between: "); +// + String name = mofAssociation.getName(); + + MofClass end1Class = null; + MofClass end2Class = null; + String end1Name = null; + String end2Name = null; + + MetaModelEntity end1Type = null; + MetaModelEntity end2Type = null; + + // an Association contains 2 AssociationEnds + for (Iterator iterator = mofAssociation.getContents().iterator(); + iterator.hasNext();) + { + Object item = iterator.next(); + if (item instanceof AssociationEnd) + { + AssociationEnd associationEnd = (AssociationEnd) item; + + try + { + + end1 = associationEnd; + end1Class = (MofClass) + associationEnd.getType(); + end1Name = associationEnd.getName(); + // logger.info(metamodelExamination, + // " - (end1)" + + // end1Class.getName()); + + + associationEnd = (AssociationEnd) iterator.next(); + + + end2 = associationEnd; + end2Class = (MofClass) + associationEnd.getType(); + end2Name = associationEnd.getName(); + // logger.info(metamodelExamination, + // " - (end2) " + + // end2Class.getName()); + } + catch (Exception e) + { + logger.logException(e); + } + } + } + + if(end1Class != null && end2Class != null) + { + if(modelmap.containsMapping(end1Class)) + end1Type = modelmap.getElement(end1Class); + if(modelmap.containsMapping(end2Class)) + end2Type = modelmap.getElement(end2Class); + + //logger.info(metamodelExamination, "... mapped"); + + if( end1Type != null + && end2Type != null + && end1Type instanceof MetaModelClass + && end2Type instanceof MetaModelClass + ) + { + InterResourceAssociation interResourceAssociation = + mmInfo.addInterResourceAssociation(name, end1Type, end2Type); + + interResourceAssociation.getEnd1().setName(end1Name); + interResourceAssociation.getEnd2().setName(end2Name); + + interResourceAssociation.getEnd1().setType((MetaModelClass)end1Type); + interResourceAssociation.getEnd2().setType((MetaModelClass)end2Type); + + interResourceAssociation.getEnd1().setMultiple(end1.getMultiplicity().getUpper()>1);//isMultiple()); + interResourceAssociation.getEnd2().setMultiple(end2.getMultiplicity().getUpper()>1);//isMultiple()); + + try + { + TaggedValue end1TaggedValue = (TaggedValue) + modelmap.getModelElementTaggedValue( + end1, + MetaModelConst.TAG_UML_PROPERTY_GETTER); + logger.info("uml property getter found: "+end1TaggedValue.getValue()); + interResourceAssociation.getEnd1(). + setUmlPropertyGetter( + end1TaggedValue. + getValue()); + } + catch (Exception e) + { + // TODO: handle exception + /* don't care when tag is not there because it's optional, + * has a default value and is not always needed + */ + } + + try + { + TaggedValue end2TaggedValue = (TaggedValue) + modelmap.getModelElementTaggedValue( + end2, + MetaModelConst.TAG_UML_PROPERTY_GETTER); + + logger.info("uml property getter found: "+end2TaggedValue.getValue()); + interResourceAssociation.getEnd2(). + setUmlPropertyGetter( + end2TaggedValue. + getValue()); + } + catch (Exception e) + { + // TODO: handle exception + /* don't care when tag is not there because it's optional, + * has a default value and is not always needed + */ + } + //associations.add(containmentAssociation); + } + } + else + { + logger.info(" ... is no containment association"); + } + } + } + /** Breadth first search of the package named name "SecureUML" + * + */ + public Object findPackage(MofPackageWrapper mofPackageWrapper, String namePart) + { + + if(mofPackageWrapper == null || namePart == null) + return null; + + + + //*** + String nofElements = "??"; + + //*** + + + + // logger.info(metamodelValidation, + // "Searching Package *" + namePart);// + +// "* among " +// + nofElements + //+ mofPackageWrapper.getContents().size() +// + " Elements..."); + + if(mofPackageWrapper.getName() + //.getModelElement().getClass().getSimpleName() + .toLowerCase().contains(namePart.toLowerCase())) + return mofPackageWrapper; + + Object result = null; + + Object pk = mofPackageWrapper.getModelElement(); + //Package pk = (Package) pkg; + + + LinkedList myElements = + new LinkedList(); + + int index = 0; + do + { + // save Variant of "myElements.addAll(pk.getOwnedElement)" + if(pk != null) + { + //Util.printInterfaces(pk.getClass()); +// Collection contents = (Collection) +// Util.getProperty(pk, "contents"); +// //pk.getContents(); + searchAndAddAllElements(mofPackageWrapper, myElements); + } + + + Object modelelement = myElements.get(index++); + + //if (Util.hasType(modelelement, "MofPackage")) + //modelelement instanceof MofPackage ) + //{ + pk = /*(MofPackage)*/ modelelement; + MofPackageWrapper pkWrapper = + new MofPackageWrapper(pk); + + //String name = Util.getProperty(pk, "name").toString(); + + String name = pkWrapper.getName(); + //pk.getClass().getSimpleName(); + + //pk.getName(); + + + //newNode = casePackage( (Package) me); +// logger.info(metamodelExamination, prefix + +// //" Package: " + +// modelelement.getClass().getInterfaces()[0].getSimpleName() + +// ": " + +// name); + + if(name.toLowerCase().contains(namePart.toLowerCase())) + { + + //logger.info(metamodelValidation, "Package '" + namePart + "' found: " + pk.getNameA()); + //secureUmlPackage = + if(result == null) + { + // logger.info(metamodelValidation, + // "found Package: " + // + pkWrapper.getName()); + //pk.getClass().getSimpleName()); + + result = pk; + } + else + { + logger.warn(metamodelValidation,"... but more than one match for findPackage(" + namePart + ")"); + } + } + else + { + //logger.info("some Package found: " + pk.getNameA()); + + //return findSecureUmlPackage((MofPackageWrapper)modelelement); + } + //} + /*else */ + if (Util.hasType(modelelement, "Import")) + //(modelelement instanceof Import) + { + //Import im = (Import) modelelement; + Object importedNamespace = + Util.getProperty(modelelement, "importedNamespace"); + + searchAndAddAllElements(new MofPackageWrapper(importedNamespace), myElements); + +// Collection contents = (Collection) +// Util.getProperty(importedNamespace, "contents"); +// + //= im.getImportedNamespace().getContents(); + + //addAllWithoutDuplicates(myElements, contents); + } +// else +// { +// logger.info("NOT SecureUML Package: " + modelelement.getClass().getSimpleName()); +// pk = null; +// } + + + } + while (myElements.size() > index); + + return result; + } + + /** + * @param pkg + * @param myElements + */ + private void searchAndAddAllElements(RefPackageWrapper pkg, LinkedList myElements) + { + String nofElements; + + Collection allClasses = pkg.allClasses(); + if(allClasses != null) + { + nofElements = "" + allClasses.size(); + //logger.info("allClasses: " + nofElements); + addAllWithoutDuplicates(myElements, allClasses); + } + + + Collection allAssociations = pkg.allAssociations(); + if(allClasses != null) + { + nofElements = "" + allAssociations.size(); + //logger.info("allAssociations: " + nofElements); + addAllWithoutDuplicates(myElements, allAssociations); + } + + + Collection allPackages = pkg.allPackages(); + if(allPackages != null) + { + nofElements = "" + allPackages.size(); + //logger.info("allPackages: " + nofElements); + addAllWithoutDuplicates(myElements, allPackages); + } + } + + private void searchAndAddAllElements(MofPackageWrapper pkg, LinkedList myElements) + { + Collection contents = pkg.getContents(); + if(contents != null) + { + String nofElements = "" + contents.size(); + //logger.info("allPackages: " + nofElements); + addAllWithoutDuplicates(myElements, contents); + } + } + + + + /** Add all elements of additionalElements to + * collection - catch possible Exceptions for each + * Element seperately + * + * @param collection + * @param additionalElements + */ + private void addAllWithoutDuplicates(LinkedList collection, Collection additionalElements) + { + for (Iterator iter = additionalElements.iterator(); iter.hasNext();) + { + try + { + Object element = (Object) iter.next(); + if(!collection.contains(element)) + collection.add(element); + } + catch (Exception e) + { + logger.logException(e); + } + } + } + + +// +// public void traverseGenericPackage(Package pkg) +// { +// prefix = prefix + "-"; +// +// +// Package pk = (Package) pkg; +// +// Collection elements = pk.getOwnedElement(); +// Iterator it = elements.iterator(); +// while ( it.hasNext() ) +// { +// ModelElement me = (ModelElement) it.next(); +// +// if ( me instanceof Association ) +// { +// logger.info(prefix + " Association: " + me.getNameA()); +// +// //newNode = caseAssociation( (Association) me); +// } +// else if ( me instanceof Classifier ) +// { +// logger.info(prefix + " Classifier: " + me.getNameA()); +// //newNode = caseClassifier( (Classifier) me); +// } +// else if ( me instanceof Package ) +// { +// //newNode = casePackage( (Package) me); +// logger.info(prefix + " Package: " + me.getNameA()); +// traverseGenericPackage((Package)me); +// } +// else +// { +// //newNode = new DefaultMutableTreeNode("[???] " + me.getNameA() + " (" + me.getClass().getName() + ")"); +// } +// } +// +// if(prefix.length() >1) +// prefix = prefix.substring(0, prefix.length()-1); +// +// } + + public void traverseMofPackage(ModelElement pk) + { + + Association association; + Tag tag; + Object mofPackage; + + // tag.getName() == stereotype + // tag.getValues().get(0) == secuml.action + // tag.getElements().iterator().next() == + // "the Association to which the Tag belongs" + + + + prefix = prefix + "-"; + + + Collection elements = (Collection) + Util.getProperty(pk, "contents"); + //pk.getContents(); + + Iterator it = elements.iterator(); + + //logger.info("##" + elements.size()); + + while ( it.hasNext() ) + { + ModelElement me = (ModelElement) it.next(); + logger.info("###" + me.getName() + ": " + + me.getClass().getCanonicalName()); + logger.info(me.toString()); + + + if ( me instanceof Association ) + { + logger.info(prefix + " Association: " + me.getName()); + + //newNode = caseAssociation( (Association) me); + } + else if ( me instanceof Classifier ) + { + logger.info(prefix + " Classifier: " + me.getName()); + //newNode = caseClassifier( (Classifier) me); + } +// else if ( me instanceof Package ) +// { +// //newNode = casePackage( (Package) me); +// logger.info(prefix + " Package: " + me.getNameA()); +// traverseMofPackageWrapper((MofPackageWrapper)me); +// } + else if (Util.hasType(me, "MofPackage"))//(me instanceof MofPackage) + { + logger.info(prefix + " MofPackageWrapper: " + me.getName()); + traverseMofPackage(me); + + + //newNode = new DefaultMutableTreeNode("[???] " + me.getNameA() + " (" + me.getClass().getName() + ")"); + + } + else if(me instanceof Import) + { + Import im = (Import)me; + + logger.info(prefix + " Import: " + me.getName()); + + traverseMofPackage(im.getImportedNamespace()); + } + else if (me instanceof Namespace) + { + logger.info(prefix + " Namespace: " + me.getName()); + traverseMofPackage((Namespace) me); + + //newNode = new DefaultMutableTreeNode("[???] " + me.getNameA() + " (" + me.getClass().getName() + ")"); + + } + else if (me instanceof Tag) + { + Tag t = (Tag)me; + logger.info(prefix + " Tag: " + + t.getName() + " ( " + t.getValues().get(0) + " ) "); + } + else if(me instanceof Association) + { + Association a = (Association) me; + + } + else + { + logger.info(prefix + " else: " + me.getName()); + logger.info(me.toString()); + } + + + } + + if(prefix.length() >1) + prefix = prefix.substring(0, prefix.length()-1); + + } + + + + + + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/DialectMetaModelParser.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/DialectMetaModelParser.java new file mode 100644 index 0000000..913f3ca --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/DialectMetaModelParser.java @@ -0,0 +1,233 @@ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser; + +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Iterator; + +import javax.jmi.model.ModelPackage; +import javax.jmi.model.MofPackage; +import javax.jmi.reflect.RefClass; +import javax.jmi.reflect.RefPackage; + +import org.apache.log4j.Logger; +import org.argouml.model.Model; +import org.netbeans.api.mdr.MDRManager; +import org.netbeans.api.mdr.MDRepository; +import org.netbeans.api.xmi.XMIReader; +import org.netbeans.api.xmi.XMIReaderFactory; +import org.netbeans.lib.jmi.mapping.FileStreamFactory; +import org.netbeans.lib.jmi.mapping.JMIMapperImpl; + +import ch.ethz.infsec.secureumlgui.DialectMetamodelSelectedListener; +import ch.ethz.infsec.secureumlgui.SecureUmlModule; +import ch.ethz.infsec.secureumlgui.TabSecureUml; + +//import ch.ethz.infsec.secureumlgui.gui.SecureUmlComponentManager; +import ch.ethz.infsec.secureumlgui.gui.SecureUmlPermissionComponent; +import ch.ethz.infsec.secureumlgui.gui.SecureUmlRoleComponent; +import ch.ethz.infsec.secureumlgui.gui.SecureUmlComponent; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.main.SecureUmlConstants; + +import ch.ethz.infsec.secureumlgui.modelmanagement.ModelConst; +import ch.ethz.infsec.secureumlgui.modelmapping.GenericDialectHelper; +import ch.ethz.infsec.secureumlgui.modelmapping.GenericDialectModelMapper; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.DialectMetaModelInfo; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ResourceType; +import ch.ethz.infsec.secureumlgui.securemodelimpl.SecureModelFactory; + +/** + * loads metamodel from .xmi file and calls {@link + * DialectMetaModelAnalyzer}. The metamodel is assumed to have the + * following structure: + * + *
+ * ...
+ * (MOF) Model SecureModel
+ *                |
+ *                `--Package SecureUML                     (containing the SecureUML elements, like Role, Permission, Action)
+ *                |
+ *                `--Package <DesignLanguage>        (containing the design modeling elements)
+ *                |
+ *                `--Package <DesignLanguage>Dialect (containing the action types and their associations to resources)
+ * ...
+ * 
+ * + * Note that there can be arbitrary many other models in the .xmi + * file, as long as one is called "SecureModel" and containts the + * SecureUML dialect. The content of the .xmi file will be read into + * an extent also called (confusingly) "SecureModel". Note that this + * is not directly the metamodel that will be instantiated. The + * metamodel that will be instantiated is the package called + * "SecureModel" inside this extent. The extent for this instance will + * be called "mySecureModel". + * + * + */ +public class DialectMetaModelParser + implements DialectMetamodelSelectedListener +{ + + + + MultiContextLogger logger = MultiContextLogger.getDefault(); + + private static Logger aLog = Logger.getLogger(DialectMetaModelParser.class); + + // /** the file name of the .xmi file containing the dialect metamodel */ + // private String dialectMetamodelFilename; + + // /** The dialect instance */ + // private RefPackage mySecureModelPackage = null; + + // /** The SecureModel extent */ + // private ModelPackage secureModelExtent = null; + + // /** The dialect metamodel package (SecureModel) inside the SecureModel extent */ + // private MofPackage secureModelPackage = null; + + public void dialectMetamodelSelected(File xmiFile) + { + //String dialectMetamodelFilename = xmiFile.getPath(); + + + ModelPackage secureModelExtent = createMetamodelExtent(); + MofPackage secureModelPackage = readMetamodel(secureModelExtent, xmiFile); + RefPackage mySecureModelPackage = createDialectInstanceExtent(secureModelPackage); + + DialectMetaModelUtil.generateSrcFiles(mySecureModelPackage); + + DialectMetaModelAnalyzer analyzer = + new DialectMetaModelAnalyzer(secureModelPackage); + + DialectMetaModelInfo mmInfo = analyzer.analyzeDialect( secureModelPackage); + mmInfo.setDialectExtent(mySecureModelPackage); + mmInfo.setDialectMetaExtent(secureModelPackage); + + + + DialectMetaModelUtil.printMetamodel(mmInfo); + + GenericDialectHelper.getInstance().setDialectMetaModelInfo(mmInfo); + + registerSuComponents(mmInfo); + + GenericDialectModelMapper modelMapper = + new GenericDialectModelMapper(mmInfo); + + + +// System.out.println("try to load Policy class"); +// try { +// Class.forName("ch.ethz.infsec.secureumlgui.securemodel.secureuml.Policy"); +// } catch (ClassNotFoundException e) { +// // TODO Auto-generated catch block +// e.printStackTrace(); +// } + } + + /** + * @param mmInfo + */ + private void registerSuComponents(DialectMetaModelInfo mmInfo) + { + TabSecureUml tab = SecureUmlModule.getTab(); + + SecureUmlRoleComponent suRoleComponent = + new SecureUmlRoleComponent(); + + tab.registerSecureUmlComponent( + SecureUmlConstants.getRoleResourceTypeDummy(), + suRoleComponent); + + SecureUmlPermissionComponent suPermissionComponent = + new SecureUmlPermissionComponent(); + + tab.registerSecureUmlComponent( + SecureUmlConstants.getPermissionResourceTypeDummy(), + suPermissionComponent); + + SecureUmlComponent suResourceComponent = new SecureUmlComponent(); + + for (Iterator iter = mmInfo.getResourceTypes().iterator(); iter.hasNext();) + { + ResourceType rt = (ResourceType) iter.next(); + + tab.registerSecureUmlComponent(rt,suResourceComponent); + } + } + + /** creates dialect metamodel extent. Deletes any existing old + * dialect metamodel extent. Initializes {@link + * #secureModelExtent}. + */ + private ModelPackage createMetamodelExtent() { + aLog.debug("createMetamodelExtent"); + MDRepository repository = MDRManager.getDefault().getDefaultRepository(); + try { + Object oldExtent = repository.getExtent(ModelConst.SECUREMODEL_EXTENT_NAME); + if(oldExtent != null) { + repository.getExtent(ModelConst.SECUREMODEL_EXTENT_NAME).refDelete(); + } + return (ModelPackage) repository.createExtent(ModelConst.SECUREMODEL_EXTENT_NAME); + } catch (Exception e) { + logger.error("error while creating dialect metamodel extent: "+e.getMessage()); + return null; + } + } + + /** reads the dialect metamodel .xmi file into {@link + * #secureModelExtent}, and returns the contained SecureModel + * package. + */ + private MofPackage readMetamodel(ModelPackage extent, File file) { + aLog.debug("readMetamodel " + extent + " from file " + file.getAbsolutePath()); + MDRepository repository = MDRManager.getDefault().getDefaultRepository(); + aLog.debug("here?"); + XMIReader reader = XMIReaderFactory.getDefault().createXMIReader(); + aLog.debug("here? b"); + + try { + FileInputStream inputstream = new FileInputStream(file); + + Collection c = reader.read(inputstream, file.getPath(), extent); + + aLog.debug("here? c"); + + + for (Object item : c ) { + if(item instanceof javax.jmi.model.MofPackage) { + javax.jmi.model.MofPackage mofPackage = (javax.jmi.model.MofPackage) item; + aLog.debug("found: " + mofPackage.getName()); + if (mofPackage.getName().equals(ModelConst.SECUREMODEL_PACKAGE_NAME)) { + return (javax.jmi.model.MofPackage) item; + } + } + } + } catch (Exception e) { + logger.error("error while reading metamodel file: "+e.getMessage()); + } + return null; + } + + /** creates the dialect instance extent. Initializes {@link #mySecureModelPackage}*/ + private RefPackage createDialectInstanceExtent(MofPackage secureModelPackage) { + aLog.debug("createDialectInstanceExtent for MofPackage " + secureModelPackage.getName() + " (" + secureModelPackage + ")"); + MDRepository repository = MDRManager.getDefault().getDefaultRepository(); + + RefPackage pack = repository.getExtent(ModelConst.SECUREMODEL_INSTANCE_NAME); + if(pack == null) { + try { + pack = repository.createExtent(ModelConst.SECUREMODEL_INSTANCE_NAME, + secureModelPackage); + } catch(Exception e) { + logger.error("error while creating dialect instance extent"); + } + } + return pack; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/DialectMetaModelUtil.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/DialectMetaModelUtil.java new file mode 100644 index 0000000..768dc29 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/DialectMetaModelUtil.java @@ -0,0 +1,269 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser; + +import java.io.File; +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.Iterator; +import java.util.List; + +import javax.jmi.reflect.RefAssociation; +import javax.jmi.reflect.RefClass; +import javax.jmi.reflect.RefPackage; + +import org.apache.log4j.Logger; +import org.netbeans.lib.jmi.mapping.FileStreamFactory; +import org.netbeans.lib.jmi.mapping.JMIMapperImpl; + +import ch.ethz.infsec.secureumlgui.Util; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ActionResourceAssociation; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ActionType; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.CompositeActionType; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.DialectMetaModelInfo; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.InterResourceAssociation; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.MetaModelClass; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ResourceType; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; + +/** + * + */ +public class DialectMetaModelUtil +{ + static MultiContextLogger logger = MultiContextLogger.getDefault(); + + private static Logger aLog = Logger.getLogger(DialectMetaModelUtil.class); + + + public static String getUri(String filename) + { + File xmiFile = new File(filename); + if(xmiFile.exists()) + { + logger.info("XMI Metamodel found: " + filename); + } + else + { + logger.error("XMI Metamodel NOT found: " + filename); + return null; + } + + return xmiFile.toURI().toString(); + } + + public static void generateSrcFiles(RefPackage mySecureModelPackage) { + File destDir = new File("generated"); + destDir.mkdirs(); + aLog.debug("generate mySecureModelPackage sources to: " + destDir.getAbsolutePath()); + + + JMIMapperImpl mapperImpl = new JMIMapperImpl(); + FileStreamFactory fileStreamFactory = new FileStreamFactory(destDir); + + Collection packages = (Collection) mySecureModelPackage.refAllPackages(); + try { + for (RefPackage packa : packages ) { + aLog.debug("Generate package: " + packa); + mapperImpl.generate(fileStreamFactory, packa.refMetaObject()); + for ( RefClass cl : (Collection) packa.refAllClasses() ) { + aLog.debug("Generate class: " + cl); + mapperImpl.generate(fileStreamFactory, cl.refMetaObject()); + } + for ( RefAssociation ass : (Collection) packa.refAllAssociations()) { + aLog.debug("Generate association: " + ass); + mapperImpl.generate(fileStreamFactory, ass.refMetaObject()); + } + } + } catch (Exception e) { + e.printStackTrace(); + aLog.error(e); + } + } + + + + public static DialectMetaModelInfo printMetamodel(DialectMetaModelInfo metaModelInfo) + { +// for ( Object cont : metaModelInfo.getDialectMetaExtent().getContents() ) { +// if ( cont instanceof javax.jmi.model.Tag ) { +// javax.jmi.model.Tag cont2 = (javax.jmi.model.Tag ) cont; +// if ( cont2.getName().equals("umlClassName")) { +// List cont3 = cont2.getQualifiedName(); +// for ( Object cont4 : cont3) { +// System.out.println(cont4.getClass() + "." + cont4.toString()); +// } +// } +// } +// } +// +// for ( MetaModelClass mmc : metaModelInfo.getMetaModelClasses() ) { +// +// System.out.println("MetaModelClass: " + mmc.getName() + ", " + mmc.getUmlClassName()); +// +// } + + + + +// DialectMetaModelParser parser = +// new DialectMetaModelParser(metamodelFilename); +// +// ModelPackage modelPackage; +// +// +// metamodelTopPackage = parser.loadMetamodel(); +// +// +// +// //logger.info("Package type: " + topPkg.toString()); +// +// //mmTester.traverseMofMetamodel(); +// +// //mmTester.printDialectStuff(); +// +// metaModelInfo = parser.analyzeDialect(metamodelTopPackage); +// logger.info("## Protected Resource Types ##"); +// printResourcesTypes(metaModelInfo.getResourceTypes(), metaModelInfo); +// logger.info("## Atomic Action Types ##"); +// printActionsTypes(metaModelInfo.getAtomicActionTypes()); +// logger.info("## Composite Action Types ##"); +// printActionsTypes(metaModelInfo.getCompositeActionTypes()); +// logger.info("## other Metamodel Classes ##"); +// printMappableMetaModelClasses(metaModelInfo.getMetaModelClasses()); +// logger.info("## Resource-Action Associations##"); +// printResourceActionAssociations(metaModelInfo); +// logger.info("## Inter Resource Associations ##"); +// printInterResourceAssociations(metaModelInfo); + + + + return metaModelInfo; + // produces ClassCastException within org.netbeans.mdr.NBMDRepositoryImpl.createExtent +// try +// { +// RepositoryManager.getRepository().createModel("test", metamodelTopPackage); +// } +// catch (Exception e) +// { +// logger.logException(e); +// } +// + + } + + + public static void printResourcesTypes(Collection resourceTypes, DialectMetaModelInfo mmInfo) + { + + for (Iterator iter = resourceTypes.iterator(); iter.hasNext();) + { + ResourceType resourceType = (ResourceType) iter.next(); + + String resourceString = resourceType.toString(); + + logger.info("Resource: " + resourceString); + + printActionsTypes(mmInfo.getActionTypesOfResourceType(resourceType), " "); + } + } + + public static void printMetaModelClasses(Collection metaModelClasses) + { + + for (Iterator iter = metaModelClasses.iterator(); iter.hasNext();) + { + MetaModelClass metaModelClass = (MetaModelClass) iter.next(); + + String classString = metaModelClass.toString(); + + logger.info("MetaModelClass: " + classString); + + //printActionsTypes(mmInfo.getActionTypesOfResourceType(metaModelClass), " "); + } + } + + public static void printMappableMetaModelClasses(Collection metaModelClasses) + { + + for (Iterator iter = metaModelClasses.iterator(); iter.hasNext();) + { + MetaModelClass metaModelClass = (MetaModelClass) iter.next(); + + String classString = metaModelClass.toString(); + + if(metaModelClass.getUmlClassName() != null) + logger.info("MetaModelClass: " + classString); + + //printActionsTypes(mmInfo.getActionTypesOfResourceType(metaModelClass), " "); + } + } + + public static void printActionsTypes(Collection actionTypes) + { + printActionsTypes(actionTypes, ""); + } + public static void printActionsTypes(Collection actionTypes, String prefix) + { + if(actionTypes != null) + for (Iterator iter = actionTypes.iterator(); iter.hasNext();) + { + try + { + ActionType actionType = (ActionType) iter.next(); + + String loggerString = prefix + "Action: " + actionType.getName(); + + if (actionType instanceof CompositeActionType) + { + CompositeActionType compositeActionType = (CompositeActionType) actionType; + + loggerString += + " - SubactionsDefinition: " + + compositeActionType.getSubactionsDefinition(); + } + + logger.info(loggerString); + } + catch (Exception e) + { + logger.logException(e); + } + + } + } + + public static void printResourceActionAssociations(DialectMetaModelInfo mmInfo) + { + for (Iterator iter = mmInfo.getResourceTypes().iterator(); iter.hasNext();) + { + ResourceType resourceType = (ResourceType) iter.next(); + + for (Iterator iterator = mmInfo.getResourceActionAssociations(resourceType).iterator(); iterator.hasNext();) + { + ActionResourceAssociation raDependency = (ActionResourceAssociation) iterator.next(); + + logger.info(raDependency.getResourceType().getName() + + " ----" + + raDependency.getShortname() + + "----> " + + raDependency.getActionType().getName()); + + } + + } + } + + public static void printInterResourceAssociations(DialectMetaModelInfo mmInfo) + { + for (Iterator iter = mmInfo.getInterResourceAssociations().iterator(); iter.hasNext();) + { + InterResourceAssociation interResourceAssociation = (InterResourceAssociation) iter.next(); + + logger.info(interResourceAssociation.toString()); + + } + + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/BooleanExpression.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/BooleanExpression.java new file mode 100644 index 0000000..17350b6 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/BooleanExpression.java @@ -0,0 +1,27 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +/** + * + */ +public abstract class BooleanExpression extends ExpressionFragment +{ + private boolean negated = false; + + /** is the expression of form (not (...) + * - Default is 'false' + * @return true if the expression is negated. + */ + + public boolean isNegated() + { + return negated; + } + + public void setNegated(boolean negated) + { + this.negated = negated; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/BooleanLiteral.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/BooleanLiteral.java new file mode 100644 index 0000000..056bc2e --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/BooleanLiteral.java @@ -0,0 +1,41 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +/** + * + */ +public class BooleanLiteral extends Literal +{ + /** + * + */ + public BooleanLiteral(boolean value) + { + this.value = value; + } + + private boolean value; + + public boolean getValue() + { + return value; + } + + public void setValue(boolean value) + { + this.value = value; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + return "BooleanLiteral(" + + (value?"true":"false") + + ")"; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/ConjunctiveBooleanExpression.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/ConjunctiveBooleanExpression.java new file mode 100644 index 0000000..fd58da6 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/ConjunctiveBooleanExpression.java @@ -0,0 +1,41 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; + +/** + * + */ +public class ConjunctiveBooleanExpression extends BooleanExpression +{ + private Collection terms + = new LinkedList(); + + public Collection getTerms() + { + return terms; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + String s = "ConjunctiveBooleanExpression( "; + + for (Iterator iter = terms.iterator(); iter.hasNext();) + { + ExpressionFragment term = (ExpressionFragment) iter.next(); + + s += term.toString(); + } + + s += " )"; + return s; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/DecimalLiteral.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/DecimalLiteral.java new file mode 100644 index 0000000..96eec23 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/DecimalLiteral.java @@ -0,0 +1,39 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +/** + * + */ +public class DecimalLiteral extends Literal +{ + /** + * + */ + public DecimalLiteral(double value) + { + this.value = value; + } + + private double value; + + public double getValue() + { + return value; + } + + public void setValue(double value) + { + this.value = value; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + return "DecimalLiteral("+value+")"; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/DisjunctiveBooleanExpression.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/DisjunctiveBooleanExpression.java new file mode 100644 index 0000000..015d672 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/DisjunctiveBooleanExpression.java @@ -0,0 +1,41 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; + +/** + * + */ +public class DisjunctiveBooleanExpression extends BooleanExpression +{ + private Collection terms + = new LinkedList(); + + public Collection getTerms() + { + return terms; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + String s = "DisjunctiveBooleanExpression( "; + + for (Iterator iter = terms.iterator(); iter.hasNext();) + { + ExpressionFragment term = (ExpressionFragment) iter.next(); + + s += term.toString(); + } + + s += " )"; + return s; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/Equation.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/Equation.java new file mode 100644 index 0000000..ef62fc5 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/Equation.java @@ -0,0 +1,83 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +/** LeftPart and RightPart must evaluate to comparable Literal Types + * + */ +public class Equation extends ExpressionFragment +{ + /** + * + */ + public Equation() + { + ; + } + + /** + * + */ + public Equation( + ExpressionFragment leftPart, + ExpressionFragment rightPart, + boolean isEqual) + { + this.leftPart = leftPart; + this.rightPart = rightPart; + this.isEqual = isEqual; + } + + + /** true if ... = ..., + * false if ... <> ... + * + */ + private boolean isEqual; + + public boolean isEqual() + { + return isEqual; + } + + public void setEqual(boolean isEqual) + { + this.isEqual = isEqual; + } + + private ExpressionFragment leftPart; + + public ExpressionFragment getLeftPart() + { + return leftPart; + } + + public void setLeftPart(ExpressionFragment leftPart) + { + this.leftPart = leftPart; + } + + private ExpressionFragment rightPart; + + public ExpressionFragment getRightPart() + { + return rightPart; + } + + public void setRightPart(ExpressionFragment rightPart) + { + this.rightPart = rightPart; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + return "Equation(" + + leftPart + ", " + + rightPart + ")"; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/ExpressionEvaluator.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/ExpressionEvaluator.java new file mode 100644 index 0000000..d5fa5f0 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/ExpressionEvaluator.java @@ -0,0 +1,16 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +/** + * + */ +public class ExpressionEvaluator +{ + public Object evaluateExpression(OclExpression p, Object startPoint) + { + return null; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/ExpressionFactory.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/ExpressionFactory.java new file mode 100644 index 0000000..0d53b05 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/ExpressionFactory.java @@ -0,0 +1,71 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +/** + * + */ +public class ExpressionFactory +{ + public static String TRUE = "true"; + public static String FALSE = "false"; + + /** If s represents a literal, a literal of the corresponding + * type is created and returned + * - null is returned otherwise. + * + * @param s + * @return the created Literal + */ + public static Literal createLiteral(String s) + { + if(s == null | s.length() == 0) + return null; + else if(s.equals(TRUE)) + { + return new BooleanLiteral(true); + } + else if(s.equals(FALSE)) + { + return new BooleanLiteral(false); + } + else if(Character.isDigit(s.charAt(0))) + // Int or Decimal Literal + { + String[] parts = s.split("\\."); + if(parts.length == 1) + // doesn't contain a dot + { + int intValue = Integer.valueOf(parts[0]); + return new IntLiteral(intValue); + } + else if (parts.length == 2) + { + double doubleValue = Double.valueOf(s); + return new DecimalLiteral(doubleValue); + } + } + else if(isQuoteOrDoubleQuote(s.charAt(0)) + && isQuoteOrDoubleQuote(s.charAt(s.length()-1))) + { + String literalString = s.substring(1, s.length()-1); + return new StringLiteral(literalString); + } + + return null; + } + + public static boolean isQuoteOrDoubleQuote(char c) + { + Character character = Character.valueOf(c); + Character doubleQuoteChar = "\"".charAt(0); + Character quoteChar = "'".charAt(0); + + boolean result = character.equals(quoteChar) + || character.equals(doubleQuoteChar); + + return result; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/ExpressionFragment.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/ExpressionFragment.java new file mode 100644 index 0000000..d41bbf0 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/ExpressionFragment.java @@ -0,0 +1,12 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +/** + * + */ +public class ExpressionFragment +{ + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/IntLiteral.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/IntLiteral.java new file mode 100644 index 0000000..04ae848 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/IntLiteral.java @@ -0,0 +1,40 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +/** + * + */ +public class IntLiteral extends Literal +{ + /** + * + */ + public IntLiteral(int value) + { + this.value = value; + } + + private int value; + + public int getValue() + { + return value; + } + + public void setValue(int value) + { + this.value = value; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + return "IntLiteral("+value+")"; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/Literal.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/Literal.java new file mode 100644 index 0000000..0b9a11a --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/Literal.java @@ -0,0 +1,12 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +/** + * + */ +public class Literal extends ExpressionFragment +{ + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OclEvaluatorException.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OclEvaluatorException.java new file mode 100644 index 0000000..7ff81fa --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OclEvaluatorException.java @@ -0,0 +1,19 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +/** + * + */ +public class OclEvaluatorException extends Exception +{ + /** + * + */ + public OclEvaluatorException(String message) + { + super(message); + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OclExpression.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OclExpression.java new file mode 100644 index 0000000..e78cb11 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OclExpression.java @@ -0,0 +1,60 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +import java.util.Collection; +import java.util.Iterator; +import java.util.ArrayList; + +/** + * + */ +public class OclExpression extends ExpressionFragment +{ + /** + * + */ + public OclExpression() + { + + } + + private ArrayList steps = new ArrayList(); + + public Collection getSteps() + { + return steps; + } + +// public void setSteps(Collection steps) +// { +// this.steps = steps; +// } + + public void appendStep(PathStep step) + { + steps.add(step); + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + String resultString = "Path("; + + for (Iterator iter = steps.iterator(); iter.hasNext();) + { + PathStep pathStep = (PathStep) iter.next(); + + resultString += " " + pathStep; + } + + resultString += " )"; + + return resultString; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OclExpressionEvaluator.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OclExpressionEvaluator.java new file mode 100644 index 0000000..1cb7953 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OclExpressionEvaluator.java @@ -0,0 +1,445 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.Set; + +import ch.ethz.infsec.secureumlgui.Util; +import ch.ethz.infsec.secureumlgui.logging.LoggerContext; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; + +/** + * + */ +public class OclExpressionEvaluator +{ + public OclExpressionEvaluator( + OclExpression oclExpression, + Object startPoint, + Object self) + { + this.oclExpression = oclExpression; + this.initialStartPoint = initialStartPoint; + this.self = self; + + logger.disableLoggerContext(OCL_EXPRESSION_EVALUATOR_DETAILLED); + logger.disableLoggerContext(OCL_EXPRESSION_EVALUATOR); + } + /** + * + */ + public OclExpressionEvaluator( + OclExpression oclExpression, + Object startPoint) + { + this(oclExpression, startPoint, startPoint); + + + } + + public static LoggerContext OCL_EXPRESSION_EVALUATOR = + new LoggerContext( + "OclExpressionEvaluator", + "OclExpressionEvaluator"); + public static LoggerContext OCL_EXPRESSION_EVALUATOR_DETAILLED = + new LoggerContext( + "OclExpressionEvaluatorDetailled", + "OclExpressionEvaluatorDetailled"); + + public static String OPERATOR_SELECT = "select"; + public static String SET_OPERATOR_UNION = "union"; + public static String SET_OPERATOR_INTERSECT = "intersect"; + public static String SET_OPERATOR_MINUS = "minus"; + + + + private OclExpression oclExpression; + private Object initialStartPoint; + private Object self; + + MultiContextLogger logger = new MultiContextLogger(OCL_EXPRESSION_EVALUATOR); + + public Set evaluateExpression() + throws OclEvaluatorException + { + return evaluateExpression(oclExpression, initialStartPoint, self); + } + + protected Set evaluateExpression( + OclExpression p, Object startPoint, Object self) + throws OclEvaluatorException + { + Set startPoints = new LinkedHashSet(); + startPoints.add(startPoint); + + Set result = new LinkedHashSet(); + + for (Iterator iter = p.getSteps().iterator(); iter.hasNext();) + { + PathStep step = (PathStep) iter.next(); + + result = evaluateStep(step, startPoints); + + startPoints = result; + } + + return result; + } + + protected Set evaluateStep( + PathStep step, Set startPoints) + throws OclEvaluatorException + { + Set result = new LinkedHashSet(); + + if(step instanceof Self) + { + result.add(self); + } + else if (step instanceof PropertyAccessStep) + { + PropertyAccessStep propertyAccessStep = (PropertyAccessStep) step; + + takePropertyAccessStep(result, propertyAccessStep, startPoints); + + } + else if (step instanceof SelectionStep) + { + SelectionStep selectionStep = (SelectionStep) step; + + takeSelectionStep(result, selectionStep, startPoints); + } + else if (step instanceof SetOperationStep) + { + SetOperationStep setOperationStep = (SetOperationStep) step; + + takeSetOperationStep(result, setOperationStep, startPoints); + } + + return result; + } + + /** + * @param result + * @param paStep + * @param startPoints + */ + protected void takePropertyAccessStep( + Set result, PropertyAccessStep paStep, Set startPoints) + throws OclEvaluatorException + { + String propertyName = paStep.getPropertyName(); + propertyName = removeHeadingWhitespace(propertyName); + propertyName = removeTrailingWhitespace(propertyName); + + if(propertyName == null + || propertyName.length() == 0) + { + logger.warn( + "propertyAccessStep with empty " + + "propertyName, ignoring..."); + result.addAll(startPoints); + } + else + { + + for (Iterator iter = startPoints.iterator(); iter.hasNext();) + { + Object startPoint = (Object) iter.next(); + + + try + { + Object value = + Util.getProperty(startPoint, propertyName); + + if (value instanceof Collection) + { + Collection values = (Collection) value; + result.addAll(values); + } + else if(value != null) + { + result.add(value); + } + else + { + logger.warn(OCL_EXPRESSION_EVALUATOR_DETAILLED, + "accessing Property " + + paStep.getPropertyName() + + " on Object of Type: " + + startPoint.getClass().getSimpleName() + + " returned null"); + } + + } + catch (Exception e) + { + logger.error(OCL_EXPRESSION_EVALUATOR_DETAILLED, + "accessing Property " + + paStep.getPropertyName() + + " on Object of Type: " + + startPoint.getClass().getSimpleName() + + " failed"); + + //logger.logException(e); + } + } + } + } + + protected void takeSetOperationStep( + Set result, SetOperationStep setOperationStep, Collection startPoints) + throws OclEvaluatorException + { + result.addAll(startPoints); + + Set expressionResult = + evaluateExpression( + setOperationStep.getExpression(), self, self); + + // using bulk operations for the set operations as described on + // http://java.sun.com/docs/books/tutorial/collections/interfaces/set.html + if(setOperationStep.getOperation().equals(SET_OPERATOR_UNION)) + { + result.addAll(expressionResult); + } + else if(setOperationStep.getOperation().equals(SET_OPERATOR_INTERSECT)) + { + result.retainAll(expressionResult); + } + else if(setOperationStep.getOperation().equals(SET_OPERATOR_MINUS)) + { + result.removeAll(expressionResult); + } + } + + protected void takeSelectionStep( + Set result, SelectionStep selectionStep, Collection startPoints) + throws OclEvaluatorException + { + for (Iterator iter = startPoints.iterator(); iter.hasNext();) + { + Object startPoint = (Object) iter.next(); + + try + { + boolean conditionResult = + evaluateCondition( + selectionStep.getCondition(), + startPoint, self); + + if(conditionResult) + { + result.add(startPoint); + } + + // - if true, add result.add(startPoint) + } + catch (Exception e) + { + logger.logException(e); + } + } + } + + protected boolean evaluateCondition( + ExpressionFragment condition, Object startpoint, Object self) + throws OclEvaluatorException + { + if (condition instanceof Equation) + { + Equation equation = (Equation) condition; + + Object leftValue = null; + Object rightValue = null; + + // evaluate left part + if(equation.getLeftPart() instanceof Literal) + { + leftValue = evaluateLiteral((Literal)equation.getLeftPart()); + } + else + { + Set leftResult = + evaluateExpression( + (OclExpression)equation.getLeftPart(), + startpoint, self); + + if(leftResult.size() == 1) + leftValue = leftResult.iterator().next(); + else + throw new OclEvaluatorException( + "left part of the equation does not evaluate to a literal" + + equation.toString()); + + + } + // evaluate right part + if(equation.getRightPart() instanceof Literal) + { + rightValue = evaluateLiteral((Literal)equation.getRightPart()); + } + else + { +// if(equation.getRightPart() instanceof OclExpression) +// { + Set rightResult = + evaluateExpression( + (OclExpression)equation.getRightPart(), + startpoint, self); + if(rightResult.size() == 1) + rightValue = rightResult.iterator().next(); + else + throw new OclEvaluatorException( + "right part of the equation does not evaluate to a literal: " + + equation.toString()); +// } + } + + // compare left and right part + if(equation.isEqual()) + return leftValue.equals(rightValue); + else + return !leftValue.equals(rightValue); + } + else if (condition instanceof BooleanLiteral) + { + BooleanLiteral booleanLiteral = (BooleanLiteral) condition; + + return booleanLiteral.getValue(); + } + else if (condition instanceof OclExpression) + { + OclExpression expression = (OclExpression) condition; + + Set result = evaluateExpression(expression, startpoint, self); + if(result.size() == 1) + { + Object item = result.iterator().next(); + if(item.equals(true)) + return true; + else if(item.equals(false)) + return false; + else + { + throw new OclEvaluatorException( + "condition OCL-Expression " + + "does not evaluate to a boolean: " + + item); + } + } + else + { + if(result.size() == 0) + throw new OclEvaluatorException( + "condition OCL-Expression " + + "evaluation returned no result object: " + + result.size()); + else + throw new OclEvaluatorException( + "condition OCL-Expression " + + "evaluation returned more than one result object: " + + result.size()); + } + } + else if (condition instanceof ConjunctiveBooleanExpression) + { + ConjunctiveBooleanExpression booleanExpression = + (ConjunctiveBooleanExpression) condition; + + for (Iterator iter = booleanExpression.getTerms().iterator(); iter.hasNext();) + { + ExpressionFragment term = (ExpressionFragment) iter.next(); + + boolean termValue = evaluateCondition(term, startpoint, self); + + if(!termValue) + // one term false -> AND of all is false + return booleanExpression.isNegated(); + } + // if arrived here, all terms evaluate to 'true' + return !booleanExpression.isNegated(); + } + else if (condition instanceof DisjunctiveBooleanExpression) + { + DisjunctiveBooleanExpression booleanExpression = + (DisjunctiveBooleanExpression) condition; + + for (Iterator iter = booleanExpression.getTerms().iterator(); iter.hasNext();) + { + ExpressionFragment term = (ExpressionFragment) iter.next(); + + boolean termValue = evaluateCondition(term, startpoint, self); + + if(termValue) + // one term true -> OR of all is true + return !booleanExpression.isNegated(); + } + // if arrived here, all terms evaluate to 'false' + return booleanExpression.isNegated(); + } + else + throw new OclEvaluatorException( + "Selection Condition has invalid type: " + + condition); + } + + protected Object evaluateLiteral(Literal literal) + throws OclEvaluatorException + { + if (literal instanceof BooleanLiteral) + { + BooleanLiteral booleanLiteral = (BooleanLiteral) literal; + + return booleanLiteral.getValue(); + } + else if (literal instanceof IntLiteral) + { + IntLiteral intLiteral = (IntLiteral) literal; + + return intLiteral.getValue(); + } + else if (literal instanceof StringLiteral) + { + StringLiteral stringLiteral = (StringLiteral) literal; + + return stringLiteral.getValue(); + } + else + throw new OclEvaluatorException( + "literal of unknown type: " + + literal); + + } + + + public String removeHeadingWhitespace(String s) + { + while(s!= null && s.length()>0 + && ((s.charAt(0) == ' ') + || (s.charAt(0) == '\n'))) + { + s = s.substring(1); + } + return s; + } + + public String removeTrailingWhitespace(String s) + { + while(s!= null && s.length()>0 + && ((s.charAt(s.length()-1) == ' ') + || (s.charAt(s.length()-1) == '\n'))) + { + s = s.substring(0, s.length()-1); + } + return s; + } + + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OclExpressionsParser.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OclExpressionsParser.java new file mode 100644 index 0000000..b0da3cc --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OclExpressionsParser.java @@ -0,0 +1,686 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +import java.util.Iterator; +import java.util.LinkedList; + +import org.omg.uml.foundation.core.AssociationEnd; + +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; + +/** + * + */ +public class OclExpressionsParser +{ +// public static String OPENING_BRACKET = "["; +// public static String CLOSING_BRACKET = "]"; + + public static String OPENING_PARANTHESIS_REGEX = "\\("; + public static String CLOSING_PARANTHESIS_REGEX = "\\)"; + + public static char OPENING_PARANTHESIS_CHAR= '('; + public static char CLOSING_PARANTHESIS_CHAR = ')'; + + public static String EQUAL_SIGN = "="; + public static String NOT_EQUAL_SIGN = "<>"; + + public static String ARROW = "->"; + public static String DOT = "."; + + public static String SELF= "self"; + + public static String OPERATOR_SELECT = "select"; + public static String SET_OPERATOR_UNION = "union"; + public static String SET_OPERATOR_INTERSECT = "intersect"; + public static String SET_OPERATOR_MINUS = "minus"; + + public static String booleanOrRegexp = " or "; + public static String booleanAndRegexp = " and "; + public static String booleanNotRegexp = "not "; + + MultiContextLogger logger = MultiContextLogger.getDefault(); + +// public Collection parsePathList(String s) +// { +// LinkedList paths = new LinkedList(); +// +// String[] pathStrings = s.split(";"); +// +// for (int i = 0; i < pathStrings.length; i++) +// { +// Path p = parsePath(pathStrings[i]); +// +// paths.add(p); +// } +// +// return paths; +// } + + public OclExpression parseOclExpression(String expressionString) + { + //logger.info("ocl = '"+expressionString+"'"); + String s = expressionString; + + s = removeHeadingWhitespace(s); + + + OclExpression oclExpression = new OclExpression(); + + if(s.startsWith(SELF)) + { + oclExpression.appendStep(new Self()); + + s = s.substring(SELF.length()); + } + else + { + s = "." + s; + } + + s = removeHeadingWhitespace(s); + String rest = s; + + while(s.length() > 0) + { + String operator = null; + if(s.startsWith(DOT)) + { + operator = DOT; + rest = s.substring(DOT.length()); + + } + else if(s.startsWith(ARROW)) + { + operator = ARROW; + rest = s.substring(ARROW.length()); + + } + else + { + logger.error("invalid path String: '" + + s + "'"); + break; + } + + + if(operator == DOT) + // parse PropertyAccessStep + { + int nextDotIndex = rest.indexOf(DOT); + int nextEqualSignIndex = rest.indexOf(ARROW); + + + int stepEnd = + getMinIndex(nextDotIndex, nextEqualSignIndex); + if(stepEnd == -1) + { + if(rest.length()>0) + // case of the last step in expression + stepEnd = rest.length(); + else + logger.error("invalid rest of expression: " + s); + } + + String stepString = rest.substring(0, stepEnd); + + PropertyAccessStep step = + parsePropertyAccessStep(stepString); + //new PropertyAccessStep(propertyName); + + oclExpression.appendStep(step); + + s = rest.substring(stepEnd); + s.toString(); + } + else if(operator == ARROW) + // parse OperationStep + { + int contentStart = 1 + + rest.indexOf(OPENING_PARANTHESIS_CHAR); + // note, when using OPENING_PARANTHESIS_REGEX, it does not work + // (result is always index = -1) + + String operatorName = rest.substring(0, contentStart-1); + + // cut start including the opening bracket + rest = rest.substring(contentStart); + + int closingBracketIndex = + findMatchingClosingParanthesesIndex(rest); + + String contentString = + rest.substring(0, closingBracketIndex); + + OperationStep selectionStep = null; + + selectionStep = + parseSetOperationStep( + operatorName, contentString); + + //parseSelectionStep(contentString); + + oclExpression.appendStep(selectionStep); + + s = rest.substring(closingBracketIndex+1); + } + } + +// logger.info("OCL Expression parsed: " +// + oclExpression.toString()); + return oclExpression; + } + + /** + * @param int1 + * @param int2 + * @return the minimum + */ + private int getMinIndex(int int1, int int2) + { + int minIndex = -1; + + if(int1 == -1) + { + minIndex = int2; + } + else if(int2 == -1) + { + minIndex = int1; + } + else + { + return Math.min(int1, int2); + } + return minIndex; + } + + public int findMatchingClosingParanthesesIndex(String s) + { + int depth = 1; + + int startIndex = 0; + + while(s.length() > 0 && depth > 0) + { + int paranthesesIndex = getMinIndex( + s.indexOf(OPENING_PARANTHESIS_CHAR, startIndex), + s.indexOf(CLOSING_PARANTHESIS_CHAR, startIndex)); + + if(paranthesesIndex == -1) + { + logger.error("invalid rest of expression: " + s); + } + else + startIndex = paranthesesIndex; + + //s = s.substring(paranthesesIndex); + + if(s.substring(startIndex). + charAt(0) == OPENING_PARANTHESIS_CHAR) + { + depth++; + } + else if(s.substring(startIndex). + charAt(0) == (CLOSING_PARANTHESIS_CHAR)) + { + depth--; + + if(depth == 0) + return startIndex; + } + startIndex++; + + } + return -1; + } + + + + public PropertyAccessStep parsePropertyAccessStep(String stepString) + { + PropertyAccessStep step = new PropertyAccessStep(stepString); + + int asterixIndex = stepString.lastIndexOf("*"); + + + if(asterixIndex < 0) + // there is no * + { + step.setRepetition(1); + } + else // there is a * + { + String afterAsterix = stepString.substring(asterixIndex + 1); + + if(afterAsterix == null || afterAsterix.length()==0) + // * the last character -> n times + { + step.setRepetition(-1); + + // asterix is handled, cut it + stepString = stepString.substring(0, asterixIndex); + + } + else + // i.e. the * corresponds to this step, + { + int repetition = Integer.parseInt(afterAsterix); + step.setRepetition(repetition); + + // asterix and number handled, cut'em + stepString = stepString.substring(0, asterixIndex); + } + } + + // repetition handled if there + + + step.setPropertyName(stepString); + + // step itself handled + + + return step; + } + + public OperationStep parseSetOperationStep( + String operatorName, String contentString) + { + if(operatorName.equals(OPERATOR_SELECT)) + { + return parseSelectionStep(contentString); + } + else + { + OclExpression expression = parseOclExpression(contentString); + + SetOperationStep step = null; + + if(operatorName.equals(SET_OPERATOR_UNION)) + { + step = new SetOperationStep(SET_OPERATOR_UNION, expression); + } + else if(operatorName.equals(SET_OPERATOR_INTERSECT)) + { + step = new SetOperationStep(SET_OPERATOR_INTERSECT, expression); + } + else if(operatorName.equals(SET_OPERATOR_MINUS)) + { + step = new SetOperationStep(SET_OPERATOR_MINUS, expression); + } + else + { + logger.error("invalid Set Operator: " + operatorName); + } + + return step; + } + + } + + public SelectionStep parseSelectionStep( + String conditionString) + // throws OclParserException + { + SelectionStep result = new SelectionStep(); + + ExpressionFragment condition = parseCondition(conditionString); + + result.setCondition(condition); + + //Literal literal = PathFactory.createLiteral(conditionString); + + return result; + } + + /** + * @param conditionString + */ + private ExpressionFragment parseCondition(String conditionString) + //, SelectionStep result) + { + conditionString = removeOuterParanthesis(conditionString); + + LinkedList orParts = + splitConditionString(conditionString, booleanOrRegexp); + + if(orParts.size() > 1) + { + DisjunctiveBooleanExpression orExpression = + new DisjunctiveBooleanExpression(); + for (Iterator iter = orParts.iterator(); iter.hasNext();) + { + String orPartString = (String) iter.next(); + + ExpressionFragment orPart = + parseCondition(orPartString); + + //parseExpressionOrLiteral(orPartString); + + orExpression.getTerms().add(orPart); + + + } + + return orExpression; + } + else + { + LinkedList andParts = + splitConditionString(conditionString, booleanAndRegexp); + + if(andParts.size() > 1) + { + ConjunctiveBooleanExpression andExpression = + new ConjunctiveBooleanExpression(); + for (Iterator iter = orParts.iterator(); iter.hasNext();) + { + String andPartString = (String) iter.next(); + + ExpressionFragment andPart = + //parseExpressionOrLiteral(andPartString); + parseCondition(andPartString); + + andExpression.getTerms().add(andPart); + } + return andExpression; + } + else + { + if(conditionString.startsWith(booleanNotRegexp)) + { + conditionString = + conditionString.substring(booleanNotRegexp.length()); + + ExpressionFragment expr = + parseCondition(conditionString); + // parseExpressionOrLiteral(conditionString); + + ConjunctiveBooleanExpression negatedExpression = + new ConjunctiveBooleanExpression(); + negatedExpression.setNegated(true); + negatedExpression.getTerms().add(expr); + + return negatedExpression; + } + else + { + // now, all ands-, ors and such stuff is out + + String equalitySignsRegexp = "=|\\<\\>"; + + + LinkedList equalityExpressions = + splitConditionString(conditionString, equalitySignsRegexp); + + ExpressionFragment expressionFragment = + parseEquation(conditionString, equalityExpressions); + + return expressionFragment; + } + } + } + + + + } + + + + /** + * @param conditionString + * @param equalityExpressions + */ + private ExpressionFragment parseEquation( + String conditionString, LinkedList equalityExpressions) + //throws OclParserException + { + if(equalityExpressions.size() == 1) + // no equality sign on this level + // -> expressionOrLiteral + { + ExpressionFragment expressionFragment = + parseExpressionOrLiteral( + equalityExpressions.get(0)); + + return expressionFragment; + } + else if (equalityExpressions.size() == 2) + { + ExpressionFragment pathFragment1 = + parseExpressionOrLiteral( + equalityExpressions.get(0)); + + ExpressionFragment pathFragment2 = + parseExpressionOrLiteral( + equalityExpressions.get(1)); + + String comparatorSign = + conditionString.substring(equalityExpressions.get(0).length(), + conditionString.length() - equalityExpressions.get(1).length()); + + boolean isEqual = true; + if(comparatorSign.equals(EQUAL_SIGN)) + isEqual = true; + else if(comparatorSign.equals(NOT_EQUAL_SIGN)) + isEqual = false; + else + { + logger.error("invalid selection Condition Equation: " + + " comparatorSign is: " + comparatorSign); + } + + Equation equation = + new Equation(pathFragment1, pathFragment2, isEqual); + + return equation; + } + else + { + logger.error("invalid PathSelector Condition: " + + conditionString); +// throw new OclParserException( +// "invalid PathSelector Condition: " +// + conditionString); + return null; + } + + } + + public String removeHeadingWhitespace(String s) + { + while(s != null && s.length() > 0 + && ((s.charAt(0) == ' ') + || (s.charAt(0) == '\n'))) + { + s = s.substring(1); + } + return s; + } + + public String removeTrailingWhitespace(String s) + { + while(s != null && s.length() >0 + && ((s.charAt(s.length()-1) == ' ') + || (s.charAt(s.length()-1) == '\n'))) + { + s = s.substring(0, s.length()-1); + } + return s; + } + + + + /** remove the outer paranthesis of a String, + * if represent a pair + * + * @param string + * @return the transformed string + */ + public String removeOuterParanthesis(String string) + { + String s = string; + + if(s.length() > 1 + && s.charAt(0) == OPENING_PARANTHESIS_CHAR + && s.charAt(s.length()-1) == CLOSING_PARANTHESIS_CHAR) + { + int depth = 0; + + int indexOpen = s.indexOf(OPENING_PARANTHESIS_REGEX); + int indexClose = s.indexOf(CLOSING_PARANTHESIS_REGEX); + + while(indexOpen > 0 && indexClose > 0) + { + if(indexOpen splitConditionString( + String conditionString, String splitRegexp) + { + String[] conditionPartStrings = + conditionString.split(splitRegexp); + + + LinkedList result = new LinkedList(); + + int bracketDepth = 0; + + if(conditionPartStrings.length == 1) + // no equality sign + // -> expressionOrLiteral + { + result.add(conditionPartStrings[0]); +// ExpressionFragment condition = +// parseExpressionOrLiteral(equationPartStrings[0]); +// +// result.setCondition(condition); + } + if(conditionPartStrings.length >= 2) + // one or more equality signs + { + for (int i = 0; i < conditionPartStrings.length; i++) + { + String partString = conditionPartStrings[i]; + + + bracketDepth = countBrackets(partString); + if(bracketDepth == 0) + result.add(partString); + else + { + // join with n next segments, until bracketDepth is 0 + + while(bracketDepth != 0) + { + // the whole part is stored at allparts[i] + bracketDepth += countBrackets(conditionPartStrings[i+1]); + + conditionPartStrings[i+1] = conditionPartStrings[i] + conditionPartStrings[i+1]; + // now the whole part is stored at allparts[i+1] + i++; + + } + // the whole part is stored at allparts[i] + + result.add(conditionPartStrings[i]); + + } + } + } + + return result; + } + + /** + * @param s + */ + public ExpressionFragment parseExpressionOrLiteral(String s) + { + s = removeHeadingWhitespace(s); + s = removeTrailingWhitespace(s); + + Literal literal = tryParseLiteral(s); + if(literal != null) + return literal; + else + { + OclExpression p = parseOclExpression(s); + + return p; + } + } + + public Literal tryParseLiteral(String s) + { + Literal l = ExpressionFactory.createLiteral(s); + return l; + } + + + public int countBrackets(String s) + { + if(s == null || s.length() == 0) + return 0; + + int depth = 0; + + int indexOpen = s.indexOf(OPENING_PARANTHESIS_REGEX); + int indexClose = s.indexOf(CLOSING_PARANTHESIS_REGEX); + + while(indexOpen > 0 && indexClose > 0) + { + if(indexOpen resourcePath = + new ArrayList(); + + // Resource -> ResourcePath + Map resourcePaths = + new LinkedHashMap(); + + DialectMetaModelInfo dialectMetaModelInfo; + MetaModelClass metaModelClass; + + /* (non-Javadoc) + * @see ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions.OclExpressionEvaluator#takePropertyAccessStep(java.util.Set, ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions.PropertyAccessStep, java.util.Set) + */ + @Override + protected void takePropertyAccessStep(Set result, PropertyAccessStep paStep, Set startPoints) throws OclEvaluatorException + { + // TODO Auto-generated method stub + //super.takePropertyAccessStep(result, paStep, startPoints); + + String propertyName = paStep.getPropertyName(); + propertyName = removeHeadingWhitespace(propertyName); + propertyName = removeTrailingWhitespace(propertyName); + +// logger.info("evaluatePathExpression - step: " + paStep ); + +// logger.info( +// "evaluating OclUmlExpression on Resource of type '" +// + metaModelClass.getName()); + + // boolean stepTaken = false; + + + for (Iterator iter = startPoints.iterator(); iter.hasNext();) + { + ModelElement startPoint = (ModelElement) iter.next(); + + Collection/**/ iterationResults = + new LinkedList/**/(); + + String resourcePathSoFar = resourcePaths.get(startPoint); + +// MetaModelClass metaModelClass = +// GenericDialectHelper.getInstance(). +// getMetaModelClass(startPoint); + +// logger.info("metamodelClass = " +// + metaModelClass.getName()); + + Collection associations = dialectMetaModelInfo + .getInterResourceAssociations(metaModelClass); + + Collection res = null; + //modelElement = null; + + if(associations == null) + return; + + for (Iterator it = associations.iterator(); it.hasNext();) + { + InterResourceAssociation association = + (InterResourceAssociation) it.next(); + +// ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel. +// AssociationEnd otherEnd = +// association.getOtherEnd(metaModelClass); + + ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel. + AssociationEnd end1 = association.getEnd1(); + ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel. + AssociationEnd end2 = association.getEnd2(); + + + try + { + if(paStep.getPropertyName().equals( + end1.getName())) + { + res = takePathStep( + startPoint, propertyName, end1, null); + if(res==null) { + logger.error("takePathStep failed."); + } else { + iterationResults.addAll(res); + } + } + else if(paStep.getPropertyName().equals( + end2.getName())) + { + //modelElement + res = takePathStep( + startPoint, propertyName, end2, null); + if(res==null) { + logger.error("takePathStep failed."); + } else { + iterationResults.addAll(res); + } +// else if(res instanceof ModelElement) +// { +// iterationResults.add(res); +// } + //else + { + // logger.warn("accessing Property " + // + paStep.getPropertyName() + // + " on Object of Type: " + // + startPoint.getClass().getSimpleName() + // + " returned null"); + } + } + } + catch (Exception e) + { + logger.error("accessing Property " + + paStep.getPropertyName() + + " on Object of Type: " + + startPoint.getClass().getSimpleName() + + " failed"); + + logger.logException(e); + } + } + if(iterationResults.size() == 0) + /* if this is the case, the property is not a + * defined association, + * but it could be an attribute -> try it + */ + { + try + { + Object o = Util.tryGetProperty( + startPoint, paStep.getPropertyName()); + + if (o instanceof Collection) + { + Collection values = (Collection) o; + iterationResults.addAll(values); + } + else if(o != null) + { +// logger.info(startPoint.getName() +// + "." + paStep.getPropertyName() +// + " = " + o); + iterationResults.add(/*(ModelElement)*/o); + } + } + catch (Exception e) + { + //logger.logException(e); + } + } + if(iterationResults.size() == 0) + { + logger.warn( + "accessing Property " + + paStep.getPropertyName() + + " on Object of Type: " + + startPoint.getClass().getSimpleName() + + " " + startPoint.getName() + + " returned null"); + } + + result.addAll(iterationResults); + + // uptdate ResourcePaths + + for (Iterator iterator = iterationResults.iterator(); iter.hasNext();) + { + Object item = iterator.next(); + + if(item instanceof ModelElement) + { + ModelElement m = (ModelElement) item; + + resourcePaths.put(m, resourcePathSoFar + m.getName()); + + logger.info("put resourcePath: " + + m.getName() + " -> " + resourcePathSoFar+m.getName()); + } + } + } + } + + /** + * @param modelElement + * @param step + * @param end1 + * @param end2 + * @return ModelElement which is reached by taking the step + */ + private Collection takePathStep( + ModelElement modelElement, + String step, + ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel. + AssociationEnd end1, + ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel. + AssociationEnd end2) + { + Collection c = null; + c = navigateAssociation(modelElement, end1, end2); + + + if (c == null) { + logger.error("navigateAssociation results in null"); + return null; + } + else + // if (c instanceof Collection) + { + /* + * consider only the first element - anchor path must be unique + */ + Collection collection = (Collection) c; + +// if (collection.size() > 1) +// { +// logger.error(MultiContextLogger.MODELMAPPER, +// "Anchor Path Step: " + step + " not unique."); +// //return null; +// } + /*else*/ + if (collection.size() == 0) + { + logger.error(MultiContextLogger.MODELMAPPER, + "Anchor Path Step: " + step + "could not be followed."); + //return null; + } + else + // collection.size >= 1 + { + Object o = collection.iterator().next(); + if (o instanceof ModelElement) + { + modelElement = (ModelElement) o; + + resourcePath.add(0, modelElement); + +// if (resourcePath == null +// || resourcePath.length() == 0) +// { +// //resourcePath = modelElement.getName(); +// +// } +// else +// { +//// resourcePath = modelElement.getName() + "." +//// + resourcePath; +// } + + logger.info(OCL_EXPRESSION_EVALUATOR_DETAILLED, + "step taken: " + + step + + ", resourcePath so far: " + + getResourcePath()); + //break; + } + } + } + return c; + } + + /** + * @param from + * @param end1 + * @param end2 + * @return if the Association could not be navigated, + * 'null' is returned + */ + public Collection navigateAssociation( + ModelElement from, + ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel. + AssociationEnd end1, + ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel. + AssociationEnd end2 + ) + { + ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel. + AssociationEnd usedEnd = null; + + logger.info("from = "+from.getName()); + logger.info("end1 = "+end1.getName()); + + Object result = null; + try + { + String methodName = null; + Method umlPropertyGetter = null; + + try + { + methodName = end1.getUmlPropertyGetter(); + umlPropertyGetter = from.getClass().getMethod(methodName, + new Class[0]); + logger.info(//OCL_EXPRESSION_EVALUATOR_DETAILLED, + "found UMLPropertyGetter: " + + from.getName() + "." + + umlPropertyGetter); + usedEnd = end1; + } + catch (Exception e1) + { + logger.error("no method '" + + methodName + "' on " + from.getClass()); + // TODO: handle exception + //e.printStackTrace(); + try + { + methodName = end2.getUmlPropertyGetter(); + umlPropertyGetter = from.getClass().getMethod(methodName, + new Class[0]); + logger.info(//OCL_EXPRESSION_EVALUATOR_DETAILLED, + "found UMLPropertyGetter: " + + from.getName() + "." + + umlPropertyGetter); + usedEnd = end2; + } + catch (Exception e2) + { + logger.error("no method '" + + methodName + "' on " + from.getClass()); + // TODO: handle exception + //e.printStackTrace(); + } + } + +// AssociationEnd end; +// end.getParticipant(); + + + result = umlPropertyGetter.invoke(from, new Object[0]); + + if(usedEnd != null) + { + logger.info(//OCL_EXPRESSION_EVALUATOR_DETAILLED, + "navigated AssociationEnd successfully: " + + usedEnd); + + if(result instanceof Collection) + logger.info(//OCL_EXPRESSION_EVALUATOR_DETAILLED, + "... returned a result set of size " + + ((Collection)result).size()); + else + logger.info(//OCL_EXPRESSION_EVALUATOR_DETAILLED, + "... returned result: " + result); + + + metaModelClass = usedEnd.getType(); + + + } + else + { + logger.error( + "could not navigate Association: " + + end1.getOwner()); + } + + // if (result instanceof Collection) + // { + // // only consider the first element + // result = ((Collection) result).iterator().next(); + // } + + // if (result instanceof ModelElement) + // { + // modelElement = (ModelElement) result; + // + // } + } + catch (Exception e1) + { + //logger.logException(e1); + + // try the other associationEnd +// try +// { +// targetAssociationEnd = +// targetAssociationEnd.getOwner().getOtherEnd(targetAssociationEnd.getType()); +// methodName = +// targetAssociationEnd.getUmlPropertyGetter(); +// +// Method umlPropertyGetter = from.getClass().getMethod(methodName, +// new Class[0]); +// +// result = umlPropertyGetter.invoke(from, new Object[0]); +// } +// catch (Exception e2) +// { +// if(e1 != null && e2 != null) +// { +// logger.logException(e1); +// logger.logException(e2); +// } +// +// } + + + } + + if (result instanceof Collection) + return (Collection) result; + else if (result != null) + { + LinkedList l = new LinkedList(); + + l.add(result); + + return l; + } + else + return null; + } + + /** + * @return the resourcePath + */ + public String getResourcePath() + { + if(resourcePath.size() == 0) + { + return ""; + } + + // ugly, non-generic hack + //int nofSteps = 2; + + // generic solution, does not work correctly + int i = 0; + int nofSteps = resourcePath.size(); + for (Iterator iter = resourcePath.iterator(); + iter.hasNext();) + { + ModelElement m = (ModelElement) iter.next(); + + int firstOccurrence = resourcePath.indexOf(m); + + if(firstOccurrence < i) + // i.e. m occurred before + { + nofSteps = firstOccurrence+1; + break; + } + i++; + } + + String resourcePathString = + resourcePath.get(0).getName(); + for (int j = 1; j < nofSteps; j++) + { + resourcePathString += "." + resourcePath.get(j).getName(); + } + +// ugly, non-generic hack + // gets Association-End Permissions' resource Path always right + if(nofSteps >2) + { + resourcePathString = resourcePath.get(0).getName() + + "." + resourcePath.get(nofSteps-1).getName(); + } + return resourcePathString; + } + + /** + * @return the resourcePaths + */ + public Map getResourcePaths() + { + return resourcePaths; + } + + /** + * @param resourcePath the resourcePath to set + */ +// public void setResourcePath(String resourcePath) +// { +// this.resourcePath = resourcePath; +// } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OperationStep.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OperationStep.java new file mode 100644 index 0000000..1dec6bc --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/OperationStep.java @@ -0,0 +1,12 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +/** + * + */ +public class OperationStep extends PathStep +{ + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/Path.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/Path.java new file mode 100644 index 0000000..b43fba3 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/Path.java @@ -0,0 +1,39 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +import java.util.Collection; +import java.util.LinkedList; + +/** + * + */ +public class Path extends PathFragment +{ + /** + * + */ + public Path() + { + + } + + private LinkedList steps = new LinkedList(); + + public Collection getSteps() + { + return steps; + } + +// public void setSteps(Collection steps) +// { +// this.steps = steps; +// } + + public void appendStep(PathStep step) + { + steps.add(step); + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/PathFactory.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/PathFactory.java new file mode 100644 index 0000000..e508bb4 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/PathFactory.java @@ -0,0 +1,71 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +/** + * + */ +public class PathFactory +{ + public static String TRUE = "true"; + public static String FALSE = "false"; + + /** If s represents a literal, a literal of the corresponding + * type is created and returned + * - null is returned otherwise. + * + * @param s + * @return the created Literal + */ + public static Literal createLiteral(String s) + { + if(s == null | s.length() == 0) + return null; + else if(s.equals(TRUE)) + { + return new BooleanLiteral(true); + } + else if(s.equals(FALSE)) + { + return new BooleanLiteral(false); + } + else if(Character.isDigit(s.charAt(0))) + // Int or Decimal Literal + { + String[] parts = s.split("\\."); + if(parts.length == 1) + // doesn't contain a dot + { + int intValue = Integer.valueOf(parts[0]); + return new IntLiteral(intValue); + } + else if (parts.length == 2) + { + double doubleValue = Double.valueOf(s); + return new DecimalLiteral(doubleValue); + } + } + else if(isQuoteOrDoubleQuote(s.charAt(0)) + && isQuoteOrDoubleQuote(s.charAt(s.length()-1))) + { + String literalString = s.substring(1, s.length()-1); + return new StringLiteral(literalString); + } + + return null; + } + + public static boolean isQuoteOrDoubleQuote(char c) + { + Character character = Character.valueOf(c); + Character doubleQuoteChar = "\"".charAt(0); + Character quoteChar = "'".charAt(0); + + boolean result = character.equals(quoteChar) + || character.equals(doubleQuoteChar); + + return result; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/PathFragment.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/PathFragment.java new file mode 100644 index 0000000..b203188 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/PathFragment.java @@ -0,0 +1,12 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +/** + * + */ +public class PathFragment +{ + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/PathStep.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/PathStep.java new file mode 100644 index 0000000..8d86afd --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/PathStep.java @@ -0,0 +1,20 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +/** + * + */ +public class PathStep extends ExpressionFragment +{ + /** + * + */ + public PathStep() + { + + } + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/PropertyAccessStep.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/PropertyAccessStep.java new file mode 100644 index 0000000..df46bd3 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/PropertyAccessStep.java @@ -0,0 +1,67 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +/** + * + * access of a property (Attribute or AssociationEnd) + * through the '.' Operator + */ +public class PropertyAccessStep extends PathStep +{ + /** + * + */ + public PropertyAccessStep(String propertyName) + { + this.propertyName = propertyName; + } + + + private String propertyName; + + // the value of the step + // - i.e. name of the Property to access + public String getPropertyName() + { + return propertyName; + } + + public void setPropertyName(String value) + { + this.propertyName = value; + } + + private int repetition; + + /** repetition: specifies how many time, this step + * is to be repeated. + * n = 0, 1, 2, ... stands for n repetitions, + * n = -1 stands for (0 - \infinity) repetitions + * + * @return the number of repitions + */ + public int getRepetition() + { + return repetition; + } + + public void setRepetition(int repetition) + { + this.repetition = repetition; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + return "PropertyAccessStep(" + + propertyName + + ((repetition == -1)?"*":("*"+repetition)) + + ")"; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/SelectionStep.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/SelectionStep.java new file mode 100644 index 0000000..96c23e8 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/SelectionStep.java @@ -0,0 +1,47 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +/** + * + * + * + */ +public class SelectionStep extends OperationStep +{ + /** + * + */ + public SelectionStep()//PathFragment condition) + { + //this.condition = condition; + } + + private ExpressionFragment condition; + + /** can be a BooleanLiteral, + * a OCL-Expression that evaluates to a boolean + * or an equation + * + * @return the OCL condition expression + */ + public ExpressionFragment getCondition() + { + return condition; + } + + public void setCondition(ExpressionFragment condition) + { + this.condition = condition; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + return "SelectionStep("+condition+")"; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/Self.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/Self.java new file mode 100644 index 0000000..9e87faa --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/Self.java @@ -0,0 +1,19 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +/** + * + */ +public class Self extends PathStep +{ + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + return "Self"; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/SetOperationStep.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/SetOperationStep.java new file mode 100644 index 0000000..efe98e8 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/SetOperationStep.java @@ -0,0 +1,54 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +/** + * + * set Operation between the current result set and + * the set resulting from the evaluation of 'expression' + * + */ +public class SetOperationStep extends OperationStep +{ + public SetOperationStep(String setOperation, OclExpression expression) + { + this.operation = setOperation; + + this.expression = expression; + } + + private String operation; + + public String getOperation() + { + return operation; + } + + public void setOperation(String operation) + { + this.operation = operation; + } + + private OclExpression expression; + + public OclExpression getExpression() + { + return expression; + } + + public void setExpression(OclExpression expression) + { + this.expression = expression; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + return "SetOperationStep( " + operation + " " + + expression +" )"; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/StringLiteral.java b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/StringLiteral.java new file mode 100644 index 0000000..3e854a8 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/StringLiteral.java @@ -0,0 +1,40 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.securemodel.dialects.parser.oclexpressions; + +/** + * + */ +public class StringLiteral extends Literal +{ + /** + * + */ + public StringLiteral(String value) + { + this.value = value; + } + + private String value; + + public String getValue() + { + return value; + } + + public void setValue(String value) + { + this.value = value; + } + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + return "StringLiteral("+value+")"; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/package.html b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/package.html new file mode 100644 index 0000000..17dc5a4 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/oclexpressions/package.html @@ -0,0 +1,11 @@ + + + + + +Naive OCL expression parser and evaluator. + +Just enough to parse and evaluate the expressions we use as +annotations in the SecureUML dialect metamodels. + + diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/package.html b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/package.html new file mode 100644 index 0000000..bddf709 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/dialects/parser/package.html @@ -0,0 +1,7 @@ + + + + +Deals with the information in SecureUML dialect metamodels. + + diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/package.html b/src/ch/ethz/infsec/secureumlgui/securemodel/package.html new file mode 100644 index 0000000..d605353 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/package.html @@ -0,0 +1,8 @@ + + + + + +Deals with the information in SecureUML (and its dialects) metamodels. + + diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Action.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Action.java new file mode 100644 index 0000000..5c747ae --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Action.java @@ -0,0 +1,43 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * Action object instance interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface Action { //extends javax.jmi.reflect.RefObject + /** + * Returns the value of attribute name. + * @return Value of attribute name. + */ + public java.lang.String getName(); + /** + * Sets the value of name attribute. See {@link #getName} for description + * on the attribute. + * @param newValue New value to be set. + */ + public void setName(java.lang.String newValue); + /** + * Returns the value of reference superActions. + * @return Value of reference superActions. Element type: {@link ch.ethz.infsec.secureumlgui.securemodel.secureuml.CompositeAction} + */ + public java.util.Collection/**/ getSuperActions(); + /** + * Returns the value of reference permission. + * @return Value of reference permission. Element type: {@link ch.ethz.infsec.secureumlgui.securemodel.secureuml.Permission} + */ + public java.util.Collection/**/ getPermission(); + /** + * Returns the value of reference resource. + * @return Value of reference resource. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.Resource getResource(); + /** + * Sets the value of reference resource. See {@link #getResource} for description + * on the reference. + * @param newValue New value to be set. + */ + public void setResource(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Resource newValue); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/ActionClass.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/ActionClass.java new file mode 100644 index 0000000..0c10c9d --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/ActionClass.java @@ -0,0 +1,11 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * Action class proxy interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface ActionClass extends javax.jmi.reflect.RefClass { +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/ActionHierarchy.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/ActionHierarchy.java new file mode 100644 index 0000000..1200acc --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/ActionHierarchy.java @@ -0,0 +1,47 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * ActionHierarchy association proxy interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface ActionHierarchy extends javax.jmi.reflect.RefAssociation { + /** + * Queries whether a link currently exists between a given pair of instance + * objects in the associations link set. + * @param superActions Value of the first association end. + * @param subactions Value of the second association end. + * @return Returns true if the queried link exists. + */ + public boolean exists(ch.ethz.infsec.secureumlgui.securemodel.secureuml.CompositeAction superActions, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Action subactions); + /** + * Queries the instance objects that are related to a particular instance + * object by a link in the current associations link set. + * @param subactions Required value of the second association end. + * @return Collection of related objects. + */ + public java.util.Collection getSuperActions(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Action subactions); + /** + * Queries the instance objects that are related to a particular instance + * object by a link in the current associations link set. + * @param superActions Required value of the first association end. + * @return Collection of related objects. + */ + public java.util.Collection getSubactions(ch.ethz.infsec.secureumlgui.securemodel.secureuml.CompositeAction superActions); + /** + * Creates a link between the pair of instance objects in the associations + * link set. + * @param superActions Value of the first association end. + * @param subactions Value of the second association end. + */ + public boolean add(ch.ethz.infsec.secureumlgui.securemodel.secureuml.CompositeAction superActions, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Action subactions); + /** + * Removes a link between a pair of instance objects in the current associations + * link set. + * @param superActions Value of the first association end. + * @param subactions Value of the second association end. + */ + public boolean remove(ch.ethz.infsec.secureumlgui.securemodel.secureuml.CompositeAction superActions, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Action subactions); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/ActionResourceAssignment.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/ActionResourceAssignment.java new file mode 100644 index 0000000..fd5f87a --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/ActionResourceAssignment.java @@ -0,0 +1,47 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * ActionResourceAssignment association proxy interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface ActionResourceAssignment extends javax.jmi.reflect.RefAssociation { + /** + * Queries whether a link currently exists between a given pair of instance + * objects in the associations link set. + * @param action Value of the first association end. + * @param resource Value of the second association end. + * @return Returns true if the queried link exists. + */ + public boolean exists(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Action action, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Resource resource); + /** + * Queries the instance objects that are related to a particular instance + * object by a link in the current associations link set. + * @param resource Required value of the second association end. + * @return Collection of related objects. + */ + public java.util.Collection getAction(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Resource resource); + /** + * Queries the instance object that is related to a particular instance object + * by a link in the current associations link set. + * @param action Required value of the first association end. + * @return Related object or null if none exists. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.Resource getResource(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Action action); + /** + * Creates a link between the pair of instance objects in the associations + * link set. + * @param action Value of the first association end. + * @param resource Value of the second association end. + */ + public boolean add(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Action action, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Resource resource); + /** + * Removes a link between a pair of instance objects in the current associations + * link set. + * @param action Value of the first association end. + * @param resource Value of the second association end. + */ + public boolean remove(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Action action, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Resource resource); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/AtomicAction.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/AtomicAction.java new file mode 100644 index 0000000..fd0d26f --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/AtomicAction.java @@ -0,0 +1,11 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * AtomicAction object instance interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface AtomicAction extends ch.ethz.infsec.secureumlgui.securemodel.secureuml.Action { +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/AtomicActionClass.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/AtomicActionClass.java new file mode 100644 index 0000000..5ffdc95 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/AtomicActionClass.java @@ -0,0 +1,23 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * AtomicAction class proxy interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface AtomicActionClass extends javax.jmi.reflect.RefClass { + /** + * The default factory operation used to create an instance object. + * @return The created instance object. + */ + public AtomicAction createAtomicAction(); + /** + * Creates an instance object having attributes initialized by the passed + * values. + * @param name + * @return The created instance object. + */ + public AtomicAction createAtomicAction(java.lang.String name); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/AuthorizationConstraint.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/AuthorizationConstraint.java new file mode 100644 index 0000000..b38542a --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/AuthorizationConstraint.java @@ -0,0 +1,38 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * AuthorizationConstraint object instance interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface AuthorizationConstraint { //extends javax.jmi.reflect.RefObject + /** + * Returns the value of attribute name. + * @return Value of attribute name. + */ + public java.lang.String getName(); + /** + * Sets the value of name attribute. See {@link #getName} for description + * on the attribute. + * @param newValue New value to be set. + */ + public void setName(java.lang.String newValue); + /** + * Returns the value of attribute constraint. + * @return Value of attribute constraint. + */ + public java.lang.String getConstraint(); + /** + * Sets the value of constraint attribute. See {@link #getConstraint} for + * description on the attribute. + * @param newValue New value to be set. + */ + public void setConstraint(java.lang.String newValue); + /** + * Returns the value of reference permission. + * @return Value of reference permission. Element type: {@link ch.ethz.infsec.secureumlgui.securemodel.secureuml.Permission} + */ + public java.util.Collection/**/ getPermission(); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/AuthorizationConstraintClass.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/AuthorizationConstraintClass.java new file mode 100644 index 0000000..bf848f2 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/AuthorizationConstraintClass.java @@ -0,0 +1,24 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * AuthorizationConstraint class proxy interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface AuthorizationConstraintClass extends javax.jmi.reflect.RefClass { + /** + * The default factory operation used to create an instance object. + * @return The created instance object. + */ + public AuthorizationConstraint createAuthorizationConstraint(); + /** + * Creates an instance object having attributes initialized by the passed + * values. + * @param name + * @param constraint + * @return The created instance object. + */ + public AuthorizationConstraint createAuthorizationConstraint(java.lang.String name, java.lang.String constraint); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/CompositeAction.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/CompositeAction.java new file mode 100644 index 0000000..75c358a --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/CompositeAction.java @@ -0,0 +1,16 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * CompositeAction object instance interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface CompositeAction extends ch.ethz.infsec.secureumlgui.securemodel.secureuml.Action { + /** + * Returns the value of reference subactions. + * @return Value of reference subactions. Element type: {@link ch.ethz.infsec.secureumlgui.securemodel.secureuml.Action} + */ + public java.util.Collection/**/ getSubactions(); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/CompositeActionClass.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/CompositeActionClass.java new file mode 100644 index 0000000..fad1e1c --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/CompositeActionClass.java @@ -0,0 +1,23 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * CompositeAction class proxy interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface CompositeActionClass extends javax.jmi.reflect.RefClass { + /** + * The default factory operation used to create an instance object. + * @return The created instance object. + */ + public CompositeAction createCompositeAction(); + /** + * Creates an instance object having attributes initialized by the passed + * values. + * @param name + * @return The created instance object. + */ + public CompositeAction createCompositeAction(java.lang.String name); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/ConstraintAssignment.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/ConstraintAssignment.java new file mode 100644 index 0000000..d224c99 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/ConstraintAssignment.java @@ -0,0 +1,48 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * ConstraintAssignment association proxy interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface ConstraintAssignment extends javax.jmi.reflect.RefAssociation { + /** + * Queries whether a link currently exists between a given pair of instance + * objects in the associations link set. + * @param authorizationConstraint Value of the first association end. + * @param permission Value of the second association end. + * @return Returns true if the queried link exists. + */ + public boolean exists(ch.ethz.infsec.secureumlgui.securemodel.secureuml.AuthorizationConstraint authorizationConstraint, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Permission permission); + /** + * Queries the instance object that is related to a particular instance object + * by a link in the current associations link set. + * @param permission Required value of the second association end. + * @return Related object or null if none exists. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.AuthorizationConstraint getAuthorizationConstraint(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Permission permission); + /** + * Queries the instance objects that are related to a particular instance + * object by a link in the current associations link set. + * @param authorizationConstraint Required value of the first association + * end. + * @return Collection of related objects. + */ + public java.util.Collection getPermission(ch.ethz.infsec.secureumlgui.securemodel.secureuml.AuthorizationConstraint authorizationConstraint); + /** + * Creates a link between the pair of instance objects in the associations + * link set. + * @param authorizationConstraint Value of the first association end. + * @param permission Value of the second association end. + */ + public boolean add(ch.ethz.infsec.secureumlgui.securemodel.secureuml.AuthorizationConstraint authorizationConstraint, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Permission permission); + /** + * Removes a link between a pair of instance objects in the current associations + * link set. + * @param authorizationConstraint Value of the first association end. + * @param permission Value of the second association end. + */ + public boolean remove(ch.ethz.infsec.secureumlgui.securemodel.secureuml.AuthorizationConstraint authorizationConstraint, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Permission permission); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Group.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Group.java new file mode 100644 index 0000000..36d87c9 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Group.java @@ -0,0 +1,11 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * Group object instance interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface Group extends ch.ethz.infsec.secureumlgui.securemodel.secureuml.Subject { +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/GroupClass.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/GroupClass.java new file mode 100644 index 0000000..2638255 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/GroupClass.java @@ -0,0 +1,23 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * Group class proxy interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface GroupClass extends javax.jmi.reflect.RefClass { + /** + * The default factory operation used to create an instance object. + * @return The created instance object. + */ + public Group createGroup(); + /** + * Creates an instance object having attributes initialized by the passed + * values. + * @param name + * @return The created instance object. + */ + public Group createGroup(java.lang.String name); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Permission.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Permission.java new file mode 100644 index 0000000..7431775 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Permission.java @@ -0,0 +1,49 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * Permission object instance interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface Permission extends javax.jmi.reflect.RefObject { + /** + * Returns the value of attribute name. + * @return Value of attribute name. + */ + public java.lang.String getName(); + /** + * Sets the value of name attribute. See {@link #getName} for description + * on the attribute. + * @param newValue New value to be set. + */ + public void setName(java.lang.String newValue); + /** + * Returns the value of reference action. + * @return Value of reference action. Element type: {@link ch.ethz.infsec.secureumlgui.securemodel.secureuml.Action} + */ + public java.util.Collection/**/ getAction(); + /** + * Returns the value of reference role. + * @return Value of reference role. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role getRole(); + /** + * Sets the value of reference role. See {@link #getRole} for description + * on the reference. + * @param newValue New value to be set. + */ + public void setRole(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role newValue); + /** + * Returns the value of reference authorizationConstraint. + * @return Value of reference authorizationConstraint. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.AuthorizationConstraint getAuthorizationConstraint(); + /** + * Sets the value of reference authorizationConstraint. See {@link #getAuthorizationConstraint} + * for description on the reference. + * @param newValue New value to be set. + */ + public void setAuthorizationConstraint(ch.ethz.infsec.secureumlgui.securemodel.secureuml.AuthorizationConstraint newValue); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/PermissionActionAssignment.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/PermissionActionAssignment.java new file mode 100644 index 0000000..5cacc08 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/PermissionActionAssignment.java @@ -0,0 +1,47 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * PermissionActionAssignment association proxy interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface PermissionActionAssignment extends javax.jmi.reflect.RefAssociation { + /** + * Queries whether a link currently exists between a given pair of instance + * objects in the associations link set. + * @param permission Value of the first association end. + * @param action Value of the second association end. + * @return Returns true if the queried link exists. + */ + public boolean exists(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Permission permission, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Action action); + /** + * Queries the instance objects that are related to a particular instance + * object by a link in the current associations link set. + * @param action Required value of the second association end. + * @return Collection of related objects. + */ + public java.util.Collection getPermission(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Action action); + /** + * Queries the instance objects that are related to a particular instance + * object by a link in the current associations link set. + * @param permission Required value of the first association end. + * @return Collection of related objects. + */ + public java.util.Collection getAction(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Permission permission); + /** + * Creates a link between the pair of instance objects in the associations + * link set. + * @param permission Value of the first association end. + * @param action Value of the second association end. + */ + public boolean add(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Permission permission, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Action action); + /** + * Removes a link between a pair of instance objects in the current associations + * link set. + * @param permission Value of the first association end. + * @param action Value of the second association end. + */ + public boolean remove(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Permission permission, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Action action); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/PermissionAssignment.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/PermissionAssignment.java new file mode 100644 index 0000000..10b137b --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/PermissionAssignment.java @@ -0,0 +1,47 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * PermissionAssignment association proxy interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface PermissionAssignment extends javax.jmi.reflect.RefAssociation { + /** + * Queries whether a link currently exists between a given pair of instance + * objects in the associations link set. + * @param role Value of the first association end. + * @param permission Value of the second association end. + * @return Returns true if the queried link exists. + */ + public boolean exists(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role role, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Permission permission); + /** + * Queries the instance object that is related to a particular instance object + * by a link in the current associations link set. + * @param permission Required value of the second association end. + * @return Related object or null if none exists. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role getRole(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Permission permission); + /** + * Queries the instance object that is related to a particular instance object + * by a link in the current associations link set. + * @param role Required value of the first association end. + * @return Related object or null if none exists. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.Permission getPermission(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role role); + /** + * Creates a link between the pair of instance objects in the associations + * link set. + * @param role Value of the first association end. + * @param permission Value of the second association end. + */ + public boolean add(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role role, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Permission permission); + /** + * Removes a link between a pair of instance objects in the current associations + * link set. + * @param role Value of the first association end. + * @param permission Value of the second association end. + */ + public boolean remove(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role role, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Permission permission); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/PermissionClass.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/PermissionClass.java new file mode 100644 index 0000000..bd9d8d1 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/PermissionClass.java @@ -0,0 +1,23 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * Permission class proxy interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface PermissionClass extends javax.jmi.reflect.RefClass { + /** + * The default factory operation used to create an instance object. + * @return The created instance object. + */ + public Permission createPermission(); + /** + * Creates an instance object having attributes initialized by the passed + * values. + * @param name + * @return The created instance object. + */ + public Permission createPermission(java.lang.String name); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Resource.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Resource.java new file mode 100644 index 0000000..61497b5 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Resource.java @@ -0,0 +1,16 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * Resource object instance interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface Resource { //extends javax.jmi.reflect.RefObject + /** + * Returns the value of reference action. + * @return Value of reference action. Element type: {@link ch.ethz.infsec.secureumlgui.securemodel.secureuml.Action} + */ + public java.util.Collection/**/ getAction(); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/ResourceClass.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/ResourceClass.java new file mode 100644 index 0000000..f8d4bf2 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/ResourceClass.java @@ -0,0 +1,11 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * Resource class proxy interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface ResourceClass extends javax.jmi.reflect.RefClass { +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Role.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Role.java new file mode 100644 index 0000000..6d930a9 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Role.java @@ -0,0 +1,51 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * Role object instance interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface Role { //extends javax.jmi.reflect.RefObject + /** + * Returns the value of attribute name. + * @return Value of attribute name. + */ + public java.lang.String getName(); + /** + * Sets the value of name attribute. See {@link #getName} for description + * on the attribute. + * @param newValue New value to be set. + */ + public void setName(java.lang.String newValue); + /** + * Returns the value of reference subject. + * @return Value of reference subject. Element type: {@link ch.ethz.infsec.secureumlgui.securemodel.secureuml.Subject} + */ + public java.util.Collection/**/ getSubject(); + /** + * Returns the value of reference superroles. + * @return Value of reference superroles. Element type: {@link ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role} + */ + public java.util.Collection/**/ getSuperroles(); + /** + * Returns the value of reference permission. + * @return Value of reference permission. + */ + /* changed manually 69 */ + public java.util.Collection /**/ + getPermission(); + /* uncommented manually 69 */ +// /** +// * Sets the value of reference permissions. See {@link #getPermission} for +// * description on the reference. +// * @param newValue New value to be set. +// */ +// public void setPermission(org.argouml.ui.secureuml.securemodel.secureuml.Permission newValue); + /** + * Returns the value of reference subroles. + * @return Value of reference subroles. Element type: {@link ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role} + */ + public java.util.Collection/**/ getSubroles(); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/RoleClass.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/RoleClass.java new file mode 100644 index 0000000..693a91c --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/RoleClass.java @@ -0,0 +1,23 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * Role class proxy interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface RoleClass extends javax.jmi.reflect.RefClass { + /** + * The default factory operation used to create an instance object. + * @return The created instance object. + */ + public Role createRole(); + /** + * Creates an instance object having attributes initialized by the passed + * values. + * @param name + * @return The created instance object. + */ + public Role createRole(java.lang.String name); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/RoleHierarchy.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/RoleHierarchy.java new file mode 100644 index 0000000..3eacd7f --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/RoleHierarchy.java @@ -0,0 +1,47 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * RoleHierarchy association proxy interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface RoleHierarchy extends javax.jmi.reflect.RefAssociation { + /** + * Queries whether a link currently exists between a given pair of instance + * objects in the associations link set. + * @param subroles Value of the first association end. + * @param superroles Value of the second association end. + * @return Returns true if the queried link exists. + */ + public boolean exists(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role subroles, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role superroles); + /** + * Queries the instance objects that are related to a particular instance + * object by a link in the current associations link set. + * @param superroles Required value of the second association end. + * @return Collection of related objects. + */ + public java.util.Collection getSubroles(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role superroles); + /** + * Queries the instance objects that are related to a particular instance + * object by a link in the current associations link set. + * @param subroles Required value of the first association end. + * @return Collection of related objects. + */ + public java.util.Collection getSuperroles(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role subroles); + /** + * Creates a link between the pair of instance objects in the associations + * link set. + * @param subroles Value of the first association end. + * @param superroles Value of the second association end. + */ + public boolean add(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role subroles, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role superroles); + /** + * Removes a link between a pair of instance objects in the current associations + * link set. + * @param subroles Value of the first association end. + * @param superroles Value of the second association end. + */ + public boolean remove(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role subroles, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role superroles); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/SecureUmlPackage.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/SecureUmlPackage.java new file mode 100644 index 0000000..25c4fba --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/SecureUmlPackage.java @@ -0,0 +1,101 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * SecureUML package interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface SecureUmlPackage extends javax.jmi.reflect.RefPackage { + /** + * Returns Action class proxy object. + * @return Action class proxy object. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.ActionClass getAction(); + /** + * Returns Group class proxy object. + * @return Group class proxy object. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.GroupClass getGroup(); + /** + * Returns User class proxy object. + * @return User class proxy object. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.UserClass getUser(); + /** + * Returns Subject class proxy object. + * @return Subject class proxy object. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.SubjectClass getSubject(); + /** + * Returns CompositeAction class proxy object. + * @return CompositeAction class proxy object. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.CompositeActionClass getCompositeAction(); + /** + * Returns AtomicAction class proxy object. + * @return AtomicAction class proxy object. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.AtomicActionClass getAtomicAction(); + /** + * Returns AuthorizationConstraint class proxy object. + * @return AuthorizationConstraint class proxy object. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.AuthorizationConstraintClass getAuthorizationConstraint(); + /** + * Returns Resource class proxy object. + * @return Resource class proxy object. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.ResourceClass getResource(); + /** + * Returns Permission class proxy object. + * @return Permission class proxy object. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.PermissionClass getPermission(); + /** + * Returns Role class proxy object. + * @return Role class proxy object. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.RoleClass getRole(); + /** + * Returns ActionHierarchy association proxy object. + * @return ActionHierarchy association proxy object. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.ActionHierarchy getActionHierarchy(); + /** + * Returns ActionResourceAssignment association proxy object. + * @return ActionResourceAssignment association proxy object. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.ActionResourceAssignment getActionResourceAssignment(); + /** + * Returns PermissionActionAssignment association proxy object. + * @return PermissionActionAssignment association proxy object. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.PermissionActionAssignment getPermissionActionAssignment(); + /** + * Returns SubjectAssignment association proxy object. + * @return SubjectAssignment association proxy object. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.SubjectAssignment getSubjectAssignment(); + /** + * Returns RoleHierarchy association proxy object. + * @return RoleHierarchy association proxy object. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.RoleHierarchy getRoleHierarchy(); + /** + * Returns SubjectGroup association proxy object. + * @return SubjectGroup association proxy object. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.SubjectGroup getSubjectGroup(); + /** + * Returns ConstraintAssignment association proxy object. + * @return ConstraintAssignment association proxy object. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.ConstraintAssignment getConstraintAssignment(); + /** + * Returns PermissionAssignment association proxy object. + * @return PermissionAssignment association proxy object. + */ + public ch.ethz.infsec.secureumlgui.securemodel.secureuml.PermissionAssignment getPermissionAssignment(); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Subject.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Subject.java new file mode 100644 index 0000000..8ba4298 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/Subject.java @@ -0,0 +1,27 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * Subject object instance interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface Subject { //extends javax.jmi.reflect.RefObject + /** + * Returns the value of attribute name. + * @return Value of attribute name. + */ + public java.lang.String getName(); + /** + * Sets the value of name attribute. See {@link #getName} for description + * on the attribute. + * @param newValue New value to be set. + */ + public void setName(java.lang.String newValue); + /** + * Returns the value of reference role. + * @return Value of reference role. Element type: {@link ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role} + */ + public java.util.Collection/**/ getRole(); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/SubjectAssignment.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/SubjectAssignment.java new file mode 100644 index 0000000..5644c3a --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/SubjectAssignment.java @@ -0,0 +1,47 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * SubjectAssignment association proxy interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface SubjectAssignment extends javax.jmi.reflect.RefAssociation { + /** + * Queries whether a link currently exists between a given pair of instance + * objects in the associations link set. + * @param role Value of the first association end. + * @param subject Value of the second association end. + * @return Returns true if the queried link exists. + */ + public boolean exists(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role role, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Subject subject); + /** + * Queries the instance objects that are related to a particular instance + * object by a link in the current associations link set. + * @param subject Required value of the second association end. + * @return Collection of related objects. + */ + public java.util.Collection getRole(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Subject subject); + /** + * Queries the instance objects that are related to a particular instance + * object by a link in the current associations link set. + * @param role Required value of the first association end. + * @return Collection of related objects. + */ + public java.util.Collection getSubject(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role role); + /** + * Creates a link between the pair of instance objects in the associations + * link set. + * @param role Value of the first association end. + * @param subject Value of the second association end. + */ + public boolean add(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role role, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Subject subject); + /** + * Removes a link between a pair of instance objects in the current associations + * link set. + * @param role Value of the first association end. + * @param subject Value of the second association end. + */ + public boolean remove(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Role role, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Subject subject); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/SubjectClass.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/SubjectClass.java new file mode 100644 index 0000000..fb7eb23 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/SubjectClass.java @@ -0,0 +1,11 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * Subject class proxy interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface SubjectClass extends javax.jmi.reflect.RefClass { +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/SubjectGroup.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/SubjectGroup.java new file mode 100644 index 0000000..73ce655 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/SubjectGroup.java @@ -0,0 +1,47 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * SubjectGroup association proxy interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface SubjectGroup extends javax.jmi.reflect.RefAssociation { + /** + * Queries whether a link currently exists between a given pair of instance + * objects in the associations link set. + * @param members Value of the first association end. + * @param group Value of the second association end. + * @return Returns true if the queried link exists. + */ + public boolean exists(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Group members, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Subject group); + /** + * Queries the instance objects that are related to a particular instance + * object by a link in the current associations link set. + * @param group Required value of the second association end. + * @return Collection of related objects. + */ + public java.util.Collection getMembers(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Subject group); + /** + * Queries the instance objects that are related to a particular instance + * object by a link in the current associations link set. + * @param members Required value of the first association end. + * @return Collection of related objects. + */ + public java.util.Collection getGroup(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Group members); + /** + * Creates a link between the pair of instance objects in the associations + * link set. + * @param members Value of the first association end. + * @param group Value of the second association end. + */ + public boolean add(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Group members, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Subject group); + /** + * Removes a link between a pair of instance objects in the current associations + * link set. + * @param members Value of the first association end. + * @param group Value of the second association end. + */ + public boolean remove(ch.ethz.infsec.secureumlgui.securemodel.secureuml.Group members, ch.ethz.infsec.secureumlgui.securemodel.secureuml.Subject group); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/User.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/User.java new file mode 100644 index 0000000..c49d35a --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/User.java @@ -0,0 +1,11 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * User object instance interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface User extends ch.ethz.infsec.secureumlgui.securemodel.secureuml.Subject { +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/UserClass.java b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/UserClass.java new file mode 100644 index 0000000..2e9d6a2 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/UserClass.java @@ -0,0 +1,23 @@ +package ch.ethz.infsec.secureumlgui.securemodel.secureuml; + +/** + * User class proxy interface. + * + *

Note: This type should not be subclassed or implemented + * by clients. It is generated from a MOF metamodel and automatically implemented + * by MDR (see mdr.netbeans.org).

+ */ +public interface UserClass extends javax.jmi.reflect.RefClass { + /** + * The default factory operation used to create an instance object. + * @return The created instance object. + */ + public User createUser(); + /** + * Creates an instance object having attributes initialized by the passed + * values. + * @param name + * @return The created instance object. + */ + public User createUser(java.lang.String name); +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/package.html b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/package.html new file mode 100644 index 0000000..a152117 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodel/secureuml/package.html @@ -0,0 +1,10 @@ + + + + +Interfaces for the SecureUML package. + +Contains interfaces for each metaclass and metassociation in the + SecureUML metamodel. + + diff --git a/src/ch/ethz/infsec/secureumlgui/securemodelimpl/SecureModelFactory.java b/src/ch/ethz/infsec/secureumlgui/securemodelimpl/SecureModelFactory.java new file mode 100644 index 0000000..653e635 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodelimpl/SecureModelFactory.java @@ -0,0 +1,307 @@ + +package ch.ethz.infsec.secureumlgui.securemodelimpl; + +import ch.ethz.infsec.secureumlgui.Util; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; +import ch.ethz.infsec.secureumlgui.modelmanagement.ModelConst; +import ch.ethz.infsec.secureumlgui.modelmapping.GenericDialectHelper; + +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.ActionType; + +import javax.jmi.reflect.RefObject; +import javax.jmi.reflect.RefPackage; + +import org.apache.log4j.Logger; + +import ch.ethz.infsec.secureumlgui.securemodel.secureuml.*; +import ch.ethz.infsec.secureumlgui.securemodel.*; + +/** + * Factory class to create Instances of the SecureUML and its dialects metamodel's elements. + * + * works untyped to workaround the MDR Classloader issue + * (Interfaces cannot be found by MDR when + * running from inside ArgoUML Module) + * + * + */ +public class SecureModelFactory +{ + private SecureModelFactory() + { + // TODO NEW take from DA + //secModel = new SecureModelPackageImpl(); + + //secureUmlPackage = secModel.getSecureUml(); + //componentUmlPackage = secModel.getComponentUml(); + } + + MultiContextLogger logger = MultiContextLogger.getDefault(); + + private static Logger aLog = Logger.getLogger(SecureModelFactory.class); + + protected Object secureModelPackage = null; + public Object getSecureModel() + { + if(secureModelPackage == null) + { + secureModelPackage = + GenericDialectHelper.getInstance(). + getDialectMetaModelInfo().getDialectExtent(); + + if(secureModelPackage == null) + logger.error("secureModelPackage = null"); + + secureUmlPackage = Util.getProperty( + secureModelPackage, "SecureUml"); + //secureUmlPackage = ((SecureModelPackage) secureModelPackage).getSecureUml(); + } + return secureModelPackage; + } + + public void setSecureModel(Object secModel) + { + this.secureModelPackage = secModel; + } + + protected Object secureUmlPackage = null; + public Object getSecureUmlPackage() + { + if(secureUmlPackage == null) + { + secureUmlPackage = + Util.getProperty(getSecureModel(), "secureUml"); + } + return secureUmlPackage; + } +// public void setSecureUmlPackage(SecureUmlPackage secureUmlPackage) +// { +// this.secureUmlPackage = secureUmlPackage; +// } + + + protected Object dialectPackage = null; + public Object getDialectPackage() + { + if(dialectPackage == null) + { + String dialectPackageName = + GenericDialectHelper.getInstance(). + getDialectMetaModelInfo().getDialectName(); + + dialectPackage = + Util.getProperty(getSecureModel(), dialectPackageName); + } + return dialectPackage; + } + + protected Object dialectDialectPackage = null; + public Object getDialectDialectPackage() + { + if(dialectDialectPackage == null) + { + String dialectDialectPackageName = + GenericDialectHelper.getInstance(). + getDialectMetaModelInfo().getDialectName() + + ModelConst.DIALECT_PACKAGE_SUFFIX; + + dialectDialectPackage = + Util.getProperty(getSecureModel(), + dialectDialectPackageName); + } + return dialectDialectPackage; + + } + + +//// public void setComponentUmlPackage(ComponentUmlPackage componentUmlPackage) +//// { +//// this.componentUmlPackage = componentUmlPackage; +//// } + + +// protected Object componentUmlPackage = null; +// public Object getComponentUmlPackage() +// { +// return componentUmlPackage; +// } +//// public void setComponentUmlPackage(ComponentUmlPackage componentUmlPackage) +//// { +//// this.componentUmlPackage = componentUmlPackage; +//// } + + + public static SecureModelFactory getInstance() + { + return new SecureModelFactory(); + } + + + public Object createResource(String resourceTypeName, String name) + { + Object resourceTypeClass = + Util.getProperty(getDialectPackage(), resourceTypeName); + + Object resource = + Util.invokeParameterlessMethod(resourceTypeClass, + "create"+Util.capitalize(resourceTypeName)); + + return resource; + } + + // ComponentUML Dialect specific +// public Entity createEntity(String name) +// { +// +// return new EntityImpl(name); +// //return componentUmlPackage.getEntity().createEntity(name); +// } +// +// public Attribute createAttribute(String name) +// { +// return new AttributeImpl(name); +// //return componentUmlPackage.getAttribute().createAttribute(name); +// } +// +// public Method createMethod(String name) +// { +// return new MethodImpl(name); +// //return componentUmlPackage.getMethod().createMethod(name); +// } + + + /** create an unnamed permission */ + public /*Permission*/ RefObject createPermission() + { + + Object permissionClass = Util.getProperty(getSecureUmlPackage(), "permission"); + RefObject permission = (RefObject) Util.invokeParameterlessMethod(permissionClass, "createPermission"); + return permission; + +// return ((SecureUmlPackage) getSecureUmlPackage()) +// .getPermission() +// .createPermission(); + } + + /** create a permission with the given name */ + public /*Permission*/ RefObject createPermission(String name) + { + + + //Object permissionClass = Util.getProperty(getSecureUmlPackage(), "permission"); + RefObject permission = createPermission();//(RefObject) Util.invokeParameterlessMethod(permissionClass, "createPermission"); + + Util.setProperty(permission, "name", name); + + return permission; + + // return new PermissionImpl(name); + //return secureUmlPackage.getPermission().createPermission(name); + } + + /** create a role with the given name */ + public RefObject /* Role */ createRole(String name) + { + + //return new RoleImpl(name); + + Object roleClass = Util.getProperty(getSecureUmlPackage(), "role"); + RefObject role = (RefObject) Util.invokeParameterlessMethod(roleClass, "createRole"); + + Util.setProperty(role, "name", name); + + return role; + + //return secureUmlPackage.getRole().createRole(name); + } + + public RefObject /* Policy */ createPolicy(String name) { + aLog.debug("createPolicy__" + name); + Object policyClass = Util.getProperty(getSecureUmlPackage(), "policy"); + RefObject policy = (RefObject) Util.invokeParameterlessMethod(policyClass, "createPolicy"); + + Util.setProperty(policy, "name", name); + + return policy; + } + + + /** create an action of the type given as string */ + public /*Action*/ RefObject createAction(String name) + { + //return new ActionI + //return new ActionImpl(name); + + Object actionClass = Util.getProperty( + getDialectDialectPackage(), + //getSecureUmlPackage(), + name);//"action"); + RefObject action = (RefObject) Util.invokeParameterlessMethod(actionClass, + "create" + Util.capitalize(name));//Action"); + + Util.setProperty(action, "name", name); + + return action; + } + + /** create an action of the given type */ + public RefObject createAction(ActionType actionType) { + RefObject newActionObject = createAction(actionType.getName()); + Util.setProperty(newActionObject, "name", actionType.getShortName()); + return newActionObject; + } + + + /** create an authorization constraint */ + public RefObject createAuthorizationConstraint(String constraint) + { + Object authCClass = Util.getProperty(getSecureUmlPackage(), "authorizationConstraint"); + RefObject newAuthCObject = (RefObject) Util.invokeParameterlessMethod(authCClass, "createAuthorizationConstraint"); + Util.setProperty(newAuthCObject, "constraint", constraint); + return newAuthCObject; + } + +// /* currently not used */ +// public /*Action*/ Object createAction(Class cl) +// { +// +// try +// { +// Action action = null; +// //org.argouml.ui.secureuml.securemodelimpl.componentumldialect.EntityFullAccessImpl +// +// String classname = cl.getName(); +// +// // change 57: +// // Implementation is in Package securemodelimpl! -> replace +// classname = classname.replaceFirst(".securemodel", ".securemodelimpl"); +// +// logger.log(logger.INFORMATIONAL, logger.MODELMAPPER, "creating actionImpl: " + classname + "Impl"); +// +// Class actionImplClass = Class.forName(classname + "Impl"); +// +// Constructor ctor = actionImplClass.getConstructor(new Class[0]); +// +// Object instance = ctor.newInstance(new Object[0]); +// +// action = (Action) instance; +// +// return action; +// } +// catch (Exception e) +// { +// logger.logException(e); +// } +// +// return null; +// } + + +// public /*Association*/ Object createAssociation(String name) +// { +// AssociationImpl assoc = new AssociationImpl(name); +// return assoc; +// } + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/securemodelimpl/secureuml/package.html b/src/ch/ethz/infsec/secureumlgui/securemodelimpl/secureuml/package.html new file mode 100644 index 0000000..2a01706 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/securemodelimpl/secureuml/package.html @@ -0,0 +1,8 @@ + + + + + +Implementations of (some of) the interfaces for the SecureUML package. + + diff --git a/src/ch/ethz/infsec/secureumlgui/transformation/MetaModelMap.java b/src/ch/ethz/infsec/secureumlgui/transformation/MetaModelMap.java new file mode 100644 index 0000000..9a5d04f --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/transformation/MetaModelMap.java @@ -0,0 +1,424 @@ +package ch.ethz.infsec.secureumlgui.transformation; + +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.Map; +import java.util.Set; + +import org.apache.log4j.Logger; + +//import javax.jmi.model.ModelElement; +//import javax.jmi.reflect.RefObject; + +//import tudresden.ocl20.core.jmi.ocl.commonmodel.ModelElement; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.MetaModelEntity; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.TaggedValue; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; + +public class MetaModelMap +{ + + private MetaModelMap() + { + + } + + private static MetaModelMap instance = new MetaModelMap(); + public static MetaModelMap getDefault() + { + return instance; + + } + + protected MultiContextLogger logger = new MultiContextLogger(MultiContextLogger.MODELMAP); + + private Map map = new HashMap(); + + private Map reverseMap = new HashMap(); + + private static Logger aLog = Logger.getLogger(MetaModelMap.class); + + + /** + * @param elem UML-Modelelement + * @return true, if the Map contains a mapping for @param elem + * + */ + public boolean containsMapping(Object elem) + { + return map.containsKey(elem); + } + + /** + * @param elem SecureUML Element + */ + public boolean containsReverseMapping(MetaModelEntity elem) + { + return reverseMap.containsKey(elem); + } + + /** + * delete all contained Mappings + * + */ + public void clear() + { + //logger.info(logger.MODELMAP, "##### ModelMap cleared"); + map.clear(); + reverseMap.clear(); + } + + /** + * @param src - the new mapping source + * @param target - the new mapping's target + * + * Adds a mapping (src -> target) + */ + public void put(Object src, MetaModelEntity target) { + map.put(src, target); + reverseMap.put(target, src); + // too verbose + //aLog.debug("put Item to modelmap: " + src + "\n <-> \n" + target); +// logger.log(logger.INFORMATIONAL, logger.MODELMAP, +// "put Item to modelmap: " + src + "\n <-> \n" + target); + } + + + /* deletion stuff - taken from christian - + * currently not in use, but there because + * christian's modelmapper uses it + */ + + private Set deletables = new HashSet(); + + public void addForDeletion(Object obj) { + deletables.add(obj); + } + + /** + * finds the extent element associated with the source MOF object + * + * @param mofElementö + * @return the found element + */ + public MetaModelEntity getElement(Object mofElement) { + if (!containsMapping(mofElement)) + { + error(mofElement.toString()); + + return null; + } + else + { + return map.get(mofElement); + } + } + + public Object getMofElement(MetaModelEntity entity) { + if (!containsReverseMapping(entity)) + { +// uncommented manually 57 +// (method is used to check whether the element is there +// -> not to be logged as error!) + if(entity == null) + error("cannot get Value for Key 'null'"); + else + error(entity.toString()); + + return null; + } + else + { + return reverseMap.get(entity); + } + } + +// public Set getAllDeletableMofElements() { +// return deletables; +// } + + public Set getAllMofElements() { + return map.keySet(); + } + + public Collection getAllElements() { + return map.values(); + } + + + + /* helper Map (ModelElement<->TaggedValues) */ + + Map> modelElementTaggedValues = new HashMap>(); + + public Collection getModelElementTaggedValues(Object modelElement) + { + return modelElementTaggedValues.get(modelElement); + } + + public TaggedValue getModelElementTaggedValue(Object modelElement, String tagName) + { + Collection taggedValues = + modelElementTaggedValues.get(modelElement); + + if(taggedValues == null) + return null; + + for (Iterator iter = taggedValues.iterator(); iter.hasNext();) + { + TaggedValue taggedValue = (TaggedValue) iter.next(); + + if(taggedValue.getName().equals(tagName)) + return taggedValue; + } + return null; + } + + public void putModelElementTaggedValue(Object modelElement, TaggedValue taggedValue) + { + if(!modelElementTaggedValues.containsKey(modelElement)) + { + modelElementTaggedValues.put(modelElement, new LinkedList()); + } + modelElementTaggedValues.get(modelElement).add(taggedValue); + } + + + + + private void error(String elem) { + logger.error("requested element " + elem + " not mapped!" + + "(mapsize is: " + map.size() + " / " + reverseMap.size() + ")"); + + aLog.error("requested element " + elem + " not mapped!" + + "(mapsize is: " + map.size() + " / " + reverseMap.size() + ")"); + //logger.logCallstack(); + //printMap(); + } + + public void printMap() + { + + logger.info(MultiContextLogger.MODELMAP, toString()); + } + + public String toString() + { + + String mapString = + "################### MAP ##################### \n" + + " \n"; + + for (Iterator iter = map.keySet().iterator(); iter.hasNext();) + { + mapString += "\n@ "; + // add key String + Object key = null; + Object value = null; + try + { + key = iter.next(); + //if(key instanceof ModelElement) + { + mapString += + (/*(ModelElement)*/key).getClass().getSimpleName() + + " "; + // + (/*(ModelElement)*/key).getName(); + } + //else + { + mapString += key.toString(); + } + } + catch (Exception e) + { + mapString += "## ERROR ## \n"; + } + + mapString += " -> "; + + // add value String + try + { + value = map.get(key); + Method getNameMethod = null; + try + { + getNameMethod = + value.getClass().getMethod( + "getName", new Class[0]); + + mapString += + value.getClass().getSimpleName() + " " + + (String) getNameMethod.invoke( + value, new Object[0]); + + } + catch (Exception e) + { + mapString += key.toString(); + } + } + catch (Exception e) + { + mapString += "## ERROR ## \n"; + } + + } + + mapString += + "\n\n################### REVERSE MAP ##################### \n"; + + for (Iterator iter = reverseMap.keySet().iterator(); iter.hasNext();) + { + mapString += "\n@ "; + // add key String + Object key = null; + Object value = null; + try + { + key = iter.next(); + Method getNameMethod = null; +// try +// { + getNameMethod = + key.getClass().getMethod( + "getName", new Class[0]); + + mapString += + key.getClass().getSimpleName() + " " + + (String) getNameMethod.invoke( + key, new Object[0]); +// } +// catch (Exception e) +// { +// //mapString += key.toString(); +// } + } + catch (Exception e) + { + mapString += "## ERROR ## \n"; + } + + mapString += " -> "; + +// // add value String +// try +// { +// mapString += reverseMap.get(key).toString(); +// } +// catch (Exception e) +// { +// mapString += "## ERROR ## \n"; +// } + + // add value String + try + { + value = reverseMap.get(key); + Method getNameMethod = null; +// try +// { + getNameMethod = + value.getClass().getMethod( + "getName", new Class[0]); + + mapString += + value.getClass().getSimpleName() + " " + + (String) getNameMethod.invoke( + value, new Object[0]); + +// } +// catch (Exception e) +// { +// mapString += value.toString(); +// } + } + catch (Exception e) + { + mapString += "## ERROR ## \n"; + } + } + + + mapString += "#############################################"; + + return mapString; + + } + + + +// public String findPackage(ModelElement elem) { +// Namespace result = null; +// while (result == null) { +// result = elem.getNamespace(); +// elem = (ModelElement) elem.refImmediateComposite(); +// } +// if (elem instanceof Classifier) { +// result = elem.getNamespace(); +// } +// return result.getName(); +// } + +// @SuppressWarnings("unchecked") +// public String findContext(ModelElement elem) { +// String result = ""; +// if (elem instanceof Operation) { +// Operation elemOp = (Operation) elem; +// +// String ownerName = elemOp.getOwner().getName(); +// result += ownerName + "::" + elem.getName(); +// // operation signature +// result += "("; +// +// /* TODO: start changed manually 18 */ +// List params = elemOp.getParameter(); +// List paramsTyped = new LinkedList(); +// for (Iterator iter = params.iterator(); iter.hasNext();) +// { +// Object element = (Object) iter.next(); +// paramsTyped.add((Parameter)element); +// } +// +// for (Parameter p : (Collection) +// paramsTyped) { +// /* end changed manually 18*/ +// //for (Parameter p : (Collection) elemOp +// // .getInParametersA()) { +// result += p.getName(); +// result += ":" + p.getType().getName(); +// result += ","; +// } +// if (result.endsWith(",")) { +// result = result.substring(0, result.length() - 1); +// } +// result += ")"; +// /* TODO: uncommented manually 19 */ +// //result += ":" + elemOp.getReturnParameterA().getTypeA().getNameA(); +// } else if (elem instanceof Transition) { +// org.omg.uml.behavioralelements.statemachines.Transition transition = (org.omg.uml.behavioralelements.statemachines.Transition) elem; +// result = elem.getName(); +// StateMachine statemachine = transition.getStateMachine(); +// if (statemachine != null) { +// result = statemachine.getName() + "::" + result; +// } else { +// return result; +// } +// ModelElement context = statemachine.getContext(); +// if (context != null) { +// result = context.getName() + "::" + result; +// } +// return result; +// } else { +// logger.error("could not determine context for " + elem.getName()); +// result = null; +// } +// return result; +// } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/transformation/ModelMap.java b/src/ch/ethz/infsec/secureumlgui/transformation/ModelMap.java new file mode 100644 index 0000000..5e41f28 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/transformation/ModelMap.java @@ -0,0 +1,471 @@ +package ch.ethz.infsec.secureumlgui.transformation; + +import java.lang.reflect.Method; +import java.util.Collection; +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +import javax.jmi.reflect.RefBaseObject; +import javax.jmi.reflect.RefObject; + +import org.apache.log4j.Logger; +import org.omg.uml.foundation.core.Classifier; +import org.omg.uml.foundation.core.ModelElement; +import org.omg.uml.foundation.core.Stereotype; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; + +/** + * stores the mapping from UML model elements to SecureUML dialect elements, and vice versa. + * + */ + +public class ModelMap +{ + /** Singleton, use getDefault + * + */ + private ModelMap() + { + + } + + + private static ModelMap instance = new ModelMap(); + + private static Logger aLog = Logger.getLogger(ModelMap.class); + + public static ModelMap getDefault() + { + return instance; + } + + private static MultiContextLogger logger = new MultiContextLogger(); + + /** from UML elements to SecureUML elements */ + private Map map = new HashMap(); + + /** from SecureUML elements to UML elements */ + private Map reverseMap = new HashMap(); + +// private Set deletables = new HashSet(); + + /** + * @param elem UML-Modelelement + * @return true, if the Map contains a mapping for @param elem + * + */ + public boolean mapContainsKey(RefObject elem) + { + return map.containsKey(elem); + } + + /** + * @param elem SecureUML Element + * @return true, if the reverse map contains a mapping for elem + */ + public boolean reverseMapContainsKey(Object elem) + { + return reverseMap.containsKey(elem); + } + + /** + * delete all contained Mappings + * + */ + public void clear() + { + //logger.info(logger.MODELMAP, "##### ModelMap cleared"); + map.clear(); + reverseMap.clear(); + + actionMap.clear(); + stereotypeMap.clear(); + } + + /** + * Adds a mapping (src -> target). + * @param src - the new mapping source + * @param target - the new mapping's target + * + * + */ + public void put(RefObject src, Object target) + { + map.put(src, target); + reverseMap.put(target, src); + // too verbose + // logger.log(logger.INFORMATIONAL, logger.MODELMAP, + // "put Item to modelmap: " + src + "\n <-> \n" + target); + + aLog.debug("Modelmap.put(" + src.getClass() + " (" + (src instanceof Stereotype) + "), " + target.getClass() +" (" + (target instanceof Stereotype) + ")"); + + } + +// public void addForDeletion(RefObject obj) +// { +// deletables.add(obj); +// } + + /** + * find the SecureUML extent element associated with the source UML object. + * + * @param umlElement + * @return the found element + */ + public Object getElement(RefObject umlElement) + { + if (!mapContainsKey(umlElement)) + { + error(" (getElement) "+umlElement); + return null; + } + else + { + return map.get(umlElement); + } + } + + /** + * find the source UML object associated with the extent element + * + * @param suElement + * @return the found element + */ + public RefObject getUmlElement(Object suElement) + { + if (!reverseMapContainsKey(suElement)) + { + error(" (getUmlElement) "+suElement); + return null; + } + else + { + return reverseMap.get(suElement); + } +// for (RefObject o : map.keySet()) +// { +// if ((map.get(o) != null) && (map.get(o).equals(abstractElement))) +// { +// return o; +// } +// } +// error(abstractElement.toString()); +// return null; + } + +// public Set getAllDeletableUmlElements() +// { +// return deletables; +// } + + public Set getAllUmlElements() + { + return map.keySet(); + } + + public Collection getAllElements() + { + return map.values(); + } + + private void error(String elem) + { + //logger.error("requested element " + elem + " not mapped!"); + //logger.error("requested element not mapped"); + } + + public void printMap() + { + + logger.info(logger.MODELMAP, toString()); + } + + public String toString() + { + + String mapString = "################### MAP ##################### \n" + + " \n"; + + for (Iterator iter = map.keySet().iterator(); iter.hasNext();) + { + mapString += "\n@ "; + // add key String + Object key = null; + Object value = null; + try + { + key = iter.next(); + if (key instanceof ModelElement) + { + mapString += ((ModelElement) key).getClass().getSimpleName() + " " + + ((ModelElement) key).getName(); + } + else + { + mapString += key.toString(); + } + } + catch (Exception e) + { + mapString += "## ERROR ## \n"; + } + + mapString += " -> "; + + // add value String + try + { + value = map.get(key); + Method getNameMethod = null; + try + { + getNameMethod = value.getClass().getMethod("getName", new Class[0]); + + mapString += value.getClass().getSimpleName() + " " + + (String) getNameMethod.invoke(value, new Object[0]); + + } + catch (Exception e) + { + mapString += key.toString(); + } + } + catch (Exception e) + { + mapString += "## ERROR ## \n"; + } + + } + + mapString += "\n\n################### REVERSE MAP ##################### \n"; + + for (Iterator iter = reverseMap.keySet().iterator(); iter.hasNext();) + { + mapString += "\n@ "; + // add key String + Object key = null; + Object value = null; + try + { + key = iter.next(); + Method getNameMethod = null; + // try + // { + getNameMethod = key.getClass().getMethod("getName", new Class[0]); + + mapString += key.getClass().getSimpleName() + " " + + (String) getNameMethod.invoke(key, new Object[0]); + // } + // catch (Exception e) + // { + // //mapString += key.toString(); + // } + } + catch (Exception e) + { + mapString += "## ERROR ## \n"; + } + + mapString += " -> "; + + // // add value String + // try + // { + // mapString += reverseMap.get(key).toString(); + // } + // catch (Exception e) + // { + // mapString += "## ERROR ## \n"; + // } + + // add value String + try + { + value = reverseMap.get(key); + Method getNameMethod = null; + // try + // { + getNameMethod = value.getClass().getMethod("getName", new Class[0]); + + mapString += value.getClass().getSimpleName() + " " + + (String) getNameMethod.invoke(value, new Object[0]); + + // } + // catch (Exception e) + // { + // mapString += value.toString(); + // } + } + catch (Exception e) + { + mapString += "## ERROR ## \n"; + } + } + + mapString += "#############################################"; + + return mapString; + + } + + // public String findPackage(ModelElement elem) { + // Namespace result = null; + // while (result == null) { + // result = elem.getNamespace(); + // elem = (ModelElement) elem.refImmediateComposite(); + // } + // if (elem instanceof Classifier) { + // result = elem.getNamespace(); + // } + // return result.getName(); + // } + +// @SuppressWarnings("unchecked") +// public String findContext(ModelElement elem) +// { +// String result = ""; +// if (elem instanceof Operation) +// { +// Operation elemOp = (Operation) elem; +// +// String ownerName = elemOp.getOwner().getName(); +// result += ownerName + "::" + elem.getName(); +// // operation signature +// result += "("; +// for (Parameter p : (Collection) elemOp.getInParametersA()) +// { +// result += p.getName(); +// result += ":" + p.getType().getName(); +// result += ","; +// } +// if (result.endsWith(",")) +// { +// result = result.substring(0, result.length() - 1); +// } +// result += ")"; +// result += ":" + elemOp.getReturnParameterA().getTypeA().getNameA(); +// } +// else if (elem instanceof Transition) +// { +// tudresden.ocl20.core.jmi.uml15.statemachines.Transition transition = (tudresden.ocl20.core.jmi.uml15.statemachines.Transition) elem; +// result = elem.getName(); +// StateMachine statemachine = transition.getStateMachine(); +// if (statemachine != null) +// { +// result = statemachine.getName() + "::" + result; +// } +// else +// { +// return result; +// } +// ModelElement context = statemachine.getContext(); +// if (context != null) +// { +// result = context.getName() + "::" + result; +// } +// return result; +// } +// else +// { +// logger.error("could not determine context for " + elem.getName()); +// result = null; +// } +// return result; +// } + + /* extensions + * + * + */ + + + /** stores the action classes found in the UML model + * (SimpleName->ActionClassifier). Action classes are classes with + * stereotype secuml.action. They are used in a SecureUML dialect + * profile as type of the attribute of a permission association + * class + */ + Map actionMap = new LinkedHashMap(); + + public Classifier getActionClass(String shortname) + { + if(shortname != null && actionMap.containsKey(shortname)) + return actionMap.get(shortname); + else + { + logger.error("couldn't find Action Class for '" + + shortname + "' among " + actionMap.size() + + " actionClasses."); + return null; + } + } + + public void putActionClass(String shortname, Classifier actionClass) + { + if(shortname != null && actionClass != null) + actionMap.put(shortname, actionClass); + } + + /** stores the stereotypes found in the UML model (stereotype name -> Stereotype). + * Stereotypes that are needed, but not found, are later created by us. + */ + Map stereotypeMap = new LinkedHashMap(); + + public Stereotype getStereotype(String name) + { + if(name != null && stereotypeMap.containsKey(name)) + return stereotypeMap.get(name); + else + return null; + } + + public void putStereotype(Stereotype stereotype) + { + if(stereotype != null && stereotype.getName() != null) + stereotypeMap.put(stereotype.getName(), stereotype); + } + + + +//{ + +//Map> actionMap = +// new LinkedHashMap>(); +// +//public Classifier getActionClass(ResourceType resourceType, ActionType actionType) +//{ +// if(actionMap.containsKey(resourceType)) +// { +// Map m = actionMap.get(resourceType); +// if(m.containsKey(actionType)) +// return m.get(actionType); +// } +// return null; +//} + +//public void putActionClass(ResourceType resourceType, ActionType actionType, Classifier actionClass) +//{ +// if(actionType != null && actionClass != null) +// { +// if(actionMap.containsKey(resourceType)) +// { +// Map m = actionMap.get(resourceType); +// +// m.put(actionType, actionClass); +// } +// else +// { +// Map m = new LinkedHashMap(); +// m.put(actionType, actionClass); +// actionMap.put(resourceType, m); +// } +// } +// else +// logger.error("Modelmap.putActionClass: null argument"); +//} + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/transformation/package.html b/src/ch/ethz/infsec/secureumlgui/transformation/package.html new file mode 100644 index 0000000..5e37600 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/transformation/package.html @@ -0,0 +1,8 @@ + + + + + +Classes that store the correspondence between SecureUML (dialect) elements and their UML representation. + + diff --git a/src/ch/ethz/infsec/secureumlgui/usecasemapper/control/Controller.java b/src/ch/ethz/infsec/secureumlgui/usecasemapper/control/Controller.java new file mode 100644 index 0000000..82b2a63 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/usecasemapper/control/Controller.java @@ -0,0 +1,90 @@ +package ch.ethz.infsec.secureumlgui.usecasemapper.control; + +import ch.ethz.infsec.secureumlgui.usecasemapper.gui.View; +import ch.ethz.infsec.secureumlgui.usecasemapper.mapping.MapperStrategy; +import ch.ethz.infsec.secureumlgui.usecasemapper.mapping.ActorMapper; +import ch.ethz.infsec.secureumlgui.usecasemapper.mapping.PermissionMapper; +import ch.ethz.infsec.secureumlgui.usecasemapper.mapping.MapperException; +import ch.ethz.infsec.secureumlgui.usecasemapper.mapping.MapperHelper; + +import java.util.Collection; +import java.util.ArrayList; + +import org.apache.log4j.Logger; + +import org.argouml.model.Model; + +/** + * Controller handles the mapping process on + * a high level. It is the client in a strategy pattern, + * which uses concrete strategies for different mapping + * tasks. + * + * @version 1.0 + */ +public class Controller { + + /** + * The log4j-logger of this class. + * + */ + private static final Logger LOGGER = Logger. + getLogger(MenuActionListener.class); + + /** + * The reference to the + * {@link ch.ethz.infsec.secureumlgui.usecasemapper.gui.View} + * used for visual feedback. + */ + private final View view = new View(); + + /** + * The mapping strategies used in + * {@link ch.ethz.infsec.secureumlgui.usecasemapper.control.Controller#map()}. + */ + private final Collection mappers = + new ArrayList(); + + /** + * Initializes the mapper collection with the desired mapping + * strategies. + */ + public Controller() { + mappers.add(new ActorMapper()); + mappers.add(new PermissionMapper()); + + LOGGER.debug("Mappers added"); + } + + /** + * Starts the mapping process. + * First checks, whether there is a cyclic dependency in the + * role hierarchy, as this could prevent the mapping strategies + * from working as expected. + * Then the control is passed to the registered mapping + * algorithms. + */ + public final void map() { + + final Object model = Model.getModelManagementFactory().getRootModel(); + + if (MapperHelper.getInstance().hasNoCircularInheritance(model)) { + try { + MapperHelper.getInstance().initSecureUML(model); + + for (MapperStrategy strategy : mappers) { + LOGGER.debug("Starting mapping strategy: " + strategy); + + strategy.setModel(model); + strategy.map(); + } + view.showInfo("Mapping complete."); + } catch (MapperException me) { + view.showException("Mapping exception ocurred:", me); + } + } else { + view.showException("Circular dependency in " + + "role hierarchy detected."); + } + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/usecasemapper/control/MenuActionListener.java b/src/ch/ethz/infsec/secureumlgui/usecasemapper/control/MenuActionListener.java new file mode 100644 index 0000000..54b3e0f --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/usecasemapper/control/MenuActionListener.java @@ -0,0 +1,28 @@ +package ch.ethz.infsec.secureumlgui.usecasemapper.control; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * MenuActionListener is the listener used + * in for the custom ArgoUML menu for the SecureUML + * module. + * + * @version 1.0 + */ +public class MenuActionListener implements ActionListener { + + /** + * The reference to the @see Controller. + */ + private final Controller controller = new Controller(); + + /** + * Responds to the ActionEvents from the module menu. + * + * @param event the ActionEvent to be handled. + */ + public final void actionPerformed(final ActionEvent event) { + controller.map(); + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/usecasemapper/control/package.html b/src/ch/ethz/infsec/secureumlgui/usecasemapper/control/package.html new file mode 100644 index 0000000..d5ae90d --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/usecasemapper/control/package.html @@ -0,0 +1,11 @@ + + + + + + +Contains the mapping controller and the ActionListener +for the MenuItem. + + + diff --git a/src/ch/ethz/infsec/secureumlgui/usecasemapper/gui/View.java b/src/ch/ethz/infsec/secureumlgui/usecasemapper/gui/View.java new file mode 100644 index 0000000..ae8ef92 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/usecasemapper/gui/View.java @@ -0,0 +1,57 @@ +package ch.ethz.infsec.secureumlgui.usecasemapper.gui; + +import javax.swing.JOptionPane; + +import org.argouml.ui.ProjectBrowser; + +/** + * The View class contains all functionality + * for direct user feedback. + * + * @version 1.0 + */ +public class View { + + /** + * The reference to the project browser ArgoUML main window. + */ + private final ProjectBrowser projectBrowser = + ProjectBrowser.getInstance(); + + /** + * Displays an info dialog in ArgoUml. + * + * @param message the {@link java.lang.String} + * containing the info message. + */ + public final void showInfo(final String message) { + JOptionPane.showMessageDialog(projectBrowser, message, + "Use case mapper", + JOptionPane.INFORMATION_MESSAGE); + } + + /** + * Displays an exception dialog. + * + * @param message the {@link java.lang.String} containing + * the exception message. + */ + public final void showException(final String message) { + JOptionPane.showMessageDialog(projectBrowser, message, + "Use case mapper", + JOptionPane.ERROR_MESSAGE); + } + + /** + * Displays an exception dialog with an + * {@link java.lang.Exception}-Object. + * + * @param message the {@link java.lang.String} containing + * the exception message. + * @param exception the {@link java.lang.Exception} that occured. + */ + public final void showException(final String message, + final Exception exception) { + showException(message + "\n\n" + exception.toString()); + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/usecasemapper/gui/package.html b/src/ch/ethz/infsec/secureumlgui/usecasemapper/gui/package.html new file mode 100644 index 0000000..738586d --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/usecasemapper/gui/package.html @@ -0,0 +1,10 @@ + + + + + + +Provides the gui related functionality. + + + diff --git a/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/ActorMapper.java b/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/ActorMapper.java new file mode 100644 index 0000000..673575e --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/ActorMapper.java @@ -0,0 +1,207 @@ +package ch.ethz.infsec.secureumlgui.usecasemapper.mapping; + +import java.util.Collection; +import java.util.ArrayList; + +import org.apache.log4j.Logger; + +import org.argouml.model.Model; +import org.argouml.model.Facade; + +/** + * Mapping strategy for mapping non abstract actors to SecureUML + * roles. The details of the strategy are described in the + * comments for the method {@link #map() map}. + * + * @version 1.0 + */ +public class ActorMapper implements MapperStrategy { + + /** + * The log4j-logger of this class. + * + */ + private static final Logger LOGGER = Logger.getLogger(ActorMapper.class); + + /** + * Global reference to the target model. + */ + private Object model; + + /** + * Global reference to the ArgoUML facade to enhance readability. + */ + private final Facade facade = (Facade) Model.getFacade(); + + /** + * Maps the non abstract actors to SecureUML roles. + * The mapping process consists of two steps: + * 1. For all actors SecureUML role classes are created + * if they are not already present. + * 2. The hierarchy of the actors is mapped on the role clases. + * In this step the gaps which may have been introduced into + * the hierarchy by ignoring the abstract actors are filled + * with the appropriate non abstract actors. + * @throws MapperException Thrown if the mapping process fails. + */ + public final void map() throws MapperException { + + if (model == null) { + LOGGER.fatal("Target model undefined"); + throw new MapperException("Target model undefined"); + } else { + LOGGER.debug("Getting all non abstract actors"); + + for (Object actor : getNonAbstractActors()) { + final String actorName = facade.getName(actor); + + LOGGER.debug("Current actor: " + actorName); + + if (isActorAlreadyMapped(actor)) { + LOGGER.debug("Actor: " + actorName + " already mapped"); + } else { + createSecureUMLRole(actor); + + LOGGER.debug("Actor: " + actorName + + " mapped to SecureUML role"); + } + } + + for (Object actor : getNonAbstractActors()) { + for (Object parent : getNonAbstractParents(actor)) { + LOGGER.debug("Current generalize: " + + facade.getName(parent) + " <-- " + + facade.getName(actor)); + final Object parentClass = getRoleClassByActor(parent); + final Object actorClass = getRoleClassByActor(actor); + + if (facade.getGeneralization(actorClass, + parentClass) == null) { + Model.getCoreFactory(). + buildGeneralization(actorClass, parentClass); + LOGGER.debug("Added generalize: " + + facade.getName(parent) + " <-- " + + facade.getName(actor)); + } + } + } + } + } + + /** + * Sets the model the mapping is performed on. + * + * @param targetModel The model being the target model. + */ + public final void setModel(final Object targetModel) { + model = targetModel; + } + + /** + * Creates a class with stereotype secuml. role for a given + * actor. The role class is created in the namespace of the actor. + * + * @param actor actor object for which the role should be created + */ + private void createSecureUMLRole(final Object actor) { + + final Object targetNamespace = facade.getNamespace(actor); + final String roleClassName = facade.getName(actor); + + final Object roleClass = Model.getCoreFactory().buildClass( + roleClassName, + targetNamespace); + + // Add the SecureUML stereotype + final Object stereotype = MapperHelper.getInstance(). + getSecureUMLStereotype(model, "secuml.role"); + + Model.getCoreHelper().addStereotype(roleClass, stereotype); + } + + /** + * Gets the corresponding SecureUML role class for a given + * actor or returns null if not found. + * Checks if there is already a SecureUML role with the + * name of the actor in its namespace. + * + * @param actor An object representing an actor. + * @return an object representing the role class or null + * if not present. + */ + private Object getRoleClassByActor(final Object actor) { + if (facade.getName(actor) != null) { + final Collection allClasses = Model. + getCoreHelper().getAllClasses(facade.getNamespace(actor)); + + for (Object currClass : allClasses) { + + if (facade.getName(actor).equals(facade.getName(currClass)) + && Model.getExtensionMechanismsHelper(). + hasStereoType(currClass, "secuml.role")) { + + return currClass; + } + } + } + return null; + } + + /** + * Helper function to check whether the actors was already + * mapped. Checks if there is already a SecureUML + * role with the name of the actor in its namespace. + * This function is only a dispatcher to + * {@link #getRoleClassByActor(Object) getRoleClassByActor}. + * + * @param actor An object representing an actor. + * @return true if the actor has been + * mapped already. This means the corresponding SecureUML role + * class with stereotype <<secuml.role>> is present. + * @see #getRoleClassByActor(Object) + */ + private boolean isActorAlreadyMapped(final Object actor) { + return getRoleClassByActor(actor) != null; + } + + /** + * Gets all non abstract parents of a given actor. If there + * is a abstract actor among the direct parents, the non + * abstract parents of the abstract actor are added until + * there are no more abstract actors in the current iteration. + * + * @param actor An object representing an actor. + * @return A collection containing all non abstract parents. + */ + private Collection getNonAbstractParents(final Object actor) { + final Collection parents = new ArrayList(); + + for (Object generalize : facade.getGeneralizations(actor)) { + final Object parent = facade.getParent(generalize); + if (facade.isAbstract(parent)) { + parents.addAll(getNonAbstractParents(parent)); + } else { + parents.add(parent); + } + } + return parents; + } + + /** + * Gets all non abstract actors among all actors. + * + * @return A collection containing all non abstract actors. + */ + private Collection getNonAbstractActors() { + final Collection actors = Model.getUseCasesHelper(). + getAllActors(model); + final Collection nonAbstractActors = new ArrayList(); + + for (Object actor : actors) { + if (!facade.isAbstract(actor)) { + nonAbstractActors.add(actor); + } + } + return nonAbstractActors; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/MapperException.java b/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/MapperException.java new file mode 100644 index 0000000..ad87af8 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/MapperException.java @@ -0,0 +1,22 @@ +package ch.ethz.infsec.secureumlgui.usecasemapper.mapping; + +/** + * The exception for handling + * errors during the mapping process. + * {@link MapperStrategy#map() MapperStrategy.map()} throws + * this exception in case of an error. + * + * @version 1.0 + */ +public final class MapperException extends Exception { + + /** + * Overidden default constructor to pass the + * the exception-message. + * + * @param message String containing the message. + */ + public MapperException(final String message) { + super(message); + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/MapperHelper.java b/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/MapperHelper.java new file mode 100644 index 0000000..3b59b0c --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/MapperHelper.java @@ -0,0 +1,564 @@ +package ch.ethz.infsec.secureumlgui.usecasemapper.mapping; + +import java.util.Collection; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; + +import org.apache.log4j.Logger; + +import org.argouml.model.Model; +import org.argouml.model.Facade; + +import ch.ethz.infsec.secureumlgui.main.SecureUmlConstants; +import ch.ethz.infsec.secureumlgui.modelmanagement.ModelConst; + +/** + * Provides common tools for the mapping routines. + * The class uses the singleton pattern to provide + * a global accesspoint an ensure uniqueness. + * + * @version 1.0 + */ +public final class MapperHelper { + + /** + * The log4j-logger of this class. + * + */ + private static final Logger LOGGER = Logger. + getLogger(MapperHelper.class); + + /** + * The singleton reference. + */ + private static MapperHelper singleton = new MapperHelper(); + + /** + * The collection with the predefined names of the + * stereotypes in the SecureUML package. + */ + private final Collection secumlStereoNames = + new ArrayList(6); + + /** + * The collection with the predefined names of the + * stereotypes of the ComponentUMLDialect package. + */ + private final Collection compUMLDiSteNames = + new ArrayList(7); + + /** + * The collection with the predefined names of the + * action types in the ComponentUMLDialect package. + */ + private final Collection compUMLActTyNames = + new ArrayList(6); + + /** + * Name constant for the SecureUML package. + */ + private static final String SECUML_NS_NAME = "SecureUML"; + + /** + * Name constant for the ComponentUML dialect package. + */ + private static final String CUML_DIAL_NS_NAME = "ComponentUMLDialect"; + + /** + * Name constant for the SecureUML stereotype "secuml.actiontype" + * identifying action types in the ComponentUML dialect package. + */ + @Deprecated + private static final String ACT_STEREO_NAME = SecureUmlConstants.STEREOTYPE_SECUML_ACTIONTYPE; + + /** + * Name constant for the SecureUML stereotype "secuml.permission" + * identifiying permission classes. + */ + //@Deprecated + //private static final String PERM_STEREO_NAME = SecureUmlConstants.STEREOTYPE_SECUML_PERMISSION; //"secuml.permission"; + + /** + * Hash map to cache access to the stereo types. + */ + private final Map secumlStereotypes = + new HashMap(); + + /** + * Reference in member variable makes the code + * more readable. + */ + private final Facade facade = Model.getFacade(); + + /** + * Private constructor due to singleton pattern. + */ + private MapperHelper() { }; + + /** + * Gets the MapperHelper instance. + * + * @return the MapperHelper-instance + */ + public static MapperHelper getInstance() { + return singleton; + } + + /** + * Returns the collection of all SecureUML stereotype names. + * + * @return A collection of strings being the stereotype's names. + */ + public Collection getSecumlSteNames() { + final Collection names = new ArrayList(secumlStereoNames); + names.addAll(compUMLDiSteNames); + return names; + } + + /** + * Returns the collection of all component dialect action types. + * + * @return A collection of strings being the action type's names. + */ + public Collection getCompActTypNames() { + return new ArrayList(compUMLActTyNames); + } + + /** + * Gets the SecureUML stereotype for a passed name. + * Returns null if not successful. + * + * @param model The object holding the target model. + * @param name The string containing the + * name of the desired SecureUML stereotype. + * @return The object containing stereotype if found + * or null otherwise. + */ + public Object getSecureUMLStereotype(final Object model, + final String name) { + + System.out.println("Getting SecureUML stereotype: " + name); + + if (secumlStereotypes.containsKey(name)) { + return secumlStereotypes.get(name); + } else { + LOGGER.debug("Getting SecureUML stereotype: " + name); + + final Collection stereotypes = new ArrayList(); + + stereotypes.addAll(Model.getExtensionMechanismsHelper(). + getStereotypes(getNamespace(model, + SECUML_NS_NAME))); + + stereotypes.addAll(Model.getExtensionMechanismsHelper(). + getStereotypes(getNamespace(model, + CUML_DIAL_NS_NAME))); + + for (Object stereotype : stereotypes) { + if (facade.getName(stereotype) != null + && facade.getName(stereotype).equals(name)) { + LOGGER.debug("stereotype: " + name + " found"); + return stereotype; + } + } + return null; + } + } + + /** + * Gets the SecureUML action type for a passed name. + * Returns null if not successful. + * + * @param name The string containing the + * name of the desired SecureUML action type. + * @param model The object holding the target model. + * @return The object of the action type if found or null + * otherwise. + */ + public Object getSecureUMLActionType(final Object model, + final String name) { + + LOGGER.debug("Getting SecureUML action type: " + name); + + final Collection classes = Model.getCoreHelper(). + getAllClasses(model); + + for (Object currClass : classes) { + if (facade.getName(currClass) != null + && facade.getName(currClass).equals(name) + && Model.getExtensionMechanismsHelper(). + hasStereoType(currClass, ACT_STEREO_NAME)) { + + LOGGER.debug("action type: " + name + " found"); + return currClass; + } + } + LOGGER.debug("action type: " + name + " NOT found"); + return null; + } + + /** + * Tests for circular inheritance in the role hierachies of + * all use case diagrams. + * + * @param model The object holding the target model. + * @return true if there is no circular inheritance + */ + public boolean hasNoCircularInheritance(final Object model) { + final Collection actors = Model.getUseCasesHelper(). + getAllActors(model); + + for (Object actor : actors) { + for (Object sup : Model.getCoreHelper().getAllSupertypes(actor)) { + if (facade.getUUID(actor) == facade.getUUID(sup)) { + return false; + } + } + } + + return true; + } + + /** + * Gets the messages belonging to a passed use case. Iterates over all + * collaborations and interactions thereof to finally put all messages + * of each interaction into a collection which is returned. + * + * @param collaboration The object conaining the collaboration. + * @return The collection of the associated messages. + */ + public Collection getCollabMessages(final Object collaboration) { + final Collection messages = new ArrayList(); + + for (Object interaction : facade.getInteractions(collaboration)) { + messages.addAll(facade.getMessages(interaction)); + } + return messages; + } + + /** + * Gets the attibutes of a given target class as a collection of strings. + * Only returns the names which could be resolved. + * + * @param targetClass A object being the target class. + * @return A collection of strings containing the attribute names. + */ + public Collection getAttributes(final Object targetClass) { + final Collection attributes = new ArrayList(); + for (Object attribute : facade.getAttributes(targetClass)) { + if (facade.getName(attribute) != null) { + attributes.add(facade.getName(attribute)); + } + } + return attributes; + } + + /** + * Gets the methods of a given target class as a collection of strings. + * Only returns the names which could be resolved. + * + * @param targetClass A object being the target class. + * @return A collection of strings containing the method names. + */ + public Collection getMethods(final Object targetClass) { + final Collection methods = new ArrayList(); + for (Object method : facade.getOperations(targetClass)) { + if (facade.getName(method) != null) { + methods.add(facade.getName(method)); + } + } + return methods; + } + + /** + * Gets the SecureUML role class for a given name in a given + * namespace or returns null if not found. + * + * @param name The string containing the name of the role. + * @param namespace The object holding the namespace of the role. + * @return The object being the role class or null + * if not found. + */ + public Object getRoleClassNS(final String name, + final Object namespace) { + final Collection classes = Model.getCoreHelper(). + getAllClasses(namespace); + + for (Object currClass : classes) { + if (name.equals(facade.getName(currClass)) + && Model.getExtensionMechanismsHelper(). + hasStereoType(currClass, "secuml.role")) { + return currClass; + } + } + return null; + } + + /** + * Initializes the SecureUML package of the UML model. + * Checks if all necessary elements are present and have the + * correct type. This routine should be invoked before every + * mapping run to ensure, the mapping strategies will find + * the SecureUML elements they need. + * Therefore this routine is invoked by the + * {@link ch.ethz.infsec.secureumlgui.usecasemapper.control.Controller + * Controller} in the method + * {@link ch.ethz.infsec.secureumlgui.usecasemapper.control.Controller#map() + * map}. + * + * @param model The object holding the target model. + * @throws MapperException If the SecureUML package could not be set up + * correctly. + * @see ch.ethz.infsec.secureumlgui.usecasemapper.control.Controller + */ + public void initSecureUML(final Object model) throws MapperException { + + LOGGER.info("Initializing SecureUML packages"); + + secumlStereoNames.add(ACT_STEREO_NAME); + secumlStereoNames.add(SecureUmlConstants.STEREOTYPE_SECUML_CONSTRAINT); + secumlStereoNames.add(SecureUmlConstants.STEREOTYPE_SECUML_PERMISSION); + secumlStereoNames.add(SecureUmlConstants.STEREOTYPE_SECUML_POLICY); + secumlStereoNames.add(SecureUmlConstants.STEREOTYPE_SECUML_RESOURCE); + secumlStereoNames.add(SecureUmlConstants.STEREOTYPE_SECUML_ROLE); + secumlStereoNames.add(SecureUmlConstants.STEREOTYPE_SECUML_USER); + secumlStereoNames.add(SecureUmlConstants.STEREOTYPE_SECUML_POLICY); + + compUMLDiSteNames.add("dialect.entityaction"); + compUMLDiSteNames.add("dialect.entityattributeaction"); + compUMLDiSteNames.add("dialect.entitymethodaction"); + compUMLDiSteNames.add("isCreate"); + compUMLDiSteNames.add("isDelete"); + compUMLDiSteNames.add("isExecute"); + compUMLDiSteNames.add("isQuery"); + compUMLDiSteNames.add("isUpdate"); + + compUMLActTyNames.add("create"); + compUMLActTyNames.add("delete"); + compUMLActTyNames.add("execute"); + compUMLActTyNames.add("fullAccess"); + compUMLActTyNames.add("read"); + compUMLActTyNames.add("update"); + + setupNamespace(SECUML_NS_NAME, model); + final Object secumlNamespace = getNamespace(model, SECUML_NS_NAME); + setupStereotypesNS(secumlNamespace, secumlStereoNames); + + setupNamespace(CUML_DIAL_NS_NAME, secumlNamespace); + final Object compUMLDiaNSpace = getNamespace(model, CUML_DIAL_NS_NAME); + setupStereotypesNS(compUMLDiaNSpace, compUMLDiSteNames); + + for (String currClassName : compUMLActTyNames) { + LOGGER.debug("Looking for action type: " + currClassName); + Object foundClass = null; + for (Object currClass : Model.getCoreHelper(). + getAllClasses(compUMLDiaNSpace)) { + if (currClassName.equals(facade.getName(currClass))) { + foundClass = currClass; + } + } + if (foundClass == null) { + foundClass = Model.getCoreFactory(). + buildClass(currClassName, compUMLDiaNSpace); + } + } + + for (Object currClass : Model.getCoreHelper(). + getAllClasses(compUMLDiaNSpace)) { + setupActClassStereo(currClass, + getSecureUMLStereotype(model, + ACT_STEREO_NAME)); + } + } + + /** + * Looks if a given target namespace contains a namespace + * with the given name and creates it if not found. + * + * @param namespaceName The string representing the name of the + * namespace to be looked for. + * @param targetNamespace The object being the namespace in which + * the namespace with the name + * namespaceName will be searched. + * @throws MapperException If the given namespace could not be set up + * correctly. + */ + private void setupNamespace(final String namespaceName, + final Object targetNamespace) + throws MapperException { + + Object newNamespace = getNamespace(targetNamespace, namespaceName); + + if (newNamespace == null) { + LOGGER.debug(namespaceName + " package not found."); + newNamespace = Model.getModelManagementFactory(). + createPackage(); + Model.getCoreHelper().setName(newNamespace, + namespaceName); + Model.getCoreHelper(). + addOwnedElement(targetNamespace, newNamespace); + LOGGER.debug(namespaceName + " package created."); + } + + if (getNamespace(targetNamespace, namespaceName) == null) { + LOGGER.fatal("Could not get or create Namespace: " + + namespaceName); + throw new MapperException("Could not get or create Namespace: " + + namespaceName); + } + } + + /** + * Ensures all SecureUML stereotypes given by their + * names as a collection are present in a given namespace + * and have the correct base class. + * The base class is checked with the method + * {@link #setupBaseclass(Object) setupBaseclass}. + * + * @param namespace The object being the namespace which stereotypes + * will be checked. + * @param stereonames A collection of strings containing the names of the + * stereotypes to be checked. + * + * @see #setupBaseclass(Object) + */ + private void setupStereotypesNS(final Object namespace, + final Collection stereonames) { + + for (String stereotyName : stereonames) { + LOGGER.debug("Looking for stereotype: " + stereotyName); + Object foundStereotype = null; + for (Object stereotype : Model.getExtensionMechanismsHelper(). + getStereotypes(namespace)) { + if (stereotyName.equals(facade.getName(stereotype))) { + foundStereotype = stereotype; + } + } + if (foundStereotype == null) { + foundStereotype = Model.getExtensionMechanismsFactory(). + buildStereotype(stereotyName, namespace); + } + setupBaseclass(foundStereotype); + } + } + + /** + * Sets the stereotype of a given action class to the + * SecureUML stereotype "secuml.actiontype". + * The name of this stereotype is set in the class constant + * ACT_STEREO_NAME. + * + * @param actionClass The object being a UML class which stereotype + * should be set. + * @param actionType The object holding the type for the action class. + */ + private void setupActClassStereo(final Object actionClass, + final Object actionType) { + + if (facade.getStereotypes(actionClass).size() > 1) { + final Collection stereotypes = + new ArrayList(facade.getStereotypes(actionClass)); + for (Object stereotype : stereotypes) { + Model.getCoreHelper().removeStereotype(actionClass, + stereotype); + } + } + if (!facade.getStereotypes(actionClass).contains(actionType)) { + if (facade.getStereotypes(actionClass).size() == 1) { + final Object stereotype = facade.getStereotypes(actionClass). + iterator().next(); + Model.getCoreHelper().removeStereotype(actionClass, + stereotype); + } + Model.getCoreHelper().addStereotype(actionClass, actionType); + } + } + + /** + * Gets the namespace object for a given namespace name + * or returns null if not found. + * + * @param model The object holding the target model. + * @param nsName A string representing the name of the wanted namespace. + * @return The object being the wanted namespace or null if not found. + */ + private Object getNamespace(final Object model, final String nsName) { + final Collection namespaces = Model.getModelManagementHelper(). + getAllNamespaces(model); + + for (Object namespace : namespaces) { + if (nsName.equals(facade.getName(namespace))) { + return namespace; + } + } + return null; + } + + /** + * Sets the correct base class for a given stereotype + * depending on its name. + * Maybe the variable basetypeName is not + * necessary, as there should be a possiblity to + * determine the name of a base in the ArgoUML API. + * This method is used by + * {@link #setupStereotypesNS(Object,Collection) setupStereotypesNS} + * to set the base types during the setup. + * + * @param stereotype An object being a stereotype. + * + * @see #setupStereotypesNS(Object,Collection) + */ + private void setupBaseclass(final Object stereotype) { + final Collection bases = new ArrayList(facade. + getBaseClasses(stereotype)); + Object basetype; + String basetypeName; + + // Dummy classes to be assigned as stereotype bases + final Object dummyClass = Model.getCoreFactory().createClass(); + final Object dummyAssocClass = Model.getCoreFactory(). + createAssociationClass(); + final Object dummyMessage = Model.getCollaborationsFactory(). + createMessage(); + final Object dummyAttribute = Model.getCoreFactory().createAttribute(); + + String stereotype_name = facade.getName(stereotype); + + if (SecureUmlConstants.STEREOTYPE_SECUML_PERMISSION.equals(stereotype_name)) { + basetype = dummyAssocClass; + basetypeName = "AssociationClass"; + //} else if (stereotype_name.startsWith("dialect.")) { + } else if (stereotype_name.startsWith(ModelConst.DIALECT_PACKAGE_NAME_PART + ".")) { + basetype = dummyAttribute; + basetypeName = "Attribute"; + } else if (stereotype_name.startsWith("is")) { + basetype = dummyMessage; + basetypeName = "Message"; + } else { + basetype = dummyClass; + basetypeName = "Class"; + } + + + + if (bases.size() == 1 + && !basetypeName. + equals((String) (facade.getBaseClasses(stereotype). + iterator().next()))) { + final Object base = facade.getBaseClasses(stereotype). + iterator().next(); + Model.getExtensionMechanismsHelper(). + removeBaseClass(stereotype, base); + Model.getExtensionMechanismsHelper().addBaseClass(stereotype, + basetype); + } else if (bases.size() != 1) { + for (Object base : bases) { + Model.getExtensionMechanismsHelper(). + removeBaseClass(stereotype, base); + } + Model.getExtensionMechanismsHelper().addBaseClass(stereotype, + basetype); + } + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/MapperStrategy.java b/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/MapperStrategy.java new file mode 100644 index 0000000..7939eb7 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/MapperStrategy.java @@ -0,0 +1,29 @@ +package ch.ethz.infsec.secureumlgui.usecasemapper.mapping; + +/** + * The interface for all mapping strategies. + * The {@link ch.ethz.infsec.secureumlgui.usecasemapper.control.Controller + * Controller} + * uses a strategy pattern + * to perform its mappings. + * + * @version 1.0 + * @see ch.ethz.infsec.secureumlgui.usecasemapper.control.Controller + */ +public interface MapperStrategy { + + /** + * Performs the mapping and by this implements the strategy. + * + * @throws MapperException The exception to indicate + * the mapping process failed. + */ + void map() throws MapperException; + + /** + * Sets the model the mapping is performed on. + * + * @param model The model object being the target model. + */ + void setModel(Object model); +} diff --git a/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/Permission.java b/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/Permission.java new file mode 100644 index 0000000..1f2bae8 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/Permission.java @@ -0,0 +1,807 @@ +package ch.ethz.infsec.secureumlgui.usecasemapper.mapping; + +import org.apache.log4j.Logger; + +import org.argouml.model.Model; +import org.argouml.model.Facade; +import org.argouml.model.ExtensionMechanismsHelper; + +import java.util.Collection; +import java.util.ArrayList; + +/** + * This class encapsulates SecureUML permissions. + * It may be initialized by a sender, a message and a receiver. + * The constructor then analyzes these parts and checks if it + * is a SecureUML permission and if, if it is valid. + * The authorization constraint is only calculated on demand. + * This prevents an endless loop, if there is an error in the + * predecessor and activator relationships of the messages in + * a sequence diagram. In ArgoUML 0.24 sequence diagrams with more + * than two messages are corrupt in the sense that there is no + * message with no predecessors and activators, what is obviously + * wrong, as the first message in a sequence diagram has neiher + * a predecessor nor an activator. + * If the authorization constraint would be calculated in the + * {@link #initPermission() initPermission-routine}, the + * {@link #buildAuthConstraint() buildAuthConstraint-routine} + * would enter an endless loop during the analyzation of + * a message of such a sequence diagram. As there will be always + * a predecessor or an activator which has to be analyzed, + * it will loop until a stack overflow. + * + * @version 1.1 + */ +public class Permission { + + /** + * The log4j-logger of this class. + */ + private static final Logger LOGGER = Logger.getLogger(Permission.class); + + /** + * Name constant for the action "create". + */ + private static final String CREATE_NAME = "create"; + /** + * Name constant for the action DELETE_NAME. + */ + private static final String DELETE_NAME = "delete"; + /** + * Name constant for the action EXECUTE_NAME. + */ + private static final String EXECUTE_NAME = "execute"; + /** + * Name constant for the action "read". + */ + private static final String READ_NAME = "read"; + /** + * Name constant for the action "update". + */ + private static final String UPDATE_NAME = "update"; + + /** + * The name for the permission. Note if the name is + * not set, the name returned from + * {@link #getName() getName()} is built from the + * name of the sender and the receiver of the initializing + * message. + */ + private String name = ""; + + /** + * The sender of the initializing message. + */ + private Object sender; + /** + * The initializing message. + */ + private Object message; + /** + * The receiver of the initializing message. + */ + private Object receiver; + + /** + * The additional constraints of this permission. + */ + private final Collection constraints = new ArrayList(); + + /** + * The action of the initializing message. + */ + private String action = ""; + /** + * The operation of the action. + */ + private String operation = ""; + /** + * The resource class determined from the receiver. + */ + private String resourceClass = ""; + /** + * The resource member determined from the receiver. + */ + private String resourceMember = ""; + /** + * The resource class determined from the message + * if specified. + */ + private String resourceClassMsg = ""; + + /** + * The authorization constraint for this permission. + * This constraint is built from the possible predecessors + * and activators. + */ + private String authConstraint = ""; + + /** + * The reasons as a String why this permission is + * invalid or null if it is valid. + */ + private String invalidityReasons = null; + + /** + * The reasons as a String why the authorization constraint + * of this permission is invalid or null + * if it is valid. + */ + private String authInvalidReason = null; + + /** + * A reference to the ArgoUML facade for enhanced readability. + */ + private final Facade facade = Model.getFacade(); + + /** + * Default constructor without parameters. + * Needed if a permission should be shared for several messages + * or receivers without having to create new permissions + * each time. + */ + public Permission() { + /* + Needed if a permission should be shared for several messages + or receivers without having to create new permissions + each time. + */ + + } + + /** + * Constructor to initialize the permission with + * a sender, a message and a receiver. + * + * @param aSender The object being the sender of the given message. + * @param aMessage The object being the message used for initialization. + * @param aReceiver The object being the receiver of the message. + */ + public Permission(final Object aSender, final Object aMessage, + final Object aReceiver) { + sender = aSender; + message = aMessage; + receiver = aReceiver; + + initPermission(); + } + + /** + * Constructor to initialize the permission with + * a sender, a message, a receiver and a collection of constraints. + * + * @param aSender The object being the sender of the given message. + * @param aMessage The object being the message used for initialization. + * @param aReceiver The object being the receiver of the message. + * @param theConstraints The collection containing the constraints. + */ + public Permission(final Object aSender, final Object aMessage, + final Object aReceiver, + final Collection theConstraints) { + sender = aSender; + message = aMessage; + receiver = aReceiver; + constraints.addAll(theConstraints); + + initPermission(); + } + + /** + * Sets the name of this permission to a custom name. + * + * @param aName The string containing the name for this permission. + */ + public final void setName(final String aName) { + if (aName != null) { + name = aName; + } + } + + /** + * Gets the name of this permission. If no name has been + * set, the name is constructed from the sender and the + * receiver of the initializing message. + * The method is final as it is called + * during the instantiation of the permission object to + * ensure proper creation. + * + * @return The string containing this permission's name. + * @see #buildAuthConstraint + */ + public final String getName() { + if ("".equals(name)) { + return facade.getName(sender) + facade.getName(receiver) + + "Perm"; + } else { + return name; + } + } + + /** + * Adds constraints to this permission. + * + * @param theConstraints A collection containing additional constraints. + */ + public final void addConstraints(final Collection theConstraints) { + constraints.addAll(theConstraints); + } + + /** + * Gets the sender of the initializing message. + * + * @return The sender of the initializing message. + */ + public final Object getSender() { + return sender; + } + + /** + * Sets the sender of the initial message. This is useful + * if the permission is for an abstract actor and this + * permission is later on dispatched to concrete actors. + * + * @param aSender The object containing the new sender. + */ + public final void setSender(final Object aSender) { + sender = aSender; + } + + /** + * Gets the initializing message. + * + * @return The initializing message. + */ + public final Object getMessage() { + return message; + } + + /** + * Sets the message of this permission. + * This triggers the initialization during which the + * permission is reanalyzed and checked. + * + * @param aMessage The object being the message. + * + * @see #initPermission() + */ + public final void setMessage(final Object aMessage) { + message = aMessage; + initPermission(); + } + + /** + * Gets the receiver of the initializing message. + * + * @return The receiver of the initializing message. + */ + public final Object getReceiver() { + return receiver; + } + + /** + * Sets the receiver of this permission. + * This triggers the initialization during which the + * permission is reanalyzed and checked. + * + * @param aReceiver The object being the new receiver of the message. + * + * @see #initPermission() + */ + public final void setReceiver(final Object aReceiver) { + receiver = aReceiver; + initPermission(); + } + + /** + * Gets the constraints of this permission. + * + * @return The constraints of this permission. + */ + public final Collection getConstraints() { + return new ArrayList(constraints); + } + + /** + * Adds a constraint to this permission. + * + * @param aConstraint The constraint being added to this permission. + */ + public final void addConstraint(final Object aConstraint) { + constraints.add(aConstraint); + } + + /** + * Set the constraints of this permission. + * + * @param theConstraints A collection being the new constraints. + */ + public final void setConstraints(final Collection theConstraints) { + constraints.clear(); + constraints.addAll(theConstraints); + } + + /** + * Clears the constraints of this permission. + */ + public final void clearConstraints() { + constraints.clear(); + } + + /** + * Returns whether this permission is valid. + * NOTE: Each permission not being a SecureUML Permission + * is valid by definition, as there are no further + * validity checks possible. + * + * @return True if this permission is valid. + */ + public final boolean isValid() { + return !isSecureUMLPermission() || invalidityReasons == null; + } + + /** + * Gets the reasons why a permission is invalid. + * If the permission is valid, null + * is returned. + * + * @return The string containing the invalidity reasons, + * or null if this permission is valid. + */ + public final String getInvalidityReasons() { + return invalidityReasons; + } + + /** + * Returns true if this is a + * SecureUML permission. + * + * @return True if this is a SecureUML permission. + */ + public final boolean isSecureUMLPermission() { + return getAction() != null; + } + + /** + * Returns the authorization constraint of this permission. + * The constraint is calculated on demand. To check whether + * the calculation is necessary or not, the member variable + * authConstraint is checked whether it is + * still equal its initial value. + * + * @return The authorization constraint of this permission. + */ + public final String getAuthConstraint() { + if ("".equals(authConstraint)) { + buildAuthConstraint(); + } + return authConstraint; + } + + /** + * Returns whether the authorization constraint of this + * permission is valid or not. + * The constraint is calculated on demand. To check whether + * the calculation is necessary or not, the member variable + * authConstraint is checked whether it is + * still equal its initial value. + * + * @return True if the authorization constraint + * of this permission is valid. + */ + public final boolean isAuthValid() { + if ("".equals(authConstraint)) { + buildAuthConstraint(); + } + return authInvalidReason == null; + } + + /** + * Gets the reason why the authorization constraint is invalid. + * If this permission is valid null is returned. + * The constraint is calculated on demand. To check whether + * the calculation is necessary or not, the member variable + * authConstraint is checked whether it is + * still equal its initial value. + * + * @return The string containing the invalidity reasons, + * or null if this permission is valid. + */ + public final String getAuthInvalidReason() { + if ("".equals(authConstraint)) { + buildAuthConstraint(); + } + return authInvalidReason; + } + + /** + * Returns the resource of this permission. + * + * @return The string containing the complete resource of this permission. + */ + public final String getResource() { + if ("".equals(resourceMember)) { + return resourceClass; + } else { + return resourceClass + "." + resourceMember; + } + } + + /** + * Returns the permission class attribute for this permission. + * + * @return A string containing the description for a SecureUML + * permission class attribute for this permission. + */ + public final String getPermAttribute() { + return getResource() + ":" + action; + } + + /** + * Returns the error string if this permission is invalid + * or if there is an error in the authorization constraint. + * + * @return A string containing the error message or null + * if there is no error. + */ + public final String getErrorMessage() { + if (isValid() && isAuthValid()) { + return null; + } else { + final StringBuffer errMessage = new StringBuffer(); + errMessage.append("The permission:\n"); + errMessage.append(getName()); + errMessage.append("\nis invalid.\nThe permission has the sender:"); + errMessage.append(facade.getName(getSender())); + errMessage.append("\nThe message:"); + errMessage.append(facade.getName(getMessage())); + errMessage.append("\nThe receiver:"); + errMessage.append(facade.getName(getReceiver())); + errMessage.append("\nThe error reason is:"); + + if (!isValid()) { + errMessage.append("\nThe permission is not valid:\n"); + errMessage.append(getInvalidityReasons()); + } + if (!isAuthValid()) { + errMessage. + append("\nThe authorization constraint is invalid:\n"); + errMessage.append(getAuthInvalidReason()); + } + + return errMessage.toString(); + } + } + + /** + * Initializes this permission. + * This method is called by the constructors of this class. + * The member variable authConstraint is set + * to its initial value "", as the constraint is calculated + * on demand and triggered if the member is equal to + * its intial value. + */ + private void initPermission() { + if (sender != null && receiver != null + && message != null && getAction() != null) { + analyzePermission(); + checkPermission(); + authConstraint = ""; + } + } + + /** + * Analyzes the permission and sets the member variables. + * Looks at the message and the receiver of the message + * for analyzation. + */ + private void analyzePermission() { + + action = getAction(); + + if (facade.isACallAction(facade.getAction(message)) + && facade.getOperation(facade.getAction(message)) != null) { + operation = facade. + getName(facade.getOperation(facade.getAction(message))); + } + if (facade.getName(receiver) != null) { + resourceClass = facade.getName(receiver); + } + if (facade.getName(message) != null + && !resourceClass.equals(facade.getName(message))) { + resourceMember = facade.getName(message); + } + if (resourceMember.indexOf('.') != -1) { + resourceClassMsg = resourceMember. + substring(0, resourceMember.indexOf('.')); + resourceMember = resourceMember. + substring(resourceMember.indexOf('.') + 1); + } + if (EXECUTE_NAME.equals(action) && "".equals(resourceMember)) { + resourceMember = operation; + } + } + + /** + * Checks this permission for correctness. + * + * @see #checkExecute() + * @see #checkNonExistAttribute() + * @see #checkClassActionOnAttr() + */ + private void checkPermission() { + final StringBuffer errorMsg = new StringBuffer(110); + + // class name in message does not match target + if (!"".equals(resourceClassMsg) + && !resourceClass.equals(resourceClassMsg)) { + errorMsg.append("\nMessage target: "); + errorMsg.append(resourceClassMsg); + errorMsg.append("\nis different from:"); + errorMsg.append(resourceClass); + } + + if (EXECUTE_NAME.equals(action)) { + errorMsg.append(checkExecute()); + + } else if (READ_NAME.equals(action) || UPDATE_NAME.equals(action)) { + errorMsg.append(checkNonExistAttribute()); + + } else if (CREATE_NAME.equals(action) || DELETE_NAME.equals(action)) { + errorMsg.append(checkClassActionOnAttr()); + } + + if (errorMsg.length() > 0) { + invalidityReasons = errorMsg.toString(); + LOGGER.error("Exception occured during predicate check:\n" + + errorMsg.toString()); + } + } + + /** + * Tests the validity of a "execute"-action. + * Performs three tests: + * 1. If the operation of the message's action is set, + * checks if the resource member equals the operation. + * 2. If the resource member is set at all. + * 3. If the resource member is a method. + * + * @return A string containing the error message or an empty + * string if everything is fine. + */ + private String checkExecute() { + final StringBuffer errorMsg = new StringBuffer(80); + final Collection methods = getMethods(); + + // operation and resourceMember don't match + if (!"".equals(operation) && !resourceMember.equals(operation)) { + errorMsg.append("\nOperation does not match\n("); + errorMsg.append(resourceMember); + errorMsg.append(')'); + } + if ("".equals(resourceMember)) { + errorMsg.append("\nexecute must have method set\n" + + "either in the message or as an\noperation"); + } + if (!methods.contains(resourceMember)) { + errorMsg.append("execute must have a method as target\n("); + errorMsg.append(resourceMember); + errorMsg.append(')'); + } + + return errorMsg.toString(); + } + + /** + * Tests for a attribute action on a non-existing attribute. + * Returns an empty string if everything is fine or the + * error message otherwise. + * + * @return A string containing the error message or an empty + * string if everything is fine. + */ + private String checkNonExistAttribute() { + final StringBuffer errorMsg = new StringBuffer(); + final Collection attributes = getAttributes(); + + if (!"".equals(resourceMember) + && !attributes.contains(resourceMember)) { + errorMsg.append("Access to non-existing attribute\n("); + errorMsg.append(resourceMember); + errorMsg.append(')'); + } + return errorMsg.toString(); + } + + /** + * Tests for a class action on a attribute. + * For example a create or delete on a attribute. + * Returns an empty String if everything is fine or + * the error message otherwise. + * + * @return A string containing the error message or an empty + * string if everything is fine. + */ + private String checkClassActionOnAttr() { + final StringBuffer errorMsg = new StringBuffer(); + + if (!"".equals(resourceMember)) { + errorMsg.append("\ncreate and delete are not allowed\n" + + "for members ("); + errorMsg.append(resourceMember); + errorMsg.append(')'); + } + return errorMsg.toString(); + } + + /** + * Determines the action of a message by looking at its stereotype. + * Returns null if it is not a SecureUML action or + * the action could not be determined. + * Return messages are by default a READ_NAME. + * + * @return the string action the message symbolizes. + */ + private String getAction() { + final ExtensionMechanismsHelper helper = Model. + getExtensionMechanismsHelper(); + + String foundAction = null; + + if (message != null) { + if (helper.hasStereoType(message, "isCreate")) { + foundAction = CREATE_NAME; + } else if (helper.hasStereoType(message, "isDelete")) { + foundAction = DELETE_NAME; + } else if (helper.hasStereoType(message, "isUpdate")) { + foundAction = UPDATE_NAME; + } else if (helper.hasStereoType(message, "isQuery")) { + foundAction = READ_NAME; + } else if (facade.isAReturnAction(facade.getAction(message))) { + foundAction = READ_NAME; + } else if (helper.hasStereoType(message, "isExecute")) { + foundAction = EXECUTE_NAME; + } + } + return foundAction; + } + + /** + * Gets the attibutes of a given target class as a collection of strings. + * Only returns the names which could be resolved. + * + * @return A collection of strings containing the attribute names. + */ + private Collection getAttributes() { + final Collection attributes = new ArrayList(); + for (Object attribute : facade.getAttributes(receiver)) { + if (facade.getName(attribute) != null) { + attributes.add(facade.getName(attribute)); + } + } + return attributes; + } + + /** + * Gets the methods of a given target class as a collection of strings. + * Only returns the names which could be resolved. + * + * @return A collection of strings containing the method names. + */ + private Collection getMethods() { + final Collection methods = new ArrayList(); + for (Object method : facade.getOperations(receiver)) { + if (facade.getName(method) != null) { + methods.add(facade.getName(method)); + } + } + return methods; + } + + /** + * Constructs the authorization sequence constraint expression + * for this permission. + * The constraints for a message are all predecessors and + * activators. + */ + private void buildAuthConstraint() { + final StringBuffer authText = new StringBuffer(17); + final Collection predecessors = Model.getCollaborationsHelper(). + getAllPossiblePredecessors(message); + final Collection activators = Model.getCollaborationsHelper(). + getAllPossibleActivators(message); + + authText.append("context:" + getName() + "\nauth:"); + + if (!predecessors.isEmpty()) { + authText.append("\n("); + authText.append(getAuthByMessages(predecessors)); + authText.append(')'); + } + + if (!activators.isEmpty()) { + if (!predecessors.isEmpty()) { + authText.append("\nand"); + } + authText.append("\n("); + authText.append(getAuthByMessages(activators)); + authText.append(')'); + } + + if (!("context:" + getName() + "\nauth:"). + equals(authText.toString())) { + authConstraint = authText.toString(); + } + } + + /** + * Constructs an authorization sequence for a collection + * of given messages. + * + * @param messages A collection containing the necessary messages. + * + * @return A string containing the authorization constraint. + */ + private String getAuthByMessages(final Collection messages) { + final StringBuffer authText = new StringBuffer(); + final StringBuffer senders = new StringBuffer(); + final StringBuffer receivers = new StringBuffer(); + final Permission permission = new Permission(); + final String delimiter = " and\n"; + + for (Object currMessage : messages) { + permission.setMessage(currMessage); + senders.setLength(0); + receivers.setLength(0); + + if (permission.isSecureUMLPermission()) { + senders.append('{'); + + permission.setSender(facade. + getBases(facade.getSender(currMessage)). + iterator().next()); + + for (Object currSender : facade. + getBases(facade.getSender(currMessage))) { + senders.append(facade.getName(currSender)); + senders.append(", "); + } + senders.delete(senders.length() - 2, senders.length()); + senders.append('}'); + + authText.append("auth: "); + authText.append(senders); + authText.append(' '); + + receivers.append(" {"); + for (Object currReceiver : facade. + getBases(facade.getReceiver(currMessage))) { + permission.setReceiver(currReceiver); + + if (permission.isSecureUMLPermission() + && permission.isValid()) { + receivers.append(facade.getName(currReceiver)); + receivers.append(", "); + } else { + authInvalidReason = permission.invalidityReasons; + } + } + receivers.delete(receivers.length() - 2, receivers.length()); + receivers.append('}'); + + authText.append(permission.resourceMember); + authText.append(':'); + authText.append(permission.action); + + authText.append(receivers); + authText.append(delimiter); + } + } + + if (authText.length() >= delimiter.length()) { + authText.delete(authText.length() - delimiter.length(), + authText.length()); + } + + return authText.toString(); + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/PermissionMapper.java b/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/PermissionMapper.java new file mode 100644 index 0000000..2b9729e --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/PermissionMapper.java @@ -0,0 +1,774 @@ +package ch.ethz.infsec.secureumlgui.usecasemapper.mapping; + +import java.util.Collection; +import java.util.ArrayList; + +import org.apache.log4j.Logger; + +import org.argouml.model.Model; +import org.argouml.model.Facade; + +import ch.ethz.infsec.secureumlgui.main.SecureUmlConstants; +import ch.ethz.infsec.secureumlgui.modelmanagement.ModelConst; + +/** + * Mapping strategy for mapping sequence diagrams + * and role hierarchies to SecureUML permissions. + * + * @version 1.0 + */ +public class PermissionMapper implements MapperStrategy { + + /** + * The log4j-logger of this class. + */ + private static final Logger LOGGER = Logger. + getLogger(PermissionMapper.class); + + /** + * Name constant for the action EXECUTE_NAME. + */ + private static final String EXECUTE_NAME = "execute"; + /** + * Name constant for the action "read". + */ + private static final String READ_NAME = "read"; + /** + * Name constant for the action "update". + */ + private static final String UPDATE_NAME = "update"; + + /** + * A global reference to the model facade of ArgoUML for more readability. + */ + private final Facade facade = Model.getFacade(); + + /** + * A global reference to the MapperHelper for more readability. + */ + private final MapperHelper mapperHelper = MapperHelper.getInstance(); + + /** + * A global reference to the target model. + */ + private Object model = null; + + /** + * Maps the sequence diagrams and role hierarchies + * to SecureUML permissions. + * Uses {@link MapperHelper#getCollabMessages(Object) getCollabMessages} + * from {@link MapperHelper MapperHelper} to determine the + * messages of the collaboration. + * + * @throws MapperException The exception to indicate + * the mapping process failed. + * @see MapperHelper#getCollabMessages(Object) + */ + public final void map() throws MapperException { + + if (model == null) { + throw new MapperException("Target model undefined."); + } else { + LOGGER.debug("Getting use case diagrams of root level:"); + + final Collection constraints = new ArrayList(); + + final Collection usecases = Model.getUseCasesHelper(). + getAllUseCases(model); + + for (Object usecase : usecases) { + + LOGGER.info("Analyzing usecase: " + facade.getName(usecase)); + + final Collection actors = Model.getCoreHelper(). + getAssociatedClassifiers(usecase); + + for (Object collab : facade.getCollaborations(usecase)) { + for (Object message : mapperHelper. + getCollabMessages(collab)) { + constraints.clear(); + mapMessageToPermissions(message, actors, constraints); + } + analyzeExtends(usecase, collab); + } + + analyzeIncludes(usecase); + + LOGGER.debug("Analyzing specializations of usecase: " + + facade.getName(usecase)); + + for (Object child : Model.getCoreHelper(). + getChildren(usecase)) { + + LOGGER.debug("Analyzing specialization: " + + facade.getName(child)); + for (Object coll : facade.getCollaborations(child)) { + for (Object message : mapperHelper. + getCollabMessages(coll)) { + constraints.clear(); + mapMessageToPermissions(message, actors, + constraints); + } + } + } + } + cleanup(); + } + } + + /** + * Sets the model the mapping is performed on. + * + * @param targetModel The object being the target model. + */ + public final void setModel(final Object targetModel) { + model = targetModel; + } + + /** + * Maps a UML-message to permissions. + * + * @param message The object containing the message. + * @param usecaseActors The collection containing the actors of + * the usecase the message is from. + * @param comments The collection containing any comments + * to be added as constraints. + * + * @throws MapperException If the message could not be mapped. + * More precisely the exception + * originates form + * {@link #createPermission(Permission) + * createPermission} if there is an error. + * @see #createPermission(Permission) + */ + private void mapMessageToPermissions(final Object message, + final Collection usecaseActors, + final Collection comments) + throws MapperException { + + LOGGER.debug("Analyzing message: " + facade.getName(message)); + + final Collection senderBases = facade.getBases(facade. + getSender(message)); + final Collection receiverBases = facade. + getBases(facade.getReceiver(message)); + final Permission permission = new Permission(); + + for (Object basis : senderBases) { + if (usecaseActors.contains(basis)) { + for (Object receiverBasis : receiverBases) { + + permission.setSender(basis); + permission.setMessage(message); + permission.setReceiver(receiverBasis); + permission.setConstraints(comments); + + addAuthConstraint(permission); + + createPermission(permission); + } + } + } + // iterate over receiver bases for return messages and + // constrained reads + if (facade.isAReturnAction(facade.getAction(message))) { + for (Object receiverBasis : receiverBases) { + if (usecaseActors.contains(receiverBasis)) { + for (Object senderBasis : senderBases) { + + permission.setSender(receiverBasis); + permission.setMessage(message); + permission.setReceiver(senderBasis); + permission.setConstraints(comments); + + LOGGER.debug("Generating sequenced read: " + + facade.getName(permission.getSender()) + + " " + + permission.getPermAttribute()); + + addAuthConstraint(permission); + + createPermission(permission); + } + } + } + } + } + + /** + * Creates the given permission in the ArgoUML model. + * If the sender of the {@link Permission Permission} + * is abstract, the creation is dispatched to + * {@link #createPermissionAActor(Permission) createPermissionAActor}. + * Afterwards it is checked whether the permission + * already exists and if not, if at least the + * permission class exists. + * The permission class is created if necessary and + * finally the permission is added. + * + * @param permission The permission to be created. + * + * @throws MapperException If the given permission could not be + * created. + */ + private void createPermission(final Permission permission) + throws MapperException { + if (permission.isSecureUMLPermission() && permission.isValid()) { + if (facade.isAbstract(permission.getSender())) { + createPermissionAActor(permission); + } else if (hasPermission(permission.getSender(), + permission.getPermAttribute(), + permission.getReceiver(), + permission.getConstraints())) { + LOGGER.debug("Perm already exists."); + } else { + Object permissionClass = + getPermissionClass(permission.getSender(), + permission.getReceiver(), + permission.getConstraints()); + if (permissionClass == null) { + LOGGER.debug("New permission class needed"); + + final Object subjectClass = mapperHelper. + getRoleClassNS(facade.getName(permission.getSender()), + facade.getNamespace(permission. + getSender())); + if (subjectClass == null) { + LOGGER.error("Could not find role class for: " + + facade.getName(permission.getSender())); + } else { + permissionClass = Model.getCoreFactory(). + buildAssociationClass(subjectClass, permission. + getReceiver()); + Model.getCoreHelper().setName(permissionClass, + permission.getName()); + + Model.getCoreHelper(). + addStereotype(permissionClass, mapperHelper. + getSecureUMLStereotype(model, + SecureUmlConstants.STEREOTYPE_SECUML_PERMISSION)); + + Model.getCoreHelper(). + addOwnedElement(facade.getNamespace(permission. + getSender()), + permissionClass); + + for (Object comment : permission.getConstraints()) { + Model.getCoreHelper().addComment(permissionClass, + comment); + } + } + } + LOGGER.debug("Adding permission: " + permission. + getPermAttribute()); + addPermission(permissionClass, permission.getPermAttribute()); + } + } else if (!permission.isValid()) { + throw new MapperException(permission.getErrorMessage()); + } + } + + /** + * Dispatcher for + * {@link #createPermission(Permission) createPermission} + * to handle abstract actors. + * Makes a backup of the old constraints and uses a different + * collection for the forks, which is reset in every iteration. + * This ensures if a future manipulation of the permission's + * constraints makes changes, the intial state will be restored. + * + * @param permission The permission to be created. + * + * @throws MapperException If the given permission could not be + * created. More precisely the + * exception is thrown by the + * {@link #createPermission(Permission) + * createPermission} method. + * + * @see #createPermission(Permission) + */ + private void createPermissionAActor(final Permission permission) + throws MapperException { + final Collection oldConstraints = permission.getConstraints(); + final Collection newConstraints = new ArrayList(); + + for (Object specialization : facade. + getSpecializations(permission.getSender())) { + + final Object child = facade.getChild(specialization); + LOGGER.debug("Dispatch from " + facade. + getName(permission.getSender()) + + " to " + facade.getName(child)); + + newConstraints.clear(); + newConstraints.addAll(oldConstraints); + newConstraints.addAll(facade.getComments(permission.getSender())); + permission.setName(permission.getName()); + permission.setSender(child); + permission.setConstraints(newConstraints); + + createPermission(permission); + } + } + + /** + * Retrieves the permission class for a subject and object if existing. + * Takes the subject and object pair and constraints + * and looks for an appropriate SecureUML permission class. + * If there is no such class, null is returned. + * + * @param subject The Object containing the subject. + * @param object The Object containing the object. + * @param comments The Collection containing optional constraints. + * @return The permission class or null if none found. + */ + private Object getPermissionClass(final Object subject, + final Object object, + final Collection comments) { + + final Collection permissionClasses = + getPermissionClassesNS(facade.getNamespace(subject)); + + for (Object currClass : permissionClasses) { + final Collection connections = facade.getConnections(currClass); + + final Object association = facade.getAssociation(connections. + iterator().next()); + /* Check if source and destination match + the subject and the object */ + final String sourceName = facade.getName(Model.getCoreHelper(). + getSource(association)); + final String destName = facade.getName(Model.getCoreHelper(). + getDestination(association)); + final Collection currComments = facade.getComments(currClass); + + if (sourceName != null && destName != null + && sourceName.equals(facade.getName(subject)) + && destName.equals(facade.getName(object)) + && currComments.equals(comments)) { + LOGGER.debug("Permission class already exists: " + + facade.getName(currClass)); + return currClass; + } + } + return null; + } + + /** + * Retrieves the permission classes for a subject and object + * which have the same or less comments (=constraints). + * Takes the subject and object pair and constraints + * and looks for an appropriate SecureUML permission class. + * If there is no such class, null is returned. + * Also tries to find a appropriate permission among the + * parents of the subject by traversing the role hierarchy. + * + * @param subject The Object containing the subject. + * @param predicate The string holding the predicate. + * @param object The Object containing the object. + * @param comments The Collection containing optional constraints. + * @return a collection of equal permissions or null + * if none found. + * is already present. + */ + private Collection getPermissions(final Object subject, + final String predicate, + final Object object, + final Collection comments) { + + final Collection permissions = new ArrayList(); + final Collection permissionClasses = + getPermissionClassesNS(facade.getNamespace(subject)); + + for (Object currClass : permissionClasses) { + final Collection connections = facade.getConnections(currClass); + + final Object association = facade.getAssociation(connections. + iterator().next()); + /* Check if source and destination match + the subject and the object */ + final Collection reachableActors = Model.getCoreHelper(). + getAllSupertypes(subject); + reachableActors.add(subject); + + for (Object actor : reachableActors) { + final String sourceName = facade. + getName(Model.getCoreHelper().getSource(association)); + final String destName = facade. + getName(Model.getCoreHelper().getDestination(association)); + final Collection currComments = facade.getComments(currClass); + + if (!facade.isAbstract(actor) + && sourceName != null && destName != null + && sourceName.equals(facade.getName(actor)) + && destName.equals(facade.getName(object)) + && comments.containsAll(currComments)) { + + permissions.addAll(getClassPermissions(currClass, + predicate)); + } + } + } + return permissions; + } + + /** + * Tests whether a permission is already given. + * This method is different from + * {@link #getPermissions(Object,String,Object,Collection) getPermissions} + * in the way that only the direct subjects are compared + * and the role hierarchy is ignored. Permissions + * having less constraints are also ignored. + * These checks are delegated to getPermissions + * by calling it after the comments have been resolved. + * This methode checks only for exact matches and + * is used in + * {@link #createPermission(Permission) createPermission} + * to make sure, such a permission does not + * already exist. + * In contrast to getPermissions this method + * can also deal with comments which are not attached to + * a permission yet by resolving these to already existing + * ones. + * + * @param subject An object being the subject of the permission. + * @param predicate A string describing the action. + * @param object An object being the object of the permission. + * @param comments A collection of comments of the permission. + * @return true if the permission already exists. + * @see #getPermissions(Object,String,Object,Collection) + * @see #createPermission(Permission) + */ + private boolean hasPermission(final Object subject, + final String predicate, + final Object object, + final Collection comments) { + final Collection permClasses = getPermissionClassesNS(model); + final Collection newComments = new ArrayList(); + final Collection existComments = new ArrayList(comments); + final Collection classComments = new ArrayList(); + Collection foundComments = new ArrayList(); + + // Split the comments into existing ones and ones to be created + for (Object comment : comments) { + if (facade.getNamespace(comment) == null) { + existComments.remove(comment); + newComments.add(comment); + } + } + for (Object permClass : permClasses) { + LOGGER.debug(facade.getName(permClass)); + if (facade.getComments(permClass).containsAll(existComments)) { + LOGGER.debug("has all perms: " + facade.getName(permClass)); + classComments.clear(); + classComments.addAll(facade.getComments(permClass)); + classComments.removeAll(existComments); + foundComments = getMatchingComments(newComments, + classComments); + classComments.addAll(foundComments); + classComments.addAll(existComments); + if (newComments.size() == foundComments.size() + && getPermissions(subject, predicate, object, + classComments).size() > 0) { + return true; + } + } + } + return false; + } + + /** + * Compares the comments of a given collection newComments + * with another collection oldComments and returns + * a collection of objects from oldComments which + * match by String comparison. + * + * @param newComments A collection of comments objects. + * @param oldComments Another collection of comments objects. + * @return The collection of matching comments in terms of + * oldComments. + */ + private Collection getMatchingComments(final Collection newComments, + final Collection oldComments) { + final Collection foundComments = new ArrayList(); + + for (Object newComment : newComments) { + boolean isCommentAdded = false; + for (Object oldComment : oldComments) { + if (!isCommentAdded + && ((String) facade.getBody(newComment)). + equals((String) facade.getBody(oldComment))) { + foundComments.add(oldComment); + isCommentAdded = true; + } + } + } + return foundComments; + } + + /** + * Checks whether a given permission class has a predicate. + * + * @param permClass The Object containing the permission class. + * @param predicate The String formulating the access rights. + * @return the object reference to the permission or null + * if not found. + */ + private Collection getClassPermissions(final Object permClass, + final String predicate) { + final Collection permissions = new ArrayList(); + final Collection attributes = facade.getAttributes(permClass); + String predicateTarget = predicate; + String permissionType = ""; + + if (predicate.indexOf(':') != -1) { + permissionType = predicate.split(":")[1]; + predicateTarget = predicate.split(":")[0]; + } + for (Object attribute : attributes) { + LOGGER.debug(predicate + " vs. " + facade.getName(attribute)); + if (facade.getType(attribute) != null && permissionType. + equals(facade.getName(facade.getType(attribute)))) { + if ((permissionType.equals(READ_NAME) + || permissionType.equals(UPDATE_NAME)) + && facade.getName(attribute).indexOf('.') == -1) { + LOGGER.debug(facade.getName(permClass) + + "has predicate " + predicate); + permissions.add(attribute); + } else if (predicateTarget.equals(facade. + getName(attribute))) { + LOGGER.debug(facade.getName(permClass) + + " has predicate " + predicate); + permissions.add(attribute); + } + } + } + return permissions; + } + + /** + * Adds a given predicate to a given permission class object. + * + * @param permClass An object being the target permission class. + * @param predicate A string containing the new predicate. + */ + private void addPermission(final Object permClass, + final String predicate) { + String target = predicate; + String action = ""; + Object attribute; + + if (predicate.indexOf(':') == -1) { + attribute = Model.getCoreFactory().createAttribute(); + Model.getCoreHelper().addFeature(permClass, attribute); + } else { + target = predicate.split(":")[0]; + action = predicate.split(":")[1]; + + attribute = Model.getCoreFactory(). + buildAttribute(permClass, model, mapperHelper. + getSecureUMLActionType(model, action)); + if (target.indexOf('.') == -1) { + Model.getCoreHelper(). + addStereotype(attribute, mapperHelper. + getSecureUMLStereotype(model, "dialect.entityaction")); + } else if (READ_NAME.equals(action) || UPDATE_NAME.equals(action)) { + Model.getCoreHelper(). + addStereotype(attribute, mapperHelper. + getSecureUMLStereotype(model, "dialect.entityattributeaction")); + } else if (EXECUTE_NAME.equals(action)) { + Model.getCoreHelper(). + addStereotype(attribute, mapperHelper. + getSecureUMLStereotype(model, "dialect.entitymethodaction")); + } + } + Model.getCoreHelper().setName(attribute, target); + } + + /** + * Analyzes the includes of a given use-case. + * + * @param usecase An object being a use-case. + * + * @throws MapperException If the analyzation of the given usecase fails. + */ + private void analyzeIncludes(final Object usecase) + throws MapperException { + LOGGER.debug("Analyzing includes of usecase: " + + facade.getName(usecase)); + final Collection connections = facade.getIncludes(usecase); + + for (Object connection : connections) { + final Object connected = Model.getCoreHelper(). + getDestination(connection); + + LOGGER.debug("Analyzing include: " + facade.getName(connected)); + for (Object incCollab : facade.getCollaborations(connected)) { + analyzeExtendInclude(usecase, incCollab, + facade.getComments(connection)); + } + } + } + + /** + * Analyzes a given collaboration of a given use-case in terms + * of its extenders. + * + * @param usecase The object of the use-case being analyzed. + * @param collaboration An object holding a collaboration of the + * given use-case. + * + * @throws MapperException If the analyzation of the extend fails. + */ + private void analyzeExtends(final Object usecase, + final Object collaboration) + throws MapperException { + LOGGER.debug("Analyzing extends of usecase: " + + facade.getName(usecase)); + final Collection extenders = facade.getExtends(usecase); + final Collection constraints = new ArrayList(); + + for (Object extend : extenders) { + LOGGER.debug("Analyzing extend to: " + + facade.getName(Model.getCoreHelper(). + getDestination(extend))); + constraints.clear(); + String extendCondition = ""; + if (facade.getCondition(extend) != null) { + extendCondition = (String) facade. + getBody(facade.getCondition(extend)); + } + + if (!"".equals(extendCondition)) { + final Object comment = Model.getCoreFactory().createComment(); + Model.getCoreHelper().setBody(comment, (String) + facade.getBody(facade. + getCondition(extend))); + constraints.add(comment); + } + analyzeExtendInclude(Model.getCoreHelper().getDestination(extend), + collaboration, constraints); + } + } + + /** + * Analyze extend or include of a given usecase by looking at a given + * collaboration and possible constraints. + * Uses {@link MapperHelper#getCollabMessages(Object) getCollabMessages} + * from {@link MapperHelper MapperHelper} to determine the + * messages of the collaboration. + * + * @param usecase An object being a use case. + * @param collaboration An object being the collaboration + * to look at. + * @param comments A collection of comments being possible constraints. + * + * @throws MapperException If the analyzation of the include or exclude + * fails. + * + * @see MapperHelper#getCollabMessages(Object) + */ + private void analyzeExtendInclude(final Object usecase, + final Object collaboration, + final Collection comments) + throws MapperException { + final Collection actors = Model.getCoreHelper(). + getAssociatedClassifiers(usecase); + + LOGGER.debug("Mapping rights for associated usecase."); + for (Object message : mapperHelper. + getCollabMessages(collaboration)) { + mapMessageToPermissions(message, actors, comments); + } + } + + /** + * Removes all duplicate permissions and empty permission classes. + */ + private void cleanup() { + final Collection permissionClasses = getPermissionClassesNS(model); + + for (Object permissionClass : permissionClasses) { + for (Object attribute : facade.getAttributes(permissionClass)) { + + final String permissionType = facade.getName(facade. + getType(attribute)); + final String predicateTarget = facade.getName(attribute); + + final Collection connections = facade. + getConnections(permissionClass); + + final Object association = facade.getAssociation(connections. + iterator().next()); + final Object subject = Model.getCoreHelper(). + getSource(association); + final Object object = Model.getCoreHelper(). + getDestination(association); + final String predicate = predicateTarget + ":" + + permissionType; + + final Collection permissions = getPermissions(subject, + predicate, + object, facade. + getComments(permissionClass)); + LOGGER.debug("For permission: " + predicate + " of role " + + facade.getName(subject) + " found " + + permissions.size() + " equal permissions"); + if (permissions.size() > 1) { + LOGGER.debug("removing permission for: " + + facade.getName(subject)); + Model.getCoreHelper(). + removeFeature(permissionClass, attribute); + } + } + // remove empty permission classes + if (facade.getAttributes(permissionClass).isEmpty()) { + Model.getCoreHelper(). + removeOwnedElement(facade.getNamespace(permissionClass), + permissionClass); + } + } + } + + /** + * Retrieves all SecureUML permission classes + * from a given namespace. + * + * @param namespace The Object containing the target namespace. + * @return A Collection containing all permission classes found. + */ + private Collection getPermissionClassesNS(final Object namespace) { + final Collection permissionClasses = new ArrayList(); + final Collection allClasses = Model.getCoreHelper(). + getAllClasses(namespace); + + for (Object currClass : allClasses) { + if (Model.getExtensionMechanismsHelper(). + hasStereoType(currClass, SecureUmlConstants.STEREOTYPE_SECUML_PERMISSION)) { + permissionClasses.add(currClass); + } + } + return permissionClasses; + } + + /** + * Adds the authorization constraint to the given permission. + * If the authorization constraint is invalid or empty, + * no comment will be created in the model. + * + * @param permission The object being a permission. + */ + private void addAuthConstraint(final Permission permission) { + if (permission.isSecureUMLPermission() + && permission.isValid() + && permission.isAuthValid() + && !"".equals(permission.getAuthConstraint())) { + + final Object comment = Model. + getCoreFactory().createComment(); + Model.getCoreHelper(). + setBody(comment, permission.getAuthConstraint()); + permission.addConstraint(comment); + } + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/package.html b/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/package.html new file mode 100644 index 0000000..b5e5b0c --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/package.html @@ -0,0 +1,15 @@ + + + + + + +The mapping package contains the different mapping +strategies. +They are used by the class +{@link ch.ethz.infsec.secureumlgui.usecasemapper.control.Controller Controller} +in the package +{@link ch.ethz.infsec.secureumlgui.usecasemapper.control control}. + + + diff --git a/src/ch/ethz/infsec/secureumlgui/usecasemapper/package.html b/src/ch/ethz/infsec/secureumlgui/usecasemapper/package.html new file mode 100644 index 0000000..5d60c89 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/usecasemapper/package.html @@ -0,0 +1,11 @@ + + + + + + +Provides the mapping functionality of use cases to SecureUML permissions. + + + + diff --git a/src/ch/ethz/infsec/secureumlgui/util/ExcpPermissionDummy.java b/src/ch/ethz/infsec/secureumlgui/util/ExcpPermissionDummy.java new file mode 100644 index 0000000..dc658a5 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/util/ExcpPermissionDummy.java @@ -0,0 +1,22 @@ +package ch.ethz.infsec.secureumlgui.util; + +public class ExcpPermissionDummy extends PermissionDummy { + + public ExcpPermissionDummy(String name) { + super(name); + // TODO Auto-generated constructor stub + } + + // + + private Object excpLevel; + + public Object getExcpLevel() { + return this.excpLevel; + } + + public void setExcpLeve(Object excpLevel) { + this.excpLevel = excpLevel; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/util/ExtensionFilenameFilter.java b/src/ch/ethz/infsec/secureumlgui/util/ExtensionFilenameFilter.java new file mode 100644 index 0000000..30d366b --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/util/ExtensionFilenameFilter.java @@ -0,0 +1,39 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.util; + +import java.io.File; +import java.io.FilenameFilter;; + +/** + * + */ +public class ExtensionFilenameFilter implements FilenameFilter +{ + /** + * + */ + public ExtensionFilenameFilter(String fileExtension) + { + this.fileExtension = fileExtension; + + while(fileExtension.startsWith("\\.")) + fileExtension = fileExtension.substring(1); + } + + String fileExtension; + + /* (non-Javadoc) + * @see java.io.FilenameFilter#accept(java.io.File, java.lang.String) + */ + public boolean accept(File dir, String name) + { + if(name.endsWith("." + fileExtension)) + return true; + else + return false; + + + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/util/NotImplementedException.java b/src/ch/ethz/infsec/secureumlgui/util/NotImplementedException.java new file mode 100644 index 0000000..fcc6950 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/util/NotImplementedException.java @@ -0,0 +1,14 @@ +package ch.ethz.infsec.secureumlgui.util; + + +/** + * + * Exception to throw from Methods that are not implemented yet + * (used in my (manually generated) Implementations + * of the JMI Interfaces) + * + */ +public class NotImplementedException extends Exception +{ + +} diff --git a/src/ch/ethz/infsec/secureumlgui/util/PermissionDummy.java b/src/ch/ethz/infsec/secureumlgui/util/PermissionDummy.java new file mode 100644 index 0000000..0c7bbe0 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/util/PermissionDummy.java @@ -0,0 +1,138 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.util; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; + +//import ch.ethz.infsec.secureumlgui.securemodel.componentuml.Entity; +//import ch.ethz.infsec.secureumlgui.securemodel.secureuml.Permission; +import ch.ethz.infsec.secureumlgui.wrapper.AuthorizationConstraintWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.NamedModelElementWrapper; +import ch.ethz.infsec.secureumlgui.wrapper.RoleWrapper; +//import ch.ethz.infsec.secureumlgui.securemodelimpl.secureuml.PermissionImpl; +import ch.ethz.infsec.secureumlgui.wrapper.PermissionWrapper; + +/** + * represents the permission association class in a UML model. + * + * The main difference to a SecureUML permission therefore is that it + * can have more than one action. (which are represented by permission + * wrappers here). + * + * + */ +public class PermissionDummy +/*extends PermissionImpl*/ +{ + private String name; + private Object /*Entity*/anchor; + private List/**/permissionAttributes = new ArrayList(); + private Object authorizationConstraint; + private Object role; + private Object policy; + + + /** + * + */ + public PermissionDummy(String name) { + //super(name); + this.name = name; + } + + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Object /*Resource*/getAnchor() { + return anchor; + } + + public void setAnchor(Object anchor) { + this.anchor = anchor; + } + + public Object getPolicy() { + return this.policy; + } + + public void setPolicy(Object policy) { + this.policy = policy; + } + + public void setAnchorWrapper(NamedModelElementWrapper anchorWrapper) { + this.anchor = anchorWrapper.getModelElement(); + } + + public NamedModelElementWrapper /*Resource*/getAnchorWrapper() { + return new NamedModelElementWrapper(anchor); + } + + public List/**/getPermissionAttributes() { + return permissionAttributes; + } + + public void addPermissionAttribute(Object permissionAttribute) { + permissionAttributes.add(permissionAttribute); + } + + public List getPermissionAttributeWrappers() { + List permissionAttributeWrappers = new ArrayList(); + + for (Iterator iter = permissionAttributes.iterator(); iter.hasNext();) { + Object permissionAttribute = (Object) iter.next(); + + permissionAttributeWrappers.add(new PermissionWrapper( + permissionAttribute)); + } + return permissionAttributeWrappers; + } + + public void addPermissionWrapper(PermissionWrapper pw) { + Object permissionAttribute = pw.getModelElement(); + + permissionAttributes.add(permissionAttribute); + } + + public Object getAuthorizationConstraint() { + return authorizationConstraint; + } + + public void setAuthorizationConstraint(Object authorizationConstraint) { + this.authorizationConstraint = authorizationConstraint; + } + + public AuthorizationConstraintWrapper getAuthorizationConstraintWrapper() { + return new AuthorizationConstraintWrapper(authorizationConstraint); + } + + public void setAuthorizationConstraintWrapper( + AuthorizationConstraintWrapper authorizationConstraintWrapper) { + this.authorizationConstraint = authorizationConstraintWrapper + .getModelElement(); + } + + public Object getRole() { + return role; + } + + public void setRole(Object role) { + this.role = role; + } + + public RoleWrapper getRoleWrapper() { + return new RoleWrapper(role); + } + + public void setRoleWrapper(RoleWrapper roleWrapper) { + this.role = roleWrapper.getModelElement(); + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/util/SelectMetamodelActionListener.java b/src/ch/ethz/infsec/secureumlgui/util/SelectMetamodelActionListener.java new file mode 100644 index 0000000..b6edda0 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/util/SelectMetamodelActionListener.java @@ -0,0 +1,53 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.util; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; + +import ch.ethz.infsec.secureumlgui.DialectMetamodelSelectedListener; +import ch.ethz.infsec.secureumlgui.modelmapping.GenericDialectModelMapper; + + +/** + * + */ +public class SelectMetamodelActionListener implements ActionListener +{ + /** + * + */ + public SelectMetamodelActionListener( + File xmiFile, + DialectMetamodelSelectedListener selectionListener) + { + this.xmiFile = xmiFile; + this.selectionListener = selectionListener; + } + + File xmiFile; + DialectMetamodelSelectedListener selectionListener; + + /** + * @return the xmiFile + */ + public File getXmiFile() + { + return xmiFile; + } + + /* (non-Javadoc) + * @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) + */ + public void actionPerformed(ActionEvent arg0) + { + selectionListener.dialectMetamodelSelected(xmiFile); + + + + + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/util/Various.java b/src/ch/ethz/infsec/secureumlgui/util/Various.java new file mode 100644 index 0000000..a20d9fd --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/util/Various.java @@ -0,0 +1,36 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.util; + +import java.lang.reflect.Method; + +/** + * + */ +public class Various +{ + + public static void printInterfaces(Class cl) + { + if(cl != null) + { + + Class[] interfaces = cl.getInterfaces(); + System.out.println(" - Interfaces of class '" + cl.getName() + " :"); + for (int i = 0; i < interfaces.length; i++) + { + System.out.println("i: "+ interfaces[i].getName()); + + for (int j = 0; j < interfaces[i].getMethods().length; j++) + { + Method method = interfaces[i].getMethods()[j]; + + System.out.println(" m: " + method.toString()); + } +// + } + } + + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/util/package.html b/src/ch/ethz/infsec/secureumlgui/util/package.html new file mode 100644 index 0000000..4736807 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/util/package.html @@ -0,0 +1,8 @@ + + + + + +Miscellaneous utility classes. + + diff --git a/src/ch/ethz/infsec/secureumlgui/wrapper/ActionWrapper.java b/src/ch/ethz/infsec/secureumlgui/wrapper/ActionWrapper.java new file mode 100644 index 0000000..57380c5 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/wrapper/ActionWrapper.java @@ -0,0 +1,195 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.wrapper; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.Set; + +import ch.ethz.infsec.secureumlgui.Util; +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; + + +/** + * + */ +public class ActionWrapper extends NamedModelElementWrapper +{ + /** + * + */ + public ActionWrapper(Object secureModelElementWrapper) + { + super(secureModelElementWrapper); + } + + static MultiContextLogger logger = MultiContextLogger.getDefault(); + + /* creates either + * an AtomicActionWrapper + * (if the argument is a direct descendant + * of Type with name 'AtomicAction') + * + * or a CompositeActionWrapper Instance + * (if the argument is a direct descendant + * of Type with name 'CompositeAction') + * + * and 'null' otherwise + */ + + public static ActionWrapper createActionWrapper(Object secureModelElement) + { + if(secureModelElement == null) + { + logger.error("createActionWrapper(null) -> cannot create"); + return null; + } +// String actionSuperclassName = +// secureModelElement.getClass().getSuperclass(). +// getSimpleName(); + + else { + logger.info("create action wrapper for "+secureModelElement); + + return new ActionWrapper(secureModelElement); + } +// if(Util.isInstanceof(secureModelElement.getClass(), "AtomicAction")) +// //actionSuperclassName.equals("AtomicAction")) +// { +// return new AtomicActionWrapper(secureModelElement); +// } +// else if(Util.isInstanceof(secureModelElement.getClass(), "CompositeAction")) +// //actionSuperclassName.equals("CompositeAction")) +// { +// return new CompositeActionWrapper(secureModelElement); +// } +// else +// { +// logger.error("cannot create ActionWrapper, action has type: " + secureModelElement.getClass() +// + ", with invalid (non Action) supertype: " + secureModelElement.getClass().getSuperclass()); +// } +// return null; + } + + public Object getResource() + { + Object resource = + Util.getProperty(getModelElement(), "resource"); + return resource; + } + public void setResourceWrapper(Object resource) + { + Util.setProperty(getModelElement(), "resource", resource); + } + + public ResourceWrapper getResourceWrapper() + { + Object resource = null; + try { + resource = + Util.getProperty(getModelElement(), "resource"); + } catch (Exception e) { + logger.error("could not get Resource for "+getModelElement()); + } + + return new ResourceWrapper(resource); + } + + public Collection getSuperActions() + { + return (Collection) + Util.getProperty(getModelElement(), "superactions"); + } + + public Set getSuperActionWrappers() + { + Collection actions = getSuperActions(); + + Set actionWrappers = new LinkedHashSet(); + + for (Iterator iter = actions.iterator(); iter.hasNext();) + { + Object a = (Object) iter.next(); + + actionWrappers.add(new ActionWrapper(a)); + } + + return actionWrappers; + } + + public Collection getSubActions() + { + return (Collection) + Util.tryGetProperty(getModelElement(), "subactions"); + + // using tryGet.. here, + // because 'subactions' does not exist on AtomicActions + } + + public Set getSubActionWrappers() + { + Collection actions = getSubActions(); + + Set actionWrappers = new LinkedHashSet(); + + if(actions == null) + return actionWrappers; + + + for (Iterator iter = actions.iterator(); iter.hasNext();) + { + Object a = (Object) iter.next(); + + actionWrappers.add(new ActionWrapper(a)); + } + + return actionWrappers; + } + + public boolean hasSubActions() { + Collection subActions = getSubActions(); + if (subActions != null && subActions.size() > 0 ) { + return true; + } else { + return false; + } + } + + public void setResourceWrapper(ResourceWrapper resourceWrapper) + { + Util.setProperty(getModelElement(), "resource", resourceWrapper.getModelElement()); + } + + public Collection getPermission() + { + Object permission = Util.getProperty(getModelElement(), "permission"); + + return (Collection) permission; + } + + public void addPermission(Object permission) + { + Collection permissions = getPermission(); + + permissions.add(permission); + } + + public Collection getPermissionWrappers() + { + Collection permissions = getPermission(); + + Collection permissionWrappers = new LinkedList(); + + for (Iterator iter = permissions.iterator(); iter.hasNext();) + { + Object p = (Object) iter.next(); + + permissionWrappers.add(new PermissionWrapper(p)); + } + + return permissionWrappers; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/wrapper/AtomicActionWrapper.java b/src/ch/ethz/infsec/secureumlgui/wrapper/AtomicActionWrapper.java new file mode 100644 index 0000000..467c25e --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/wrapper/AtomicActionWrapper.java @@ -0,0 +1,20 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.wrapper; + + +/** + * + */ +public class AtomicActionWrapper extends ActionWrapper +{ + /** + * + */ + public AtomicActionWrapper(Object secureModelElementWrapper) + { + super(secureModelElementWrapper); + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/wrapper/AttributeWrapper.java b/src/ch/ethz/infsec/secureumlgui/wrapper/AttributeWrapper.java new file mode 100644 index 0000000..ef498a3 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/wrapper/AttributeWrapper.java @@ -0,0 +1,32 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.wrapper; + +import ch.ethz.infsec.secureumlgui.Util; + +/** + * + */ +public class AttributeWrapper extends NamedModelElementWrapper +{ + /** + * + */ + public AttributeWrapper(Object modelElement) + { + super(modelElement); + } + + public Object getType() + { + return Util.getProperty(getModelElement(), "type"); + } + + public String getName() + { + return + Util.getProperty(getModelElement(), "name").toString(); + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/wrapper/AuthorizationConstraintWrapper.java b/src/ch/ethz/infsec/secureumlgui/wrapper/AuthorizationConstraintWrapper.java new file mode 100644 index 0000000..ca54039 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/wrapper/AuthorizationConstraintWrapper.java @@ -0,0 +1,34 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.wrapper; + +import ch.ethz.infsec.secureumlgui.Util; + + +/** + * + */ +public class AuthorizationConstraintWrapper extends NamedModelElementWrapper +{ + /** + * + */ + public AuthorizationConstraintWrapper(Object secureModelElementWrapper) + { + super(secureModelElementWrapper); + } + + public String getConstraint() + { + Object constraint = Util.getProperty(getModelElement(), "constraint"); + + return constraint.toString(); + } + + public void setConstraint(String constraintString) + { + Util.setProperty(getModelElement(), "constraint", constraintString); + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/wrapper/CompositeActionWrapper.java b/src/ch/ethz/infsec/secureumlgui/wrapper/CompositeActionWrapper.java new file mode 100644 index 0000000..98fed84 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/wrapper/CompositeActionWrapper.java @@ -0,0 +1,22 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.wrapper; + + +/** + * + */ +public class CompositeActionWrapper extends ActionWrapper +{ + /** + * + */ + public CompositeActionWrapper(Object secureModelElementWrapper) + { + super(secureModelElementWrapper); + } + + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/wrapper/ExceptionPermissionWrapper.java b/src/ch/ethz/infsec/secureumlgui/wrapper/ExceptionPermissionWrapper.java new file mode 100644 index 0000000..90c96bc --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/wrapper/ExceptionPermissionWrapper.java @@ -0,0 +1,25 @@ +package ch.ethz.infsec.secureumlgui.wrapper; + +import ch.ethz.infsec.secureumlgui.Util; + +public class ExceptionPermissionWrapper extends PermissionWrapper { + + public ExceptionPermissionWrapper(Object secureModelElementWrapper) { + super(secureModelElementWrapper); + // TODO Auto-generated constructor stub + } + + public Object getExcpLevel() + { + Object roleObject = Util.getProperty(modelElement, "excpLevel"); + + return roleObject; + } + + public void setRole(Object excpLevel) + { + Util.setProperty(getModelElement(), "excpLevel", excpLevel); + } + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/wrapper/ModelElementWrapper.java b/src/ch/ethz/infsec/secureumlgui/wrapper/ModelElementWrapper.java new file mode 100644 index 0000000..e77cdd4 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/wrapper/ModelElementWrapper.java @@ -0,0 +1,72 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.wrapper; + + +import ch.ethz.infsec.secureumlgui.logging.MultiContextLogger; + +/** + * + */ +public class ModelElementWrapper +{ + /** + * + */ + public ModelElementWrapper(Object modelElement) + { + this.modelElement = modelElement; + } + + MultiContextLogger logger = MultiContextLogger.getDefault(); + + Object modelElement; + + /** + * @return the secureModelElement + */ + public Object getModelElement() + { + return modelElement; + } + + /* (non-Javadoc) + * @see java.lang.Object#equals(java.lang.Object) + */ + @Override + public boolean equals(Object obj) + { + if (obj != null && obj.getClass() == this.getClass()) + { + ModelElementWrapper other = (ModelElementWrapper) obj; + + if(getModelElement() == null) + { + if(other.getModelElement() == null) + return true; + else + return false; + } + else + { + if(other.getModelElement() == null) + return false; + else + { + boolean result = getModelElement()==other.getModelElement(); + + logger.info(this + " ?= " + + other + ": "+ result); + + return result; + } + } + } + else + return super.equals(obj); + } + + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/wrapper/MofClassWrapper.java b/src/ch/ethz/infsec/secureumlgui/wrapper/MofClassWrapper.java new file mode 100644 index 0000000..27fa368 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/wrapper/MofClassWrapper.java @@ -0,0 +1,51 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.wrapper; + +import java.util.Collection; + +import ch.ethz.infsec.secureumlgui.Util; + +/** + * + */ +public class MofClassWrapper extends NamedModelElementWrapper +{ + /** + * + */ + public MofClassWrapper(Object modelElement) + { + super(modelElement); + } + + public boolean isAbstract() + { + Boolean isAbstract = (Boolean) + Util.getProperty(getModelElement(), "abstract"); + return isAbstract.booleanValue(); + } + + public Collection getContents() + { + return (Collection) + Util.getProperty(getModelElement(), "contents"); + } + + public Collection getSupertypes() + { + return (Collection) + Util.getProperty(getModelElement(), "supertypes"); + } + +// public Collection allAttributes() +// { +// Collection allAttributes = (Collection) +// Util.invokeParameterlessMethod( +// getModelElement(), "refAllAttributes"); +// +// return allAttributes; +// } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/wrapper/MofPackageWrapper.java b/src/ch/ethz/infsec/secureumlgui/wrapper/MofPackageWrapper.java new file mode 100644 index 0000000..43ac2ae --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/wrapper/MofPackageWrapper.java @@ -0,0 +1,28 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.wrapper; + +import java.util.Collection; + +import ch.ethz.infsec.secureumlgui.Util; + +/** + * + */ +public class MofPackageWrapper extends NamedModelElementWrapper +{ + /** + * + */ + public MofPackageWrapper(Object modelElement) + { + super(modelElement); + } + + public Collection getContents() + { + return (Collection) + Util.getProperty(getModelElement(), "contents"); + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/wrapper/NamedModelElementWrapper.java b/src/ch/ethz/infsec/secureumlgui/wrapper/NamedModelElementWrapper.java new file mode 100644 index 0000000..e2ba2cd --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/wrapper/NamedModelElementWrapper.java @@ -0,0 +1,61 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.wrapper; + + +import ch.ethz.infsec.secureumlgui.Util; + +/** + * + */ +public class NamedModelElementWrapper extends ModelElementWrapper +{ + /** + * + */ + public NamedModelElementWrapper(Object modelElement) + { + super(modelElement); + } + + + public String getName() + { + if (getModelElement() == null) logger.error(" null in getName()"); + try + { + return (String) Util.getProperty(getModelElement(), "name"); + } + catch (Exception e) + { + logger.error(" cannot read Property 'name' on Object " + + getModelElement().getClass().getSimpleName()); + return null; + } + } + + public void setName(String name) + { + try + { + Util.setProperty(modelElement, "name", name); + } + catch (Exception e) + { + logger.error(" cannot write Property 'name' on Object " + + modelElement.getClass().getSimpleName()); + } + } + + + /* (non-Javadoc) + * @see java.lang.Object#toString() + */ + @Override + public String toString() + { + return getName(); + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/wrapper/PermissionWrapper.java b/src/ch/ethz/infsec/secureumlgui/wrapper/PermissionWrapper.java new file mode 100644 index 0000000..180b627 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/wrapper/PermissionWrapper.java @@ -0,0 +1,241 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.wrapper; + +import java.util.Collection; +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedHashSet; +import java.util.LinkedList; +import java.util.Set; + +import org.apache.log4j.Logger; + +import ch.ethz.infsec.secureumlgui.Util; +import ch.ethz.infsec.secureumlgui.main.SecureUmlConstants; +import ch.ethz.infsec.secureumlgui.modelmapping.GenericDialectModelMapper; + +/** + * + */ +public class PermissionWrapper extends NamedModelElementWrapper +{ + + private static Logger aLog = Logger.getLogger(PermissionWrapper.class); + /** + * + */ + public PermissionWrapper(Object secureModelElementWrapper) + { + super(secureModelElementWrapper); + } + + public Object getAction() + { + Object me = getModelElement(); + if (me == null) logger.error("PermissionWrapper.getAction: me = null"); + + Object action = Util.getProperty(me, "Action"); + + return /*(Collection)*/ action; + } + + public void setAction(Object action) + { + logger.info("setAction("+action +")"); + Util.setProperty(getModelElement(), "Action", action); + } + + public /*Collection<*/ActionWrapper getActionWrapper() + { + Object action = getAction(); + if(action == null) { + logger.error("PermissionWrapper.getActionWrapper: action = null, this="+this); + //return null; + } + logger.info("getAction() = "+action +" in getActionWrapper()"); + return ActionWrapper.createActionWrapper(action); + +// Collection actionWrappers = null; +// +// if(result instanceof Collection) +// { +// Collection actions = (Collection) result; +// +// actionWrappers = +// new LinkedList(); +// +// for (Iterator iter = actions.iterator(); iter.hasNext();) +// { +// Object action = (Object) iter.next(); +// +// actionWrappers.add(ActionWrapper.createActionWrapper(action)); +// } +// +// } +// return actionWrappers; + } + + public Object getRole() + { + Object roleObject = Util.getProperty(modelElement, "role"); + + return roleObject; + } + + public void setRole(Object role) + { + Util.setProperty(getModelElement(), "role", role); + } + + public RoleWrapper getRoleWrapper() + { + Object roleObject = getRole(); + + //if (roleObject instanceof Object) + if(roleObject != null) + { + Object role = (Object) roleObject; + + return new RoleWrapper(role); + + } + return null; + } + + public void setRoleWrapper(RoleWrapper roleWrapper) + { + Object roleObject = null; + if(roleWrapper != null) + roleObject = roleWrapper.getModelElement(); + + setRole(roleObject); + } + + public Object getPolicies() { + Object policyObject = Util.getProperty(getModelElement(), "policy"); + +// if ( policyObject == null ) { +// policyObject = GenericDialectModelMapper.getInstance().getDefaultPolicy(); +// Util.setProperty(modelElement, "policy", policyObject); +// } + return policyObject; + } + + public void setPolicy(Object policy) { +// if (aLog.isDebugEnabled() && Util.getProperty(Util.getProperty(modelElement, "policy"), "name").equals(SecureUmlConstants.DEFAULT_POLICY_NAME)) { +// aLog.warn("A default policy is set to a permission!"); +// } + Util.setProperty(getModelElement(), "policy", policy); + } + + + +// public Set getSuperActionWrappers() +// { +// Collection actions = getSuperActions(); +// +// Set actionWrappers = new LinkedHashSet(); +// +// for (Iterator iter = actions.iterator(); iter.hasNext();) +// { +// Object a = (Object) iter.next(); +// +// actionWrappers.add(new ActionWrapper(a)); +// } +// +// return actionWrappers; +// } + + + + public Set getPolicyWrappers() { + + Collection policies = (Collection) getPolicies(); + + if ( policies == null ) { + return null; + } else { + Set policyWrappers = new HashSet(); + + for ( Object obj : policies ) { + policyWrappers.add(new PolicyWrapper(obj)); + } + return policyWrappers; + } + + + + + + + + + + + + + +// if ( policy instanceof org.netbeans.mdr.handlers.AEIndexSetWrapper) { +// //if ( policy == null ) { +// aLog.warn("policy is AEIndexSetWrapper: " + policy); +// return null; +// } else { +// return new PolicyWrapper(getPolicy()); +// } + } + + public void setPolicyWrapper(PolicyWrapper policyWrapper) { + if( policyWrapper != null ) { + setPolicy(policyWrapper.getModelElement()); + } else { + setPolicy(GenericDialectModelMapper.getInstance().getDefaultPolicy()); + } + } + + + public Object getAuthorizationConstraint() + { + Object authorizationConstraint = Util.getProperty(getModelElement(), "authorizationConstraint"); + + return authorizationConstraint; + } + + public void setAuthorizationConstraint(Object authorizationConstraint) + { + Util.setProperty(getModelElement(), "authorizationConstraint", authorizationConstraint); + } + + + public AuthorizationConstraintWrapper getAuthorizationConstraintWrapper() + { + Object authorizationConstraint = getAuthorizationConstraint(); + + return new AuthorizationConstraintWrapper(authorizationConstraint); + } + + public void setAuthorizationConstraintWrapper( + AuthorizationConstraintWrapper authorizationConstraintWrapper) + { + setAuthorizationConstraint( + authorizationConstraintWrapper.getModelElement()); + + } + + public boolean isConstrained() { + Object oConstr = getAuthorizationConstraint(); + if (oConstr == null ) { + return false; + } + AuthorizationConstraintWrapper wConstr = new AuthorizationConstraintWrapper(oConstr); + if ( wConstr.getConstraint() != null && wConstr.getConstraint().length() == 0 ) { + return false; + } else { + return true; + } + } + + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/wrapper/PolicyWrapper.java b/src/ch/ethz/infsec/secureumlgui/wrapper/PolicyWrapper.java new file mode 100644 index 0000000..29586ae --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/wrapper/PolicyWrapper.java @@ -0,0 +1,76 @@ +package ch.ethz.infsec.secureumlgui.wrapper; + +import java.util.Collection; +import java.util.LinkedList; + +import org.apache.log4j.Logger; + +import ch.ethz.infsec.secureumlgui.Util; + +public class PolicyWrapper extends NamedModelElementWrapper { + + private static Logger aLog = Logger.getLogger(PolicyWrapper.class); + + public PolicyWrapper(Object modelElement) { + super(modelElement); + } + + //public java.util.Collection/**/ getSuperroles(); + public Collection getRefinedBy() { + Collection policies = (Collection) Util.getProperty( + getModelElement(), "refinedBy"); + + return policies; + } + + public Collection getRefines() { + Collection policies = (Collection) Util.getProperty( + getModelElement(), "refines"); + + return policies; + } + + public Collection getRefinedByWrappers() + { + Collection policies = createWrapper(getRefinedBy()); + + if (aLog.isDebugEnabled()) { + + StringBuffer buff = new StringBuffer("policy " + this.getName() + " refined by "); + + for (PolicyWrapper policy : policies ) { + buff.append(policy.getName()); + buff.append(":"); + } + + aLog.debug(buff.toString()); + + } + + return policies; + + } + + public Collection getRefinesWrappers() { + return createWrapper(getRefines()); + } + + + + + private Collection createWrapper(Collection policies) { + + Collection result = new LinkedList(); + + if(policies != null) + { + for ( Object policy : policies ) { + result.add(new PolicyWrapper(policy)); + } + return result; + } + else + return null; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/wrapper/RefPackageWrapper.java b/src/ch/ethz/infsec/secureumlgui/wrapper/RefPackageWrapper.java new file mode 100644 index 0000000..79b2a4d --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/wrapper/RefPackageWrapper.java @@ -0,0 +1,102 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.wrapper; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; + +import ch.ethz.infsec.secureumlgui.Util; +import ch.ethz.infsec.secureumlgui.securemodel.dialects.metamodel.MetaModelConst; + +/** + * + */ +public class RefPackageWrapper extends ModelElementWrapper +{ + /** + * + */ + public RefPackageWrapper(Object modelElement) + { + super(modelElement); + } + + public String getName() + { + String name = getModelElement().getClass().getSimpleName(); + + name = name.split(MetaModelConst.MDR_IMPL_SUFFIX)[0]; + + return name; + } + +// public Collection getContents() +// { +// Object contents = +// Util.getProperty(getModelElement(), "contents"); +// +// return (Collection) contents; +// } +// +// public Object getContainer() +// { +// Object container = +// Util.getProperty(getModelElement(), "container"); +// +// return container; +// } + + public Collection allClasses() + { + Collection allClasses = (Collection) + Util.invokeParameterlessMethod( + modelElement, + "refAllClasses"); + + return allClasses; + } + + public Collection allAssociations() + { + Collection allAssociations = (Collection) + Util.invokeParameterlessMethod( + modelElement, + "refAllAssociations"); + + return allAssociations; + } + + public Collection allPackages() + { + Collection allPackages = (Collection)Util.invokeParameterlessMethod( + modelElement, + "refAllPackages"); + + return allPackages; + } + + public Collection getContents() + { + + Collection contents = new LinkedList(); + + Util.addAllSave(contents, allClasses()); + Util.addAllSave(contents, allAssociations()); + Util.addAllSave(contents, allPackages()); + + for (Iterator iter = allPackages().iterator(); iter.hasNext();) + { + Object pkg = (Object) iter.next(); + + RefPackageWrapper pkgWrapper = new RefPackageWrapper(pkg); + Collection pkgContents = pkgWrapper.getContents(); + + Util.addAllSave(contents, pkgContents); + } + + return contents; + } + +} diff --git a/src/ch/ethz/infsec/secureumlgui/wrapper/ResourceWrapper.java b/src/ch/ethz/infsec/secureumlgui/wrapper/ResourceWrapper.java new file mode 100644 index 0000000..69c3564 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/wrapper/ResourceWrapper.java @@ -0,0 +1,103 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.wrapper; + +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; + +import org.omg.uml.foundation.core.ModelElement; + +import ch.ethz.infsec.secureumlgui.Util; +import ch.ethz.infsec.secureumlgui.modelmapping.GenericDialectHelper; +import ch.ethz.infsec.secureumlgui.transformation.ModelMap; + + + +/** + * + */ +public class ResourceWrapper extends NamedModelElementWrapper +{ + /** + * + */ + public ResourceWrapper(Object secureModelElement) + { + super(secureModelElement); + } + + public Collection getAction() + { + Object action = + Util.getProperty(getModelElement(), "action"); + return (Collection) action; + } + + public Collection getActionWrapper() + { + Collection actions = getAction(); + + Collection result = + new LinkedList(); + + if(actions != null) + { + for (Iterator iter = actions.iterator(); iter.hasNext();) + { + Object action = (Object) iter.next(); + + result.add(ActionWrapper.createActionWrapper(action)); + } + } + + return result; + } + + public String getResourcePath() + { + String resourcePath = ""; + + Object suResource = getModelElement(); + if(suResource != null) + { + ModelElement umlResource = (ModelElement) + ModelMap.getDefault().getUmlElement(suResource); + ModelElement anchor = + GenericDialectHelper.getInstance(). + findAnchor(umlResource); + + resourcePath = + GenericDialectHelper.getInstance().getResourcePath(); + } + + return resourcePath; + } + + + @Override + public String toString() + { + + if(getModelElement() == null)// || getName() == null) + return ""; + return getModelElement().toString();//getName(); +// else +// { +// GenericDialectHelper helper = GenericDialectHelper.getInstance(); +// Object suElement = getModelElement(); +// +// ModelElement umlElement = (ModelElement) +// ModelMap.getDefault().getUmlElement(suElement); +// helper.findAnchor(umlElement); +// +// if(umlElement != null) +// return helper.getResourcePath(); +// else +// return this.getName(); +// } + } + + +} diff --git a/src/ch/ethz/infsec/secureumlgui/wrapper/RoleWrapper.java b/src/ch/ethz/infsec/secureumlgui/wrapper/RoleWrapper.java new file mode 100644 index 0000000..0a13ca3 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/wrapper/RoleWrapper.java @@ -0,0 +1,99 @@ +/** + * + */ +package ch.ethz.infsec.secureumlgui.wrapper; + +import java.security.Permission; +import java.util.Collection; +import java.util.Iterator; +import java.util.LinkedList; + +import ch.ethz.infsec.secureumlgui.Util; + + +/** + * + */ +public class RoleWrapper extends NamedModelElementWrapper +{ + /** + * + */ + public RoleWrapper(Object secureModelElement) + { + super(secureModelElement); + } + + public Collection getSuperrolesWrappers() + { + return createWrapper(getSuperroles()); + } + + public Collection getSubrolesWrappers() { + return createWrapper(getSubroles()); + } + + private Collection createWrapper(Collection roles) { + + Collection result = new LinkedList(); + + if(roles != null) + { + for (Iterator iter = roles.iterator(); iter.hasNext();) + { + Object role = (Object) iter.next(); + + result.add(new RoleWrapper(role)); + + } + return result; + } + else + return null; + } + + public Collection getSuperroles() + { + Collection roles = (Collection) Util.getProperty( + getModelElement(), "superroles"); + + return roles; + } + + public Collection getSubroles() { + return (Collection) Util.getProperty(getModelElement(), "subroles"); + } + + + public Collection getPermission() + { + Collection permission = (Collection) Util.getProperty( + getModelElement(), "permission"); + + return permission; + } + + + public void addPermission(Object permission) + { + Collection permissions = (Collection) Util.getProperty( + getModelElement(), "permission"); + + permissions.add(permission); + } + + public Collection getPermissionWrapper() + { + Collection permissions = getPermission(); + + Collection permissionWrapper = new LinkedList(); + + for (Iterator iter = permissions.iterator(); iter.hasNext();) + { + Object permission = (Object) iter.next(); + + permissionWrapper.add(new PermissionWrapper(permission)); + } + return permissionWrapper; + } +} diff --git a/src/ch/ethz/infsec/secureumlgui/wrapper/package.html b/src/ch/ethz/infsec/secureumlgui/wrapper/package.html new file mode 100644 index 0000000..852c889 --- /dev/null +++ b/src/ch/ethz/infsec/secureumlgui/wrapper/package.html @@ -0,0 +1,8 @@ + + + + + +Wrappers around SecureUML elements, providing a more convenient interface. + + diff --git a/src/manifest.mf b/src/manifest.mf new file mode 100644 index 0000000..c032244 --- /dev/null +++ b/src/manifest.mf @@ -0,0 +1,12 @@ +Manifest-Version: 2.0 +Class-Path: argouml.jar argo_secureuml_resources.jar +Created-By: 1.2 (Sun Microsystems Inc.) + +Name: ch/ethz/infsec/secureumlgui/SecureUmlModule.class +Extension-name: module.ui.secureuml.sumodule +Specification-Title: ArgoUML SecureUml Module +Specification-Version: 0.4.2 +Specification-Vendor: ETH Zuerich +Implementation-Vendor: ETH Zuerich +Implementation-Version: 0.4.2 +Implementation-Title: ArgoUML SecureUml Module diff --git a/src/overview.html b/src/overview.html new file mode 100644 index 0000000..fceeb31 --- /dev/null +++ b/src/overview.html @@ -0,0 +1,16 @@ + + +SecureUML GUI + + + +An ArgoUML plugin for editing SecureUML policies. + +Allows the editing of SecureUML permissions using simple GUI +controls, instead of manually using the SecureUML profile. + +Also contains a plugin to generate SecureUML policy templates from +use-case diagrams. + + + diff --git a/test/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/ActorMapperTest.java b/test/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/ActorMapperTest.java new file mode 100644 index 0000000..2bca60a --- /dev/null +++ b/test/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/ActorMapperTest.java @@ -0,0 +1,220 @@ +package ch.ethz.infsec.secureumlgui.usecasemapper.mapping; + +import org.junit.Test; +import org.junit.Before; +import static org.junit.Assert.*; + +import org.argouml.model.Model; +import org.argouml.model.CoreHelper; + +/** + * JUnit test class for the mapping strategy + * {@link ActorMapper ActorMapper}. + * + * @version 1.0 + * @see ActorMapper + */ +public class ActorMapperTest { + + /** + * Reference to the ArgoUML CoreHelper for + * enhanced readability. + */ + private final CoreHelper helper = Model.getCoreHelper(); + + /** + * The actor mapper used for the tests. + */ + private final ActorMapper actorMapper = new ActorMapper(); + + /** + * The model being setup and which is used to test the + * {@link ActorMapper ActorMapper}. + */ + private Object model; + + /** + * The {@link MapperHelper MapperHelper} singleton as + * a reference for enhanced readability. + */ + private final MapperHelper mapperHelper = MapperHelper.getInstance(); + + /** + * The {@link MapperTestHelper MapperTestHelper} singleton + * as a reference for enhanced readability. + */ + private final MapperTestHelper mapperTestHelper = MapperTestHelper. + getInstance(); + + /** + * Initalizes the model according to the class description. + * Sets the model as current model in the actor mapper. + */ + @Before public final void setup() { + model = Model.getModelManagementFactory().createModel(); + mapperTestHelper.initTestModelActors(model); + actorMapper.setModel(model); + } + + /** + * Checks if the MapperException is correctly thrown if there + * is no model set. + */ + @Test public final void noMapWithoutModel() { + actorMapper.setModel(null); + boolean exceptionOccured = false; + try { + actorMapper.map(); + } catch (MapperException exception) { + exceptionOccured = true; + } + assertTrue(exceptionOccured); + } + + /** + * Checks if only the non abstract actors are mapped to + * SecureUML roles. + */ + @Test public final void mapOnlyNonAbstractActors() { + try { + actorMapper.map(); + } catch (MapperException exception) { + fail(); + } + assertNotNull("User not mapped", mapperHelper. + getRoleClassNS(mapperTestHelper.USER_NAME, + mapperTestHelper.getTestPackage())); + assertNotNull("SuperUser not mapped", mapperHelper. + getRoleClassNS(MapperTestHelper.SUPER_USER_NAME, + mapperTestHelper.getTestPackage())); + assertNotNull("OtherUser not mapped", mapperHelper. + getRoleClassNS(MapperTestHelper.OTHER_USER_NAME, + mapperTestHelper.getTestPackage())); + assertNotNull("Test not mapped", mapperHelper. + getRoleClassNS(MapperTestHelper.TEST_NAME, + mapperTestHelper.getTestPackage())); + assertNotNull("Guest not mapped", mapperHelper. + getRoleClassNS(MapperTestHelper.GUEST_NAME, + mapperTestHelper.getTestPackage())); + assertNull("EntryOwner mapped", mapperHelper. + getRoleClassNS(MapperTestHelper.ENTRY_OWNER_NAME, + mapperTestHelper.getTestPackage())); + assertNull("OtherOwner mapped", mapperHelper. + getRoleClassNS(MapperTestHelper.OTHER_OWNER_NAME, + mapperTestHelper.getTestPackage())); + assertNull("TestOwner mapped", mapperHelper. + getRoleClassNS(MapperTestHelper.TEST_OWNER_NAME, + mapperTestHelper.getTestPackage())); + } + + /** + * Checks if the generalize relations are only to the next + * concrete actor and not to any children thereof. + */ + @Test public final void onlyInheritNextConcrete() { + try { + actorMapper.map(); + } catch (MapperException exception) { + fail(); + } + final Object testRole = mapperHelper. + getRoleClassNS(MapperTestHelper.TEST_NAME, + mapperTestHelper.getTestPackage()); + final Object guestRole = mapperHelper. + getRoleClassNS(MapperTestHelper.GUEST_NAME, + mapperTestHelper.getTestPackage()); + final Object userRole = mapperHelper. + getRoleClassNS(MapperTestHelper.USER_NAME, + mapperTestHelper.getTestPackage()); + final Object otherUserRole = mapperHelper. + getRoleClassNS(MapperTestHelper.OTHER_USER_NAME, + mapperTestHelper.getTestPackage()); + final Object superUserRole = mapperHelper. + getRoleClassNS(MapperTestHelper.SUPER_USER_NAME, + mapperTestHelper.getTestPackage()); + + assertNotNull("Generalization: Test <-- OtherUser should be present", + helper.getGeneralization(otherUserRole, testRole)); + assertNotNull("Generalization: Guest <-- User should be present", + helper.getGeneralization(userRole, guestRole)); + assertNotNull("Generalization: " + + "OtherUser <-- SuperUser should be present", + helper.getGeneralization(superUserRole, otherUserRole)); + assertNotNull("Generalization: Test <-- SuperUser should be present", + helper.getGeneralization(superUserRole, testRole)); + assertNull("No Generalization: Guest <-- SuperUser as no direct heir", + helper.getGeneralization(superUserRole, guestRole)); + } + + /** + * Checks if the mapper is able to determine the next + * concrete heir, even if there are multiple abstract + * actors inbetween in the hierarchy. + */ + @Test public final void findConcreteChild() { + try { + actorMapper.map(); + } catch (MapperException exception) { + fail(); + } + final Object testRole = mapperHelper. + getRoleClassNS(MapperTestHelper.TEST_NAME, + mapperTestHelper.getTestPackage()); + final Object superUserRole = mapperHelper. + getRoleClassNS(MapperTestHelper.SUPER_USER_NAME, + mapperTestHelper.getTestPackage()); + assertNotNull("Generalization Test <-- SuperUser not present", + helper.getGeneralization(superUserRole, testRole)); + } + + /** + * Ensures multiple mapping runs do not change the model + * anymore after the first run. + */ + @Test public final void multipleMapsDontChange() { + try { + actorMapper.map(); + } catch (MapperException exception) { + fail(); + } + final int classCount = helper. + getAllClasses(mapperTestHelper.getTestPackage()).size(); + + try { + actorMapper.map(); + } catch (MapperException exception) { + fail(); + } + assertEquals("old class count != class count after 2nd map", + classCount, helper. + getAllClasses(mapperTestHelper.getTestPackage()).size()); + } + + /** + * Checks if only the non existing roles are mapped and the + * existing ones are not changed. + */ + @Test public final void onlyMapNonExisting() { + final Object testRole = Model.getCoreFactory(). + buildClass(MapperTestHelper.TEST_NAME, + mapperTestHelper.getTestPackage()); + final Object superUserRole = Model.getCoreFactory(). + buildClass(mapperTestHelper.SUPER_USER_NAME, mapperTestHelper. + getTestPackage()); + + final Object stereotype = MapperHelper.getInstance(). + getSecureUMLStereotype(model, "secuml.role"); + + helper.addStereotype(testRole, stereotype); + helper.addStereotype(superUserRole, stereotype); + + try { + actorMapper.map(); + } catch (MapperException exception) { + fail(); + } + assertEquals("concrete role count != class count", + MapperTestHelper.CONCRETE_ROLE_SUM, helper. + getAllClasses(mapperTestHelper.getTestPackage()).size()); + } +} diff --git a/test/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/MapperHelperTest.java b/test/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/MapperHelperTest.java new file mode 100644 index 0000000..b8c33ef --- /dev/null +++ b/test/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/MapperHelperTest.java @@ -0,0 +1,86 @@ +package ch.ethz.infsec.secureumlgui.usecasemapper.mapping; + +import org.junit.Test; +import org.junit.Before; +import static org.junit.Assert.*; + +import org.apache.log4j.Logger; + +import org.argouml.model.Model; + +/** + * JUnit test the singleton class + * {@link MapperHelper MapperHelper}. + * + * @version 1.0 + * @see MapperHelper + */ +public class MapperHelperTest { + + + /** + * Logger for the MapperHelperTest class. + */ + private static final Logger LOGGER = Logger. + getLogger(MapperHelperTest.class); + + /** + * Global reference to the target model the MapperHelper + * is tested against. + */ + private final Object model = Model.getModelManagementFactory(). + createModel(); + + /** + * Reference to the MapperHelper instance for + * enhanced readability. + */ + private final MapperHelper mapperHelper = MapperHelper.getInstance(); + + /** + * Setup the SecureUML package for the tests. + */ + @Before public final void setup() { + try { + MapperHelper.getInstance().initSecureUML(model); + } catch (MapperException exception) { + LOGGER.fatal("Could not initialize model"); + } + } + + /** + * Checks of circular inheritance relationships are correctly detected. + */ + @Test public final void detectsCircularInheritance() { + final Object actorA = Model.getUseCasesFactory().createActor(); + final Object actorB = Model.getUseCasesFactory().createActor(); + final Object actorC = Model.getUseCasesFactory().createActor(); + Model.getCoreHelper().addOwnedElement(model, actorA); + Model.getCoreHelper().addOwnedElement(model, actorB); + Model.getCoreHelper().addOwnedElement(model, actorC); + Model.getCoreFactory().buildGeneralization(actorA, actorB); + Model.getCoreFactory().buildGeneralization(actorB, actorC); + Model.getCoreFactory().buildGeneralization(actorC, actorA); + + assertFalse("Model contains circular inheritance", + mapperHelper.hasNoCircularInheritance(model)); + } + + /** + * Checks if the complete SecureUML package is setup + * after the invocation of {@link MapperHelper#initSecureUML(Object)}. + */ + @Test public final void allStereosNActionsSetup() { + for (String stereoName : mapperHelper.getSecumlSteNames()) { + assertNotNull("Stereotype: " + stereoName + "should be present", + mapperHelper.getSecureUMLStereotype(model, + stereoName)); + } + + for (String actionName : mapperHelper.getCompActTypNames()) { + assertNotNull("Dialect action type: " + actionName + + "should be present", mapperHelper. + getSecureUMLActionType(model, actionName)); + } + } +} diff --git a/test/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/MapperTestHelper.java b/test/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/MapperTestHelper.java new file mode 100644 index 0000000..e5f6bd4 --- /dev/null +++ b/test/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/MapperTestHelper.java @@ -0,0 +1,229 @@ +package ch.ethz.infsec.secureumlgui.usecasemapper.mapping; + +import org.apache.log4j.Logger; + +import org.argouml.model.Model; +import org.argouml.model.ModelManagementFactory; +import org.argouml.model.CoreHelper; +import org.argouml.model.CoreFactory; +import org.argouml.model.UseCasesFactory; + +/** + * Provides helper methods for the JUnit tests + * of the mapping strategies. + * Sets up the test model for the tests. + * + * Creates the following structure to test the mappers against: + *

Role hierarchy

+ *
+ *                       Test
+ *                         ^
+ *                         |
+ *                         |
+ * Guest "EntryOwner"  "OtherOwner"
+ *  ^     ^        ^     ^      ^
+ *  |     |        |     |      |
+ *  \-----|        |     |      |
+ *       User    OtherUser    "TestOwner"
+ *         ^      ^             ^
+ *         |      |            /
+ *         |      |------------
+ *        SuperUser
+ * 
+ * The actor names in double quotes are abstract actors. + * + * @version 1.0 + */ +public final class MapperTestHelper { + + /** + * The log4j-logger of this class. + * + */ + private static final Logger LOGGER = Logger. + getLogger(MapperTestHelper.class); + + /** + * The singleton reference. + */ + private static MapperTestHelper singleton = new MapperTestHelper(); + + /** + * The number of non abstract roles in the predefined model. + */ + public static final int CONCRETE_ROLE_SUM = 5; + /** + * The name of the role "Test". + */ + public static final String TEST_NAME = "Test"; + /** + * The name of the role "Guest". + */ + public static final String GUEST_NAME = "Guest"; + /** + * The name of the role "EntryOwner". + */ + public static final String ENTRY_OWNER_NAME = "EntryOwner"; + /** + * The name of the role "OtherOwner". + */ + public static final String OTHER_OWNER_NAME = "OtherOwner"; + /** + * The name of the role "User". + */ + public static final String USER_NAME = "User"; + /** + * The name of the role "OtherUser". + */ + public static final String OTHER_USER_NAME = "OtherUser"; + /** + * The name of the role "TestOwner". + */ + public static final String TEST_OWNER_NAME = "TestOwner"; + /** + * The name of the role "SuerUser". + */ + public static final String SUPER_USER_NAME = "SuperUser"; + + /** + * Reference to the ArgoUML ModelManagementFactory + * for enhanced readability. + */ + private final ModelManagementFactory manager = Model. + getModelManagementFactory(); + + /** + * Reference to the ArgoUML CoreHelper for + * enhanced readability. + */ + private final CoreHelper helper = Model.getCoreHelper(); + + /** + * Reference to the ArgoUML CoreFactory for + * enhanced readability. + */ + private final CoreFactory factory = Model.getCoreFactory(); + /** + * Reference to the ArgoUML UseCasesFactory for + * enhanced readybility. + */ + private final UseCasesFactory ucFactory = Model.getUseCasesFactory(); + + /** + * Test package to be created in the test model. + */ + private Object testPackage; + + /** + * The object for the actor of the first level of the hierarchy. + */ + private Object testActor; + /** + * An object for an actor of the second level of the hierarchy. + */ + private Object guestActor, entryOwnerActor, otherOwnerActor; + /** + * An object for an actor of the third level of the hierarchy. + */ + private Object userActor, otherUserActor, testOwnerActor; + /** + * The object for the actor of the forth level of the hierarchy. + */ + private Object superUserActor; + + /** + * Private constructor due to singleton pattern. + */ + private MapperTestHelper() { }; + + /** + * Gets the MapperTestHelper instance. + * + * @return the MapperTestHelper-instance + */ + public static MapperTestHelper getInstance() { + return singleton; + } + + /** + * Gets the test package object. + * + * @return The object reference to the test package. + */ + public Object getTestPackage() { + return testPackage; + } + + /** + * Creates an actor with a given name, puts it + * into a given namespace and returns it. + * + * @param name The string containing the name of the new actor. + * @param namespace The object being the target namespace. + * @return The object being the actor just added. + */ + public Object addActorNS(final String name, + final Object namespace) { + final Object actor = ucFactory.createActor(); + helper.setName(actor, name); + helper.addOwnedElement(namespace, actor); + + return actor; + } + + /** + * Initializes the whole test model. + * For a description see the class documentation. + * + * @param model The object holding the model to be initialized. + */ + public void initTestModel(final Object model) { + try { + MapperHelper.getInstance().initSecureUML(model); + } catch (MapperException exception) { + LOGGER.fatal("Could not initialize test model"); + } + initTestModelActors(model); + } + + /** + * Initializes all the actors and inheritance relations + * of the test model. + * + * @param model The object holding the model which actors are initialized. + */ + public void initTestModelActors(final Object model) { + try { + MapperHelper.getInstance().initSecureUML(model); + } catch (MapperException exception) { + LOGGER.fatal("Could not initialize test model"); + } + + testPackage = manager.createPackage(); + helper.setName(testPackage, "testpackage"); + helper.addOwnedElement(model, testPackage); + + testActor = addActorNS(TEST_NAME, testPackage); + guestActor = addActorNS(GUEST_NAME, testPackage); + entryOwnerActor = addActorNS(ENTRY_OWNER_NAME, testPackage); + otherOwnerActor = addActorNS(OTHER_OWNER_NAME, testPackage); + userActor = addActorNS(USER_NAME, testPackage); + otherUserActor = addActorNS(OTHER_USER_NAME, testPackage); + testOwnerActor = addActorNS(TEST_OWNER_NAME, testPackage); + superUserActor = addActorNS(SUPER_USER_NAME, testPackage); + + helper.setAbstract(otherOwnerActor, true); + helper.setAbstract(entryOwnerActor, true); + helper.setAbstract(testOwnerActor, true); + + factory.buildGeneralization(otherOwnerActor, testActor); + factory.buildGeneralization(userActor, guestActor); + factory.buildGeneralization(userActor, entryOwnerActor); + factory.buildGeneralization(otherUserActor, entryOwnerActor); + factory.buildGeneralization(otherUserActor, otherOwnerActor); + factory.buildGeneralization(testOwnerActor, otherOwnerActor); + factory.buildGeneralization(superUserActor, userActor); + factory.buildGeneralization(superUserActor, otherUserActor); + factory.buildGeneralization(superUserActor, testOwnerActor); + } +} diff --git a/test/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/PermissionMapperTest.java b/test/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/PermissionMapperTest.java new file mode 100644 index 0000000..cbfe62c --- /dev/null +++ b/test/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/PermissionMapperTest.java @@ -0,0 +1,65 @@ +package ch.ethz.infsec.secureumlgui.usecasemapper.mapping; + +import static org.junit.Assert.*; +import org.junit.Test; +import org.junit.Before; + +import org.apache.log4j.Logger; + +import org.argouml.model.Model; + +/** + * JUnit test class for the mapping strategy + * {@link PermissionMapper PermissionMapper}. + * + * @version 1.0 + * @see PermissionMapper + */ +public class PermissionMapperTest { + + /** + * The log4j logger for this class. + */ + private static final Logger LOGGER = + Logger.getLogger(PermissionMapperTest.class); + + /** + * The {@link MapperTestHelper MapperTestHelper} singleton + * as a reference for enhanced readability. + */ + private final MapperTestHelper mapperTestHelper = MapperTestHelper. + getInstance(); + + /** + * The model being setup and which is used to test the + * {@link PermissionMapper PermissionMapper}. + */ + private Object model; + + /** + * The permission mapper used for the tests. + */ + private final PermissionMapper permissionMapper = new PermissionMapper(); + + /** + * Initalizes the model according to the class description. + */ + @Before public final void setup() { + + model = Model.getModelManagementFactory().createModel(); + mapperTestHelper.initTestModel(model); + permissionMapper.setModel(model); + } + + /** + * Checks if all SecureUML messages have been mapped. + */ + @Test public final void mapsAllMessages() { + try { + permissionMapper.map(); + } catch (MapperException exception) { + LOGGER.error("Permission mapper failed."); + fail("The mapping of the permission mapper failed."); + } + } +} diff --git a/test/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/package.html b/test/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/package.html new file mode 100644 index 0000000..b5e5b0c --- /dev/null +++ b/test/ch/ethz/infsec/secureumlgui/usecasemapper/mapping/package.html @@ -0,0 +1,15 @@ + + + + + + +The mapping package contains the different mapping +strategies. +They are used by the class +{@link ch.ethz.infsec.secureumlgui.usecasemapper.control.Controller Controller} +in the package +{@link ch.ethz.infsec.secureumlgui.usecasemapper.control control}. + + +