Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org')
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/Activator.java99
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/Messages.java42
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/BeanPropertyEditorController.java79
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/CreatePropertyEditorControllerDescriptorOperation.java82
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/CreatePropertyEditorControllerOperation.java116
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFPropertyEditorController.java40
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFTBindingEReferenceController.java121
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFTEReferenceController.java299
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFTLabelProviderStructuralFeatureController.java142
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFTPropertyEditorController.java136
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFTStructuralFeatureController.java287
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/IBoundedValuesController.java62
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/ILabelProviderController.java29
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/IPropertyEditorController.java168
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/IWizardPropertyEditorController.java51
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/NullPropertyEditorController.java153
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/PropertyEditorController.java230
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/PropertyEditorControllerConfiguration.java182
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/PropertyEditorControllerProvider.java122
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/PropertyEditorControllerService.java196
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/BeanPropertyEditorControllerDescriptor.java121
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/BeanPropertyEditorControllerDescriptorFactory.java88
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/ControllerDescriptorState.java144
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/EMFTBindingPropertyEditorControllerDescriptor.java118
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/EMFTBindingPropertyEditorControllerDescriptorFactory.java113
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/EMFTPropertyEditorControllerDescriptor.java338
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/EMFTPropertyEditorControllerDescriptorFactory.java127
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/IBindingLabelProviderDescriptor.java44
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/IPropertyEditorControllerDescriptor.java65
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/IPropertyEditorControllerDescriptorFactory.java33
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/NullPropertyEditorControllerDescriptor.java91
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/NullPropertyEditorControllerDescriptorFactory.java52
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/predefined/CreatePredefinedPropertyControllerProviderOperation.java56
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/predefined/GetAllPredefinedPropertyEditorControllersOperation.java35
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/predefined/PredefinedControllerDescriptor.java115
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/predefined/PredefinedControllerState.java132
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/predefined/PredefinedPropertyControllerProvider.java218
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/dialogs/EMFFeatureBindingLabelProviderDescriptor.java104
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/dialogs/GetDialogDescriptorOperation.java59
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/dialogs/GetDialogDescriptorOperationById.java57
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/dialogs/PropertyDialog.java215
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/dialogs/ReferenceExplorerDialog.java215
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/messages.properties3
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/IPropertyModelHandlerFactory.java29
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/ModelHandlerFactoryDescriptor.java145
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/ModelHandlerService.java101
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/BooleanEMFModelHandler.java158
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/BooleanEMFModelHandlerFactory.java45
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/BooleanStereotypeModelHandler.java134
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/BooleanStereotypeModelHandlerFactory.java44
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFFeatureModelHandler.java1004
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFFeatureModelHandlerState.java143
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFModelHandlerFactory.java48
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFStereotypeFeatureModelHandler.java310
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFStereotypeFeatureModelHandlerState.java111
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFUtils.java113
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EnumerationEMFModelHandler.java344
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EnumerationEMFModelHandlerFactory.java45
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EnumerationStereotypeModelHandler.java279
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EnumerationStereotypeModelHandlerFactory.java44
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/IEMFModelHandler.java239
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/IEMFModelHandlerState.java23
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/ReferenceEMFModelHandler.java304
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/ReferenceEMFModelHandlerFactory.java45
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/ReferenceStereotypeModelHandler.java73
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/ReferenceStereotypeModelHandlerFactory.java44
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/StereotypeModelHandlerFactory.java47
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/StringEMFModelHandler.java327
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/StringEMFModelHandlerFactory.java45
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/StringStereotypeModelHandler.java194
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/StringStereotypeModelHandlerFactory.java44
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/TransactionUtil.java63
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/AbstractPropertyEditor.java281
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/AbstractTablePropertyEditor.java497
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/ComboPropertyEditor.java202
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/CreatePropertyEditorDescriptorOperation.java64
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/CreatePropertyEditorOperation.java83
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/GroupedRadioBoxPropertyEditor.java81
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/IPropertyEditorTypeValidator.java36
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultiplePrimitiveTypedPropertyEditor.java100
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultiplePrimitiveTypedPropertyEditorValidator.java36
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultipleReferencePropertyEditor.java367
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultipleReferencePropertyEditorValidator.java38
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultipleStructuralFeaturesPropertyEditor.java34
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultipleStructuralFeaturesPropertyEditorValidator.java38
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/NullPropertyEditor.java100
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/NullPropertyEditorTypeValidator.java34
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/PropertyEditorConfiguration.java240
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/PropertyEditorProvider.java126
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/PropertyEditorService.java161
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/PropertyEditorTypeValidator.java41
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/RadioBoxPropertyEditor.java236
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/SimpleReferencePropertyEditor.java334
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/SimpleReferencePropertyEditorValidator.java38
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/TextPropertyEditor.java188
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/TextPropertyEditorValidator.java39
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/ComboPropertyEditorDescriptor.java72
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/ComboPropertyEditorDescriptorFactory.java75
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/IBoundedValuesPropertyEditorDescriptor.java36
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/IPropertyEditorDescriptor.java59
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/IPropertyEditorDescriptorFactory.java29
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultiplePrimitiveTypedPropertyEditorDescriptor.java53
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultiplePrimitiveTypedPropertyEditorDescriptorFactory.java74
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultipleReferencePropertyEditorDescriptor.java53
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultipleReferencePropertyEditorDescriptorFactory.java74
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultipleStructuralFeaturesPropertyEditorDescriptor.java54
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultipleStructuralFeaturesPropertyEditorDescriptorFactory.java75
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/PropertyEditorDescriptor.java133
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/PropertyEditorDescriptorFactory.java74
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/PropertyEditorDescriptorState.java172
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/RadioBoxPropertyEditorDescriptor.java73
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/RadioBoxPropertyEditorDescriptorFactory.java75
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/SimpleReferencePropertyEditorDescriptor.java53
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/SimpleReferencePropertyEditorDescriptorFactory.java74
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/state/AbstractState.java65
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/state/IFragmentDescriptorState.java37
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/state/IState.java86
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/state/ITraversableModelElement.java45
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/AbstractConstrainedDescriptor.java117
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/DialogDescriptor.java141
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/FragmentDescriptor.java110
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/FragmentDescriptorState.java300
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/GetAllFragmentDescriptorsOperation.java42
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/GetFragmentDescriptorOperation.java54
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/IConfigurableDescriptor.java46
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/IFragmentDescriptor.java43
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/IPropertyViewOperation.java24
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/IPropertyViewProvider.java87
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/PredefinedFragmentDescriptor.java93
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/PredefinedFragmentDescriptorState.java107
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/PropertyViewProviderParser.java672
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/PropertyViewService.java307
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/XMLParseException.java32
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/XMLPropertyViewProvider.java352
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/constraints/AppliedStereotypeConstraintDescriptor.java198
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/constraints/ConstraintDescriptorState.java74
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/constraints/ConstraintParser.java82
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/constraints/IConstraintDescriptor.java35
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/constraints/ObjectTypeConstraintDescriptor.java161
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/AbstractContainerDescriptor.java79
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/ContainerDescriptor.java256
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/ContainerDescriptorState.java219
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/ExpandableContainerDescriptor.java258
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/GridLayoutDescriptor.java101
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/GridLayoutDescriptorState.java160
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/GroupContainerDescriptor.java240
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/LayoutDescriptor.java34
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/LayoutDescriptorState.java64
-rw-r--r--plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/LayoutParser.java90
149 files changed, 19237 insertions, 0 deletions
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/Activator.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/Activator.java
new file mode 100644
index 00000000000..679b284b8aa
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/Activator.java
@@ -0,0 +1,99 @@
+package org.eclipse.papyrus.properties.runtime;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.jface.resource.ImageRegistry;
+import org.eclipse.papyrus.log.LogHelper;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+ /** plugin ID */
+ public static final String ID = "org.eclipse.papyrus.properties.runtime";
+
+ /** shared instance */
+ private static Activator plugin;
+
+ /** Logging helper */
+ public static LogHelper log;
+
+ /**
+ * The constructor
+ */
+ public Activator() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void start(BundleContext context) throws Exception {
+ super.start(context);
+ plugin = this;
+ log = new LogHelper(plugin);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void stop(BundleContext context) throws Exception {
+ plugin = null;
+ super.stop(context);
+ }
+
+ /**
+ * Returns the shared instance
+ *
+ * @return the shared instance
+ */
+ public static Activator getDefault() {
+ return plugin;
+ }
+
+ /**
+ * This method returns an <code>org.eclipse.swt.graphics.Image</code> identified by its pluginId and image Descriptor.<BR>
+ *
+ * By default, it returns a default image. This image is the image placed in
+ * the directory <em>resources/icons/default.gif</em>
+ *
+ * @param descriptor
+ * the image descriptor of the image
+ * @return the Image
+ */
+ public static Image getImageFromDescriptor(ImageDescriptor descriptor) {
+ String key = descriptor.toString();
+ ImageRegistry registry = getDefault().getImageRegistry();
+ Image image = registry.get(key);
+
+ if(image == null) {
+
+ registry.put(key, descriptor);
+ image = registry.get(key);
+
+ }
+ return image;
+ }
+
+ /**
+ * Returns the image from the given path
+ *
+ * @param path
+ * the path the image to be displayed
+ * @return the image found
+ */
+ public static Image getImage(String path) {
+ final ImageRegistry registry = getDefault().getImageRegistry();
+ Image image = registry.get(path);
+ if(image == null) {
+ registry.put(path, Activator.imageDescriptorFromPlugin(ID, path));
+ image = registry.get(path);
+ }
+ return image;
+
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/Messages.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/Messages.java
new file mode 100644
index 00000000000..2366c6d4d4b
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/Messages.java
@@ -0,0 +1,42 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime;
+
+import org.eclipse.osgi.util.NLS;
+
+/**
+ * Messages internationalization class
+ */
+public class Messages extends NLS {
+
+ /** bundle name */
+ private static final String BUNDLE_NAME = "org.eclipse.papyrus.properties.runtime.messages"; //$NON-NLS-1$
+
+ /** Label for the Menu: CreationOperation */
+ public static String EMFTEReferenceController_CreationOperationMenuLabel;
+
+ /** Label for the Operation: Destroy operation */
+ public static String EMFTEReferenceController_DeleteElement_OperationLabel;
+
+ public static String ReferenceEMFModelHandler_Select_Values;
+
+ static {
+ // initialize resource bundle
+ NLS.initializeMessages(BUNDLE_NAME, Messages.class);
+ }
+
+ /**
+ * Creates a new Messages.
+ */
+ private Messages() {
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/BeanPropertyEditorController.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/BeanPropertyEditorController.java
new file mode 100644
index 00000000000..a67ee9a483c
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/BeanPropertyEditorController.java
@@ -0,0 +1,79 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller;
+
+import java.beans.PropertyChangeListener;
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.BeanPropertyEditorControllerDescriptor;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IPropertyEditorControllerDescriptor;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.swt.widgets.Composite;
+
+
+
+/**
+ * Controller for property editors based on java.beans property
+ */
+public abstract class BeanPropertyEditorController extends PropertyEditorController implements PropertyChangeListener {
+
+ /** descriptor that configures this controller */
+ private BeanPropertyEditorControllerDescriptor descriptor;
+
+ /** identifier for this controller */
+ public final static String ID = "beanPropertyEditorController";
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected IStatus initPropertyEditor(IPropertyEditorDescriptor descriptor) {
+ return getPropertyEditor().init(descriptor);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IStatus initController(Composite parent, List<Object> objectsToEdit, IPropertyEditorControllerDescriptor descriptor) {
+ setParent(parent);
+ setObjectsToEdit(objectsToEdit);
+
+ if(descriptor instanceof BeanPropertyEditorControllerDescriptor) {
+ this.descriptor = (BeanPropertyEditorControllerDescriptor)descriptor;
+ } else {
+ return new Status(IStatus.ERROR, Activator.ID, "impossible to adapt descriptor to an EMFTPropertyEditorControllerDescriptor");
+ }
+
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * Returns the descriptor configuring this controller
+ *
+ * @return the descriptor configuring this controller
+ */
+ public BeanPropertyEditorControllerDescriptor getDescriptor() {
+ return descriptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void updateModel() {
+ setValueInModel(getEditorValue());
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/CreatePropertyEditorControllerDescriptorOperation.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/CreatePropertyEditorControllerDescriptorOperation.java
new file mode 100644
index 00000000000..cbe67dcdb5f
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/CreatePropertyEditorControllerDescriptorOperation.java
@@ -0,0 +1,82 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller;
+
+import org.eclipse.gmf.runtime.common.core.service.IOperation;
+import org.eclipse.gmf.runtime.common.core.service.IProvider;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IPropertyEditorControllerDescriptor;
+import org.osgi.framework.Bundle;
+import org.w3c.dom.Node;
+
+
+/**
+ * Operation that creates and configure the descriptor of a property editor controller provider
+ */
+public class CreatePropertyEditorControllerDescriptorOperation implements IOperation {
+
+ /** id of the controller to configure */
+ private final String controllerID;
+
+ /** node that configures the controller */
+ private final Node controllerNode;
+
+ /** bundle used to load classes for the controllers */
+ private final Bundle bundle;
+
+ /**
+ * Creates a new CreatePropertyEditorControllerDescriptorOperation.
+ *
+ * @param controllerId
+ * the id of the configured controller
+ * @param controllerNode
+ * the node that configures the controller
+ * @param bundle
+ * bundle used to load classes
+ */
+ public CreatePropertyEditorControllerDescriptorOperation(String controllerId, Node controllerNode, Bundle bundle) {
+ this.controllerID = controllerId;
+ this.controllerNode = controllerNode;
+ this.bundle = bundle;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IPropertyEditorControllerDescriptor execute(IProvider provider) {
+ IPropertyEditorControllerDescriptor descriptor = null;
+
+ if(provider instanceof PropertyEditorControllerProvider) {
+ descriptor = ((PropertyEditorControllerProvider)provider).generateDescriptor(controllerID, controllerNode);
+ }
+
+ return descriptor;
+ }
+
+ /**
+ * Returns the controller unique identifier
+ *
+ * @return the controller unique identifier
+ */
+ public String getControllerID() {
+ return controllerID;
+ }
+
+ /**
+ * Returns the bundle
+ *
+ * @return the bundle
+ */
+ public Bundle getBundle() {
+ return bundle;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/CreatePropertyEditorControllerOperation.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/CreatePropertyEditorControllerOperation.java
new file mode 100644
index 00000000000..7e08c8996a4
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/CreatePropertyEditorControllerOperation.java
@@ -0,0 +1,116 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.gmf.runtime.common.core.service.IOperation;
+import org.eclipse.gmf.runtime.common.core.service.IProvider;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IPropertyEditorControllerDescriptor;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * Specific operation for emft-based controllers
+ */
+public class CreatePropertyEditorControllerOperation implements IOperation {
+
+ /** the parent of all controls created by the editor */
+ private Composite parent;
+
+ /** List of EObjects to edit */
+ private List<Object> objectsToEdit;
+
+ /** configuration of the EMFTPropertyEditorController */
+ private final IPropertyEditorControllerDescriptor descriptor;
+
+ /** id of the controller to create */
+ private String controllerID;
+
+
+ /**
+ * Creates a new CreatePropertyEditorControllerOperation.
+ *
+ * @param id
+ * the identifier of the editor controller to create
+ * @param objectsToEdit
+ * List of EObjects to edit
+ * @param descriptor
+ * the configuration of the editor
+ * @param parent
+ * parent of all controls created by the editor
+ */
+ public CreatePropertyEditorControllerOperation(String id, List<Object> objectsToEdit, Composite parent, IPropertyEditorControllerDescriptor descriptor) {
+ this.controllerID = id;
+ this.descriptor = descriptor;
+ this.objectsToEdit = objectsToEdit;
+ this.parent = parent;
+ }
+
+ /**
+ * Returns the identifier of the specific controller to find
+ *
+ * @return the identifier of the controller editor to find.
+ */
+ public String getControllerIdentifier() {
+ return controllerID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IPropertyEditorController execute(IProvider provider) {
+ if(provider instanceof PropertyEditorControllerProvider) {
+ if(checkMultiSelection()) {
+ // this descriptor allows multi-selection edition. Create the given controller
+ IPropertyEditorController controller = ((PropertyEditorControllerProvider)provider).createPropertyEditorController(getControllerIdentifier());
+ IStatus status = controller.initController(parent, objectsToEdit, descriptor);
+ if(status.getSeverity() != Status.ERROR) {
+ return controller;
+ } else {
+ Activator.log.error("(" + status.getSeverity() + ") Error during creation of Property Editor Controller: " + status.getMessage(), null);
+ return null;
+ }
+
+ }
+
+ return null;
+ } else {
+ Activator.log.error("CreatePropertyEditorControllerOperation should execute on a PropertyEditorControllerProvider", null);
+ }
+ return null;
+ }
+
+ /**
+ * Checks if the current selection is supported by the controller
+ *
+ * @param descriptor
+ * the descriptor to check
+ * @param objectsToEdit
+ * the selection of objects
+ * @return <code>true</code> if the selection is OK for the controller
+ */
+ protected boolean checkMultiSelection() {
+ int selectionSize = objectsToEdit.size();
+ if(selectionSize > 1) {
+ // multi selection. check if the controller accepts this condition
+ return descriptor.acceptMultiSelection();
+ }
+ // selection has only one element => controller should be ok in every cases
+ return true;
+ }
+
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFPropertyEditorController.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFPropertyEditorController.java
new file mode 100644
index 00000000000..e3a6049715d
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFPropertyEditorController.java
@@ -0,0 +1,40 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller;
+
+import java.util.List;
+
+import org.eclipse.emf.common.notify.Adapter;
+import org.eclipse.emf.ecore.EObject;
+
+
+/**
+ * Property editor controller for EMF-based models
+ */
+public abstract class EMFPropertyEditorController extends PropertyEditorController implements Adapter {
+
+ /**
+ * Creates a new EMFPropertyEditorController.
+ */
+ public EMFPropertyEditorController() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public List<? extends EObject> getObjectsToEdit() {
+ return (List<? extends EObject>)super.getObjectsToEdit();
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFTBindingEReferenceController.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFTBindingEReferenceController.java
new file mode 100644
index 00000000000..64f3497779c
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFTBindingEReferenceController.java
@@ -0,0 +1,121 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IBindingLabelProviderDescriptor;
+import org.eclipse.swt.graphics.Image;
+
+
+/**
+ * Controller for {@link EReference}(s) that uses a binding label provider to display references
+ */
+public class EMFTBindingEReferenceController extends EMFTEReferenceController {
+
+ /** identifier for this controller */
+ public final static String ID = "emftBindingEReferenceController";
+
+ /** editor label provider for EMF objects */
+ protected ILabelProvider editorLabelProvider = new BindingLabelProvider(labelProvider);
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ILabelProvider getEditorLabelProvider() {
+ return editorLabelProvider;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ILabelProvider getBrowserLabelProvider() {
+ return editorLabelProvider;
+ }
+
+ /**
+ * Label provider which proposed binded messages if possible, otherwise relies on an other label provider
+ */
+ public class BindingLabelProvider implements ILabelProvider {
+
+ /** label provider used by default */
+ protected final ILabelProvider referenceLabelProvider;
+
+ /**
+ * Creates a new EMFTEReferenceController.BindingLabelProvider.
+ *
+ * @param labelProvider
+ * the referenced label provider, which is used by default when the label provider can not bind elements
+ */
+ public BindingLabelProvider(ILabelProvider labelProvider) {
+ this.referenceLabelProvider = labelProvider;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addListener(ILabelProviderListener listener) {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void dispose() {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isLabelProperty(Object element, String property) {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removeListener(ILabelProviderListener listener) {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage(Object element) {
+ return referenceLabelProvider.getImage(element);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText(Object element) {
+
+ if(getDescriptor() instanceof IBindingLabelProviderDescriptor) {
+ // retrieve message to display
+ // the features are the features of the element referenced by the structural feature => has to compute this value
+ if(element instanceof EObject) {
+ if(((EObject)element).eIsProxy()) {
+ return "Proxy - " + element;
+ }
+
+ return ((IBindingLabelProviderDescriptor)getDescriptor()).computeBindings((EObject)element);
+ }
+ }
+ return referenceLabelProvider.getText(element);
+ }
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFTEReferenceController.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFTEReferenceController.java
new file mode 100644
index 00000000000..2df3f5a3c97
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFTEReferenceController.java
@@ -0,0 +1,299 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.commands.operations.IUndoableOperation;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.common.util.TreeIterator;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.resource.Resource;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.emf.edit.provider.IItemLabelProvider;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryContentProvider;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand;
+import org.eclipse.gmf.runtime.emf.type.core.IElementType;
+import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest;
+import org.eclipse.gmf.runtime.emf.type.core.requests.DestroyElementRequest;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerFilter;
+import org.eclipse.papyrus.core.utils.DisplayUtils;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.Messages;
+import org.eclipse.papyrus.properties.runtime.modelhandler.emf.EMFFeatureModelHandler;
+import org.eclipse.papyrus.service.edit.service.ElementEditServiceUtils;
+import org.eclipse.papyrus.service.edit.service.IElementEditService;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Controller for EReferences controller
+ */
+public class EMFTEReferenceController extends EMFTStructuralFeatureController implements IBoundedValuesController, IWizardPropertyEditorController {
+
+ /** identifier for this controller */
+ public final static String ID = "emftEReferenceController"; //$NON-NLS-1$
+
+ /** factory used by EMF objects */
+ protected AdapterFactory factory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
+
+ /** label provider for EMF objects */
+ protected ILabelProvider labelProvider = initLabelProvider();
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object getAvailableValues() {
+ return getModelHandler().getAvailableValues(getObjectsToEdit().get(0));
+ }
+
+ /**
+ * Creates and return the label provider for this controller
+ *
+ * @return the label provider for this controller
+ */
+ protected ILabelProvider initLabelProvider() {
+ final ILabelProvider provider = DisplayUtils.getLabelProvider();
+ if(provider != null) {
+ return provider;
+ }
+ Activator.log.warn("Impossible to find the label provider from the service registry"); //$NON-NLS-1$
+ // adapter factory used by EMF objects
+ return new AdapterFactoryLabelProvider(factory) {
+
+ /**
+ * This implements {@link ILabelProvider}.getText by forwarding it
+ * to an object that implements {@link IItemLabelProvider#getText
+ * IItemLabelProvider.getText}
+ */
+ public String getText(Object object) {
+ // Get the adapter from the factory.
+ //
+ IItemLabelProvider itemLabelProvider = (IItemLabelProvider)adapterFactory.adapt(object, IItemLabelProvider.class);
+ if(object instanceof EObject) {
+ if(((EObject)object).eIsProxy()) {
+ return "Proxy - " + object; //$NON-NLS-1$
+ }
+ }
+ return itemLabelProvider != null ? itemLabelProvider.getText(object) : object == null ? "" : object.toString(); //$NON-NLS-1$
+ }
+ };
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object[] getCurrentValues() {
+ // look only for first element
+ EObject eObject = getObjectsToEdit().get(0);
+ Object values = getModelHandler().getValueToEdit(eObject);
+ if(values instanceof Object[]) {
+ return (Object[])values;
+ } else if(values instanceof List<?>) {
+ return ((List<?>)values).toArray();
+ } else if(values instanceof Object) {
+ return Arrays.asList(values).toArray();
+ }
+ return new Object[]{ values };
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ILabelProvider getBrowserLabelProvider() {
+ return labelProvider;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ILabelProvider getEditorLabelProvider() {
+ return labelProvider;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<ViewerFilter> getViewerFilters() {
+ List<ViewerFilter> filters = new ArrayList<ViewerFilter>();
+ ViewerFilter typeFilter = new ViewerFilter() {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean select(Viewer viewer, Object parentElement, Object element) {
+ // return containsValidElements(element,
+ // getFeatureToEdit().getEType().getInstanceClass());
+ return true;
+ }
+ };
+ filters.add(typeFilter);
+ return filters;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IStructuredContentProvider getContentProvider() {
+ return new AdapterFactoryContentProvider(factory) {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object[] getElements(Object inputElement) {
+ if(inputElement instanceof ResourceSet) {
+ ResourceSet resourceSet = (ResourceSet)inputElement;
+
+ ArrayList<EObject> contents = new ArrayList<EObject>();
+ for(Resource resource : resourceSet.getResources()) {
+ contents.addAll(resource.getContents());
+ }
+ return contents.toArray();
+ }
+ return super.getElements(inputElement);
+ }
+ };
+ }
+
+ /**
+ * Returns <code>true</code> if the element contains valid elements
+ *
+ * @param element
+ * the element to check
+ * @param typeClass
+ * the type of element to check
+ * @return <code>true</code> if the element contains valid elements
+ */
+ protected static boolean containsValidElements(Object element, Class<?> typeClass) {
+ if(element instanceof Resource) {
+ TreeIterator<EObject> iter = (((Resource)element)).getAllContents();
+ while(iter.hasNext()) {
+ if(containsValidElements(iter.next(), typeClass))
+ return true;
+ }
+ }
+ if(element instanceof EObject) {
+ EObject eObject = (EObject)element;
+ if(typeClass.isAssignableFrom(eObject.getClass())) {
+ return true;
+ }
+
+ for(EObject content : eObject.eContents()) {
+ if(containsValidElements(content, typeClass)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<IUndoableOperation> getAvailableCreationOperations() {
+ // retrieve the Eclass of the elements to edit
+ List<IUndoableOperation> undoableOperations = new ArrayList<IUndoableOperation>();
+ EClass eClass = retrieveEClass();
+ if(eClass == null || getObjectsToEdit() == null || getObjectsToEdit().size() == 0 || !(getModelHandler() instanceof EMFFeatureModelHandler)) {
+ return undoableOperations;
+ }
+ EObject eObject = getObjectsToEdit().get(0);
+ EStructuralFeature feature = ((EMFFeatureModelHandler)getModelHandler()).getFeatureByName(eObject);
+ if(!(feature instanceof EReference)) {
+ return undoableOperations;
+ }
+ //IClientContext context;
+ try {
+ //context = UMLTypeContext.getContext();
+
+
+
+ // Use UML service creation context and look for element types that are possible types of
+ // the selected EReference
+ List<IElementEditService> containedTypeServices = ElementEditServiceUtils.getEditServiceProvider().getContainedTypeEditServices(eObject, (EReference)feature);
+ for(IElementEditService service : containedTypeServices) {
+ CreateElementRequest request = new CreateElementRequest(getEditingDomain(), eObject, (IElementType)service.getAdapter(IElementType.class), (EReference)feature);
+ request.setLabel(Messages.bind(Messages.EMFTEReferenceController_CreationOperationMenuLabel, service.getDisplayName()));
+ ICommand command = service.getEditCommand(request);
+ if(command.canExecute()) {
+ // adds it to the list of command that can be
+ // executed
+ undoableOperations.add(command);
+ }
+ }
+
+ } catch (Exception e) {
+ Activator.log.error(e);
+ }
+ return undoableOperations;
+ }
+
+ /**
+ * Retrieves the common metaclass for all selected objects
+ *
+ * @return the selected metaclass
+ *
+ */
+ protected EClass retrieveEClass() {
+ @SuppressWarnings("unchecked")
+ List<EObject> eObjects = (List<EObject>)getObjectsToEdit();
+ if(eObjects == null) {
+ return null;
+ } else if(eObjects.size() > 0) {
+ return eObjects.get(0).eClass();
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int openPostCreationDialog(Shell shell) {
+ return 0;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IUndoableOperation getDeleteOperation(List<Object> objectsToDelete) {
+ CompositeTransactionalCommand undoableOperation = new CompositeTransactionalCommand(getEditingDomain(), Messages.EMFTEReferenceController_DeleteElement_OperationLabel);
+ EClass eClass = retrieveEClass();
+ if(eClass == null || getObjectsToEdit() == null || getObjectsToEdit().size() == 0 || !(getModelHandler() instanceof EMFFeatureModelHandler)) {
+ return undoableOperation;
+ }
+ for(Object objectToDelete : objectsToDelete) {
+ if(objectToDelete instanceof EObject) {
+ DestroyElementRequest request = new DestroyElementRequest(getEditingDomain(), (EObject)objectToDelete, false);
+ IUndoableOperation operation = ElementEditServiceUtils.getCommandProvider(objectToDelete).getEditCommand(request);
+ if(operation != null && operation.canExecute()) {
+ undoableOperation.add(operation);
+ }
+ } else {
+ Activator.log.debug("the object to delete was not an EObject: " + objectToDelete);
+ }
+ }
+
+ return undoableOperation.reduce();
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFTLabelProviderStructuralFeatureController.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFTLabelProviderStructuralFeatureController.java
new file mode 100644
index 00000000000..7ab055d154d
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFTLabelProviderStructuralFeatureController.java
@@ -0,0 +1,142 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.core.commands.operations.IUndoableOperation;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.emf.edit.provider.IItemLabelProvider;
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider;
+import org.eclipse.gmf.runtime.emf.type.core.ElementTypeRegistry;
+import org.eclipse.gmf.runtime.emf.type.core.IElementType;
+import org.eclipse.gmf.runtime.emf.type.core.edithelper.IEditHelper;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.papyrus.core.utils.DisplayUtils;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.modelhandler.emf.EMFFeatureModelHandler;
+
+
+/**
+ * Controller for Structural features which uses a label provider to display elements
+ */
+public class EMFTLabelProviderStructuralFeatureController extends EMFTStructuralFeatureController implements ILabelProviderController {
+
+ /** id of the controller */
+ public final static String ID = "emftLabelProviderStructuralFeatureController";
+
+ /** label provider for EMF objects */
+ protected ILabelProvider labelProvider = initLabelProvider();
+
+ /**
+ * Creates and return the label provider for this controller
+ *
+ * @return the label provider for this controller
+ */
+ protected ILabelProvider initLabelProvider() {
+ final ILabelProvider provider = DisplayUtils.getLabelProvider();
+ if(provider != null) {
+ return provider;
+ }
+ Activator.log.warn("Impossible to find the label provider from the service registry");
+ //adapter factory used by EMF objects
+ AdapterFactory factory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
+ return new AdapterFactoryLabelProvider(factory) {
+
+ /**
+ * This implements {@link ILabelProvider}.getText by forwarding it to an object that implements {@link IItemLabelProvider#getText
+ * IItemLabelProvider.getText}
+ */
+ public String getText(Object object) {
+ // Get the adapter from the factory.
+ //
+ IItemLabelProvider itemLabelProvider = (IItemLabelProvider)adapterFactory.adapt(object, IItemLabelProvider.class);
+ if(object instanceof EObject) {
+ if(((EObject)object).eIsProxy()) {
+ return "Proxy - " + object;
+ }
+ }
+ return itemLabelProvider != null ? itemLabelProvider.getText(object) : object == null ? "" : object.toString();
+ }
+ };
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ILabelProvider getEditorLabelProvider() {
+ return labelProvider;
+ }
+
+ /**
+ * Returns the list of all available creation operation for this controller
+ *
+ * @return the list of available operations
+ */
+ public List<IUndoableOperation> getAvailableCreationOperations() {
+ // retrieve the Eclass of the elements to edit
+ EClass eClass = retrieveEClass();
+ if(eClass == null || getObjectsToEdit() == null || getObjectsToEdit().size() == 0 || !(getModelHandler() instanceof EMFFeatureModelHandler)) {
+ return new ArrayList<IUndoableOperation>();
+ }
+ EObject eObject = getObjectsToEdit().get(0);
+ EStructuralFeature feature = ((EMFFeatureModelHandler)getModelHandler()).getFeatureByName(eObject);
+ if(!(feature instanceof EReference)) {
+ return new ArrayList<IUndoableOperation>();
+ }
+ IElementType type = ElementTypeRegistry.getInstance().getElementType(eClass);
+ IEditHelper helper = type.getEditHelper();
+ List<?> values = helper.getContainedValues(eObject, (EReference)feature);
+ if(values != null) {
+ for(Iterator<?> i = values.iterator(); i.hasNext();) {
+ Object nextValue = i.next();
+ if(nextValue instanceof IElementType) {
+ IElementType next = (IElementType)nextValue;
+ System.err.println(next);
+ }
+ }
+ }
+
+ List<IUndoableOperation> operations = new ArrayList<IUndoableOperation>();
+
+ Collection<?> list = getEditingDomain().getNewChildDescriptors(getObjectsToEdit().get(0), null);
+ System.err.println(list);
+
+ return operations;
+ }
+
+ /**
+ * Retrieves the common metaclass for all selected objects
+ *
+ * @return the selected metaclass
+ *
+ */
+ protected EClass retrieveEClass() {
+ @SuppressWarnings("unchecked")
+ List<EObject> eObjects = (List<EObject>)getObjectsToEdit();
+ if(eObjects == null) {
+ return null;
+ } else if(eObjects.size() > 0) {
+ return eObjects.get(0).eClass();
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFTPropertyEditorController.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFTPropertyEditorController.java
new file mode 100644
index 00000000000..3e880507d90
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFTPropertyEditorController.java
@@ -0,0 +1,136 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ * Vincent Lorenzo (CEA-LIST) vincent.lorenzo@cea.fr
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.common.core.command.CompositeCommand;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
+import org.eclipse.papyrus.commands.wrappers.GMFtoEMFCommandWrapper;
+import org.eclipse.papyrus.properties.runtime.modelhandler.emf.IEMFModelHandler;
+import org.eclipse.papyrus.properties.runtime.modelhandler.emf.TransactionUtil;
+
+
+/**
+ * Controller for property editors, that manages EMFT-based models. This means that a transaction will be opened each time the model has to be
+ * modified
+ */
+public abstract class EMFTPropertyEditorController extends EMFPropertyEditorController {
+
+ /** Transactional editing domain used to write into the model */
+ private TransactionalEditingDomain editingDomain;
+
+ /** model handler to interact with the model for this controller */
+ protected IEMFModelHandler modelHandler;
+
+ /**
+ * Constructor.
+ */
+ public EMFTPropertyEditorController() {
+ super();
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.properties.runtime.controller.PropertyEditorController#updateModel()
+ *
+ */
+ @Override
+ public void updateModel() {
+ CompositeCommand cc = new CompositeCommand("Set Value Command"); //$NON-NLS-1$
+ Object valueToSet = getEditorValue();
+ for(Object obj : this.objectToEdit) {
+ EObject elementToEdit = (EObject)obj;
+ //build the request
+ SetRequest[] req = null;
+ req = modelHandler.getSetRequest(getEditingDomain(), elementToEdit, valueToSet);
+ if(req == null) {
+ break;
+ }
+ org.eclipse.papyrus.service.edit.service.IElementEditService provider = org.eclipse.papyrus.service.edit.service.ElementEditServiceUtils.getCommandProvider(elementToEdit);
+ if(provider != null) {
+
+ ICommand editCommand = null;
+ for(SetRequest current : req) {
+ editCommand = provider.getEditCommand(current);
+
+ if(editCommand != null && editCommand.canExecute()) {
+ cc.add(editCommand);
+ }
+ }
+ }
+
+ if(cc.canExecute() && !(TransactionUtil.isReadTransactionInProgress(getEditingDomain(), true, true))) {
+ getEditingDomain().getCommandStack().execute(new GMFtoEMFCommandWrapper(cc));
+ return;
+ }
+ }
+
+ /*
+ * req was null, or the command was unexecutable
+ * Currently, the handler for stereotype return always null!
+ */
+ AbstractTransactionalCommand command = new EMFTControllerCommand();
+ if(command.canExecute() && !(TransactionUtil.isReadTransactionInProgress(editingDomain, true, true))) {
+ editingDomain.getCommandStack().execute(new GMFtoEMFCommandWrapper(command));
+ }
+ }
+
+ /**
+ * Returns the editing domain that manages modifications to the model
+ *
+ * @return the editing domain that manages modifications to the model
+ */
+ public TransactionalEditingDomain getEditingDomain() {
+ return editingDomain;
+ }
+
+ /**
+ * Sets the editingDomain for this controller
+ *
+ * @param editingDomain
+ * the editingDomain to set
+ */
+ public void setEditingDomain(TransactionalEditingDomain editingDomain) {
+ this.editingDomain = editingDomain;
+ }
+
+ /**
+ * Command to modify the model, using the property editors
+ */
+ protected class EMFTControllerCommand extends AbstractTransactionalCommand {
+
+ /**
+ * Creates the new EMFTControllerCommand.
+ */
+ public EMFTControllerCommand() {
+ super(editingDomain, "Editing Property", getWorkspaceFiles(getObjectsToEdit())); //$NON-NLS-1$
+ }
+
+ /**
+ * @{inheritDoc
+ */
+ @Override
+ protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+ setValueInModel(getEditorValue());
+ return CommandResult.newOKCommandResult(getObjectsToEdit());
+ }
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFTStructuralFeatureController.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFTStructuralFeatureController.java
new file mode 100644
index 00000000000..e7fd1dc0e83
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/EMFTStructuralFeatureController.java
@@ -0,0 +1,287 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ * Vincent Lorenzo (CEA-LIST) vincent.lorenzo@cea.fr
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller;
+
+import java.util.List;
+
+import org.eclipse.core.commands.operations.IUndoableOperation;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.notify.Notifier;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.EMFTPropertyEditorControllerDescriptor;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IPropertyEditorControllerDescriptor;
+import org.eclipse.papyrus.properties.runtime.controller.predefined.PredefinedControllerDescriptor;
+import org.eclipse.papyrus.properties.runtime.modelhandler.emf.EMFUtils;
+import org.eclipse.papyrus.properties.runtime.modelhandler.emf.IEMFModelHandler;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * Controller for {@link EStructuralFeature} property editor controller.
+ */
+public class EMFTStructuralFeatureController extends EMFTPropertyEditorController {
+
+ /** descriptor that configures this controller */
+ private EMFTPropertyEditorControllerDescriptor descriptor;
+
+ /** identifier of the controller */
+ public final static String ID = "emftStructuralFeatureController"; //$NON-NLS-1$
+
+ /**
+ * Creates a new EMFTStructuralFeatureController.
+ */
+ public EMFTStructuralFeatureController() {
+ super();
+ }
+
+ /**
+ * Initialize the controller.
+ *
+ * @param parent
+ * the composite parent of the controls created by the editor
+ * @param objectsToEdit
+ * the list of objects to edit
+ * @param descriptor
+ * the descriptor that realize specific configuration for this controller
+ */
+ @Override
+ public IStatus initController(Composite parent, List<Object> objectsToEdit, IPropertyEditorControllerDescriptor descriptor) {
+ setParent(parent);
+ IPropertyEditorControllerDescriptor realDescriptor = descriptor;
+ if(descriptor instanceof PredefinedControllerDescriptor) {
+ IPropertyEditorControllerDescriptor predefinedDescriptor = ((PredefinedControllerDescriptor)descriptor).getDescriptor();
+ if(predefinedDescriptor instanceof EMFTPropertyEditorControllerDescriptor) {
+ realDescriptor = predefinedDescriptor;
+ }
+ }
+ if(realDescriptor instanceof EMFTPropertyEditorControllerDescriptor) {
+ this.descriptor = (EMFTPropertyEditorControllerDescriptor)realDescriptor;
+ } else {
+ return new Status(IStatus.ERROR, Activator.ID, "impossible to adapt descriptor to an EMFTPropertyEditorControllerDescriptor"); //$NON-NLS-1$
+ }
+
+ this.modelHandler = this.descriptor.getHandler();
+ setObjectsToEdit(objectsToEdit);
+
+ TransactionalEditingDomain editingDomain = EMFUtils.getTransactionalEditingDomain(objectsToEdit);
+ if(editingDomain == null && !objectsToEdit.isEmpty()) {
+ return new Status(IStatus.ERROR, Activator.ID, "impossible to find an editing domain for the controller."); //$NON-NLS-1$
+ }
+ setEditingDomain(editingDomain);
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean acceptMultiSelection() {
+ return descriptor.acceptMultiSelection();
+ }
+
+ /**
+ * Returns the model handler that manages interaction with the model
+ *
+ * @return the model handler that manages interaction with the model
+ */
+ public IEMFModelHandler getModelHandler() {
+ return modelHandler;
+ }
+
+
+ /**
+ * Returns the descriptor configuring this controller
+ *
+ * @return the descriptor configuring this controller
+ */
+ public EMFTPropertyEditorControllerDescriptor getDescriptor() {
+ return descriptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void addListenersToModel() {
+ modelHandler.addListenersToModel(getObjectsToEdit(), this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String getDefaultLabel() {
+ return descriptor.getFeatureNameToEdit();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Object getValueToEdit() {
+ // when editing multiple objects, the value returned is the value of the first element
+ // it has already been asserted in the contructor that the list is not empty. get(0) should never throw an exception
+ if(!getObjectsToEdit().isEmpty()) {
+ EObject object = getObjectsToEdit().get(0);
+ return getModelHandler().getValueToEdit(object);
+ }
+ return new Object();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void setValueInModel(Object value) {
+ // when editing multiple objects, the value set will be the same for all elements
+ // should look for exceptions here perhaps?
+ for(EObject object : getObjectsToEdit()) {
+ getModelHandler().setValueInModel(object, value);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected IStatus initPropertyEditor(IPropertyEditorDescriptor descriptor) {
+ // property editor has already been created, but it is not initialized
+ getPropertyEditor().setIsReadOnly(!getModelHandler().isChangeable(getObjectsToEdit()));
+ getModelHandler().completeEditorDescriptor(descriptor, getObjectsToEdit());
+ return getPropertyEditor().init(descriptor);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void removeListenersFromModel() {
+ getModelHandler().removeListenersFromModel(getObjectsToEdit(), this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Notifier getTarget() {
+ // nothing to do here, as there is only one target
+ return null;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isAdapterForType(Object type) {
+ for(EObject eObject : getObjectsToEdit()) {
+ if(eObject.getClass().equals(type)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void notifyChanged(Notification notification) {
+ getModelHandler().handleNotifyChange(notification, getObjectsToEdit(), this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setTarget(Notifier newTarget) {
+ // nothing to do here, as the adapter already knows the target
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IUndoableOperation getMoveCurrentValuesOperation(List<Integer> indexes, int delta) {
+ return getModelHandler().getMoveValueOperation(getObjectsToEdit(), indexes, getComposite(), delta);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean canMoveValues(List<Integer> indexes, int delta) {
+ return getModelHandler().canCreateMoveValueOperation(getObjectsToEdit(), indexes, getComposite(), delta);
+ }
+
+ /**
+ * Retrieves the common metaclass for all selected objects
+ *
+ * @return the selected metaclass
+ *
+ */
+ protected EClass retrieveEClass() {
+ @SuppressWarnings("unchecked")
+ List<EObject> eObjects = (List<EObject>)getObjectsToEdit();
+ if(eObjects == null) {
+ return null;
+ } else if(eObjects.size() > 0) {
+ return eObjects.get(0).eClass();
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<IUndoableOperation> getCreateValueOperations() {
+ return getModelHandler().getCreateValueOperations(getObjectsToEdit(), getComposite());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean canCreateValueOperations() {
+ return getModelHandler().canCreateValueOperations(getObjectsToEdit());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IUndoableOperation getDeleteValueOperation(List<Integer> indexes) {
+ return getModelHandler().getDeleteValueOperation(getObjectsToEdit(), getComposite(), indexes);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean canDeleteValueOperation() {
+ return getModelHandler().canCreateDeleteValueOperation(getObjectsToEdit());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IUndoableOperation getEditValueOperation(int index, Composite parent, Object value) {
+ return getModelHandler().getEditValueOperation(getObjectsToEdit(), index, parent, value);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean canCreateEditOperation(int index, Composite parent, Object value) {
+ return true;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/IBoundedValuesController.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/IBoundedValuesController.java
new file mode 100644
index 00000000000..03e2376522a
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/IBoundedValuesController.java
@@ -0,0 +1,62 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller;
+
+import java.util.List;
+
+import org.eclipse.jface.viewers.IContentProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ViewerFilter;
+
+
+
+/**
+ * Interface for bounded values controller (references, etc)
+ */
+public interface IBoundedValuesController extends ILabelProviderController {
+
+ /**
+ * Returns the list of available elements
+ *
+ * @return the list of available elements
+ */
+ public Object getAvailableValues();
+
+ /**
+ * Returns the list of current values
+ *
+ * @return the list of current values
+ */
+ public Object[] getCurrentValues();
+
+ /**
+ * Returns the set of filters used to display the tree
+ *
+ * @return the set of filters used to display the tree
+ */
+ public List<ViewerFilter> getViewerFilters();
+
+ /**
+ * Returns the content provider for the viewer
+ *
+ * @return the content provider for the viewer
+ */
+ public IContentProvider getContentProvider();
+
+ /**
+ * Returns the label provider used to display elements in the reference browser
+ *
+ * @return the label provider used to display elements in the reference browser
+ */
+ public ILabelProvider getBrowserLabelProvider();
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/ILabelProviderController.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/ILabelProviderController.java
new file mode 100644
index 00000000000..a0d1200ae03
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/ILabelProviderController.java
@@ -0,0 +1,29 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller;
+
+import org.eclipse.jface.viewers.ILabelProvider;
+
+
+/**
+ * Interface for Controllers using label providers
+ */
+public interface ILabelProviderController extends IPropertyEditorController {
+
+ /**
+ * Returns the label provider used to display elements in the editor
+ *
+ * @return the label provider used to display elements in the editor
+ */
+ public ILabelProvider getEditorLabelProvider();
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/IPropertyEditorController.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/IPropertyEditorController.java
new file mode 100644
index 00000000000..10c91bce6e8
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/IPropertyEditorController.java
@@ -0,0 +1,168 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller;
+
+import java.util.List;
+
+import org.eclipse.core.commands.operations.IUndoableOperation;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IPropertyEditorControllerDescriptor;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+
+
+/**
+ * Interface implemented by all property editor controllers
+ */
+public interface IPropertyEditorController {
+
+ /**
+ * Sets the objectToEdit
+ *
+ * @param objectToEdit
+ * the objectToEdit to set
+ */
+ public void setObjectsToEdit(List<? extends Object> objectToEdit);
+
+ /**
+ * Indicates that the list of objects to edit should change. It removes old listeners, and adds new ones
+ *
+ * @param objectToEdit
+ * the new list of objects to edit
+ */
+ public void changeObjectsToEdit(List<? extends Object> objectToEdit);
+
+ /**
+ * Sets the parent composite for all controls created by the editor
+ *
+ * @param composite
+ * the composite to set
+ */
+ public void setParent(Composite composite);
+
+ /**
+ * Indicates if the controller manages multi-selection of objects
+ *
+ * @return <code>true</code> if the controller accepts multi-selection
+ */
+ public boolean acceptMultiSelection();
+
+ /**
+ * Creates the property editor, with label on the specified position and the given icon.
+ *
+ * @param descriptor
+ * the image descriptor for the property editor
+ * @param widgetFactory
+ * widget factory used to create the content of the editor
+ */
+ public void createPropertyEditor(IPropertyEditorDescriptor descriptor, TabbedPropertySheetWidgetFactory widgetFactory);
+
+ /**
+ * Initialize the controller.
+ *
+ * @param parent
+ * the composite parent of the controls created by the editor
+ * @param objectsToEdit
+ * the list of objects to edit
+ * @param descriptor
+ * the descriptor that realize specific configuration for this controller
+ * @return the status of the initialization
+ */
+ public IStatus initController(Composite parent, List<Object> objectsToEdit, IPropertyEditorControllerDescriptor descriptor);
+
+ /**
+ * Refresh the content of the editor, given values in the model.
+ */
+ public void refreshDisplay();
+
+ /**
+ * Moves the given list of Objects in the list
+ *
+ * @param indexes
+ * the indexes of objects to move
+ * @param move
+ * the delta for the index (0: stays at the same place, -1: everything move upper, +2: everything moves 2 index further)
+ * @return the operation that moves the elements or <code>null</code>
+ */
+ public IUndoableOperation getMoveCurrentValuesOperation(List<Integer> indexes, int move);
+
+ /**
+ * Indicates if the values can be moved in the feature
+ *
+ * @param indexes
+ * the indexes of objects to move
+ * @param move
+ * the delta for the index (0: stays at the same place, -1: everything move upper, +2: everything moves 2 index further)
+ * @return <code>true</code> if the values can be moved, else <code>false</code>
+ */
+ public boolean canMoveValues(List<Integer> indexes, int move);
+
+ /**
+ * Returns the operation to create a new value for this property
+ *
+ * @return the operation to create a new value for this property
+ */
+ public List<IUndoableOperation> getCreateValueOperations();
+
+ /**
+ * Returns <code>true</code> if the controller can create a new value for the property
+ *
+ * @return <code>true</code> if the controller can create a new value for the property
+ */
+ public boolean canCreateValueOperations();
+
+ /**
+ * Returns the operation to delete a value for this property
+ *
+ * @param indexes
+ * list of indexes for values to delete (not used in case of single valued proeprty)
+ * @return the operation to delete a value for this property
+ */
+ public IUndoableOperation getDeleteValueOperation(List<Integer> indexes);
+
+ /**
+ * Returns <code>true</code> if the controller can delete a value for the property
+ *
+ * @return <code>true</code> if the controller can delete a value for the property
+ */
+ public boolean canDeleteValueOperation();
+
+ /**
+ * Returns the operation to edit a value for this property
+ *
+ * @param index
+ * the index of the value to set
+ * @param parent
+ * the composite parent used for user interface
+ * @param value
+ * the value to set
+ *
+ * @return the operation to edit a value for this property
+ */
+ public IUndoableOperation getEditValueOperation(int index, Composite parent, Object value);
+
+ /**
+ * Returns <code>true</code> if the controller can edit a value for the property
+ *
+ * @param index
+ * the index of the value to set
+ * @param parent
+ * the composite parent used for user interface
+ * @param value
+ * the value to set
+ *
+ * @return <code>true</code> if the controller can edit a value for the property
+ */
+ public boolean canCreateEditOperation(int index, Composite parent, Object value);
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/IWizardPropertyEditorController.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/IWizardPropertyEditorController.java
new file mode 100644
index 00000000000..80be5da4f4d
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/IWizardPropertyEditorController.java
@@ -0,0 +1,51 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller;
+
+import java.util.List;
+
+import org.eclipse.core.commands.operations.IUndoableOperation;
+import org.eclipse.swt.widgets.Dialog;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * Interface implemented by property editors that are able to create elements
+ */
+public interface IWizardPropertyEditorController {
+
+ /**
+ * Returns the list of available creation commands for the current set of objects to edit
+ *
+ * @return the list of available creation commands for the current set of objects to edit or an empty list if no commands are available
+ */
+ public List<IUndoableOperation> getAvailableCreationOperations();
+
+ /**
+ * Opens the dialog after the creation of the element
+ *
+ * @param shell
+ * the shell for the dialog
+ * @return the result of the open dialog (@see {@link Dialog})
+ */
+ public int openPostCreationDialog(Shell shell);
+
+ /**
+ * Returns the command that deletes the given list of elements
+ *
+ * @param objectsToDelete
+ * the list of objects to delete
+ * @return the operation in charge of the destruction or <code>null</code>
+ */
+ public IUndoableOperation getDeleteOperation(List<Object> objectsToDelete);
+
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/NullPropertyEditorController.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/NullPropertyEditorController.java
new file mode 100644
index 00000000000..89a24d8111a
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/NullPropertyEditorController.java
@@ -0,0 +1,153 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller;
+
+import java.util.List;
+
+import org.eclipse.core.commands.operations.IUndoableOperation;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IPropertyEditorControllerDescriptor;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * Controller for Empty property editors, i.e. editors that are a simple Composite
+ */
+public class NullPropertyEditorController extends PropertyEditorController {
+
+ /** id of this controller */
+ public static final String ID = "nullPropertyEditorController";
+
+ /**
+ * {@inheritDoc}
+ */
+ public IUndoableOperation getMoveCurrentValuesOperation(List<Integer> indexes, int move) {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean canMoveValues(List<Integer> indexes, int move) {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<IUndoableOperation> getCreateValueOperations() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean canCreateValueOperations() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IUndoableOperation getDeleteValueOperation(List<Integer> indexes) {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean canDeleteValueOperation() {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IUndoableOperation getEditValueOperation(int index, Composite parent, Object value) {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean canCreateEditOperation(int index, Composite parent, Object value) {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected String getDefaultLabel() {
+ return "";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected IStatus initPropertyEditor(IPropertyEditorDescriptor descriptor) {
+ return getPropertyEditor().init(descriptor);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IStatus initController(Composite parent, List<Object> objectsToEdit, IPropertyEditorControllerDescriptor descriptor) {
+ setParent(parent);
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void setValueInModel(Object value) {
+ // Nothing to do
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Object getValueToEdit() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void addListenersToModel() {
+ // Nothing to do
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void removeListenersFromModel() {
+ // Nothing to do
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void updateModel() {
+ // Nothing to do
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/PropertyEditorController.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/PropertyEditorController.java
new file mode 100644
index 00000000000..372bad0d326
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/PropertyEditorController.java
@@ -0,0 +1,230 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IPropertyEditorControllerDescriptor;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.AbstractPropertyEditor;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.PropertyEditorService;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.services.IDisposable;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+
+
+/**
+ * Controller for property editors
+ */
+public abstract class PropertyEditorController implements IDisposable, IPropertyEditorController {
+
+ /** objects to edit */
+ protected List<? extends Object> objectToEdit;
+
+ /** parent composite for the viewer */
+ protected Composite composite;
+
+ /** property editor */
+ protected AbstractPropertyEditor propertyEditor;
+
+ /**
+ * Creates a new {@link PropertyEditorController}
+ */
+ public PropertyEditorController() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setObjectsToEdit(List<? extends Object> objectToEdit) {
+ assert (objectToEdit != null && !objectToEdit.isEmpty()) : "List of object to edit should be neither null nor empty";
+ this.objectToEdit = objectToEdit;
+ addListenersToModel();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void changeObjectsToEdit(List<? extends Object> objectToEdit) {
+ removeListenersFromModel();
+ setObjectsToEdit(objectToEdit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setParent(Composite composite) {
+ this.composite = composite;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean acceptMultiSelection() {
+ return true;
+ }
+
+ /**
+ * Returns the property editor associated to this controller
+ *
+ * @return the propertyEditor controlled by this controller
+ */
+ public AbstractPropertyEditor getPropertyEditor() {
+ return propertyEditor;
+ }
+
+ /**
+ * Sets the property editor associated to this controller
+ *
+ * @param propertyEditor
+ * the property editor to set
+ */
+ protected void setPropertyEditor(AbstractPropertyEditor propertyEditor) {
+ this.propertyEditor = propertyEditor;
+ }
+
+ /**
+ * Returns the object to edit.
+ * <P>
+ * In case of a property editor that edits the name of a named element, the object to edit is the named element.
+ * </P>
+ *
+ * @return the object to edit
+ */
+ public List<? extends Object> getObjectsToEdit() {
+ return objectToEdit;
+ }
+
+ /**
+ * Returns the parent composite of controls created by the property editor
+ *
+ * @return the composite parent of controls of the property editor
+ */
+ protected Composite getComposite() {
+ return composite;
+ }
+
+ /**
+ * {@inheritDoc}
+ *
+ * @param widgetFactory
+ */
+ public void createPropertyEditor(IPropertyEditorDescriptor descriptor, TabbedPropertySheetWidgetFactory widgetFactory) {
+ setPropertyEditor(PropertyEditorService.getInstance().createPropertyEditor(this, descriptor.getEditorId(), widgetFactory));
+ IStatus status = initPropertyEditor(descriptor);
+ if(IStatus.ERROR != status.getSeverity()) {
+ getPropertyEditor().createContent(getComposite());
+ } else {
+ Activator.log.error("Could not create the property editor because of initialisation issues.", null);
+ }
+ refreshDisplay();
+ }
+
+ /**
+ * Returns the default label for the property editor
+ *
+ * @return the default label for the property editor
+ */
+ protected abstract String getDefaultLabel();
+
+ /**
+ * Initializes the content of the property editor, in case the property editor contains enumeration or references for example
+ *
+ * @param descriptor
+ * the descriptor of the editor
+ * @return the status of the initialization
+ */
+ protected abstract IStatus initPropertyEditor(IPropertyEditorDescriptor descriptor);
+
+ /**
+ * {@inheritDoc}
+ */
+ public abstract IStatus initController(Composite parent, List<Object> objectsToEdit, IPropertyEditorControllerDescriptor descriptor);
+
+ /**
+ * Sets the value of the property in the model
+ *
+ * @param value
+ * the value to set
+ */
+ protected abstract void setValueInModel(Object value);
+
+ /**
+ * Returns the value currently in the property editor
+ *
+ * @return the current value in the property editor
+ */
+ protected Object getEditorValue() {
+ if(isValid(getPropertyEditor())) {
+ return getPropertyEditor().getValue();
+ }
+ return null;
+ }
+
+ /**
+ * Check if the proeprty editor is valid
+ *
+ * @param propertyEditor
+ * the editor to check
+ * @return <code>true</code> if the editor is not <code>null</code> and not disposed
+ */
+ protected boolean isValid(AbstractPropertyEditor propertyEditor) {
+ return getPropertyEditor() != null && !getPropertyEditor().isDisposed();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void refreshDisplay() {
+ if(isValid(getPropertyEditor())) {
+ getPropertyEditor().setValue(getValueToEdit());
+ }
+ }
+
+ /**
+ * Returns the value of the property to edit, found in the model
+ *
+ * @return the value of the property to edit
+ */
+ protected abstract Object getValueToEdit();
+
+ /**
+ * Adds listener in the model to have notification when the model changes and that the editor should be updated
+ */
+ protected abstract void addListenersToModel();
+
+ /**
+ * Removes listener in the model to have notification when the model changes. It should be the mirror of {@link #addListenersToModel()}
+ */
+ protected abstract void removeListenersFromModel();
+
+ /**
+ * Performs the action of updating the model.
+ */
+ public abstract void updateModel();
+
+ /**
+ * {@inheritDoc}
+ */
+ public void dispose() {
+ // remove added listeners
+ removeListenersFromModel();
+
+ // dispose the composite created by the property editor
+ if(getPropertyEditor() != null) {
+ getPropertyEditor().dispose();
+ }
+ setPropertyEditor(null);
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/PropertyEditorControllerConfiguration.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/PropertyEditorControllerConfiguration.java
new file mode 100644
index 00000000000..2ab2f446766
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/PropertyEditorControllerConfiguration.java
@@ -0,0 +1,182 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IPropertyEditorControllerDescriptor;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IPropertyEditorControllerDescriptorFactory;
+import org.osgi.framework.Bundle;
+import org.w3c.dom.Node;
+
+/**
+ * Class that contains the information about a specific controller
+ */
+public class PropertyEditorControllerConfiguration {
+
+ /** description of the editor */
+ protected String description;
+
+ /** Image descriptor of the editor */
+ protected ImageDescriptor descriptor;
+
+ /** identifier of this extension point */
+ protected String id;
+
+ /** configuration element that manages this editor */
+ protected IConfigurationElement element;
+
+ /** factory used to create controller descriptors */
+ private IPropertyEditorControllerDescriptorFactory factory;
+
+ /**
+ * Sets the element that configures the editor
+ *
+ * @param element
+ * the element to set
+ */
+ protected void setElement(IConfigurationElement element) {
+ this.element = element;
+ }
+
+ /**
+ * Returns the element that configures the editor
+ *
+ * @return the element that configures the editor
+ */
+ protected IConfigurationElement getElement() {
+ return element;
+ }
+
+ /**
+ * Returns the description of the editor
+ *
+ * @return the description of the editor
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Sets the description of this editor
+ *
+ * @param description
+ * the description to set
+ */
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+ /**
+ * Returns the image descriptor of the preview of the editor
+ *
+ * @return the image descriptor of the preview of the editor
+ */
+ public ImageDescriptor getDescriptor() {
+ return descriptor;
+ }
+
+ /**
+ * Sets the image descriptor of the editor preview
+ *
+ * @param descriptor
+ * the descriptor to set
+ */
+ public void setDescriptor(ImageDescriptor descriptor) {
+ this.descriptor = descriptor;
+ }
+
+
+ /**
+ * parses the configuration element and returns an editor configuration
+ *
+ * @param element
+ * the configuration element to parse
+ * @return the created editor configuration
+ * @throws CoreException
+ * the validator was not successfully initialized
+ */
+ public static PropertyEditorControllerConfiguration parse(IConfigurationElement element) throws CoreException {
+ PropertyEditorControllerConfiguration configuration = new PropertyEditorControllerConfiguration();
+
+ // init the id
+ configuration.setId(element.getAttribute("id"));
+
+ // description
+ configuration.setDescription(element.getAttribute("description"));
+
+ // sets the configuration that configures this editor
+ configuration.setElement(element);
+
+ configuration.setDescriptorFactory((IPropertyEditorControllerDescriptorFactory)element.createExecutableExtension("factory"));
+
+ // check everything is valid
+ assert configuration.getId() != null : "impossible to get the identifier for the provider " + element.getName();
+
+ return configuration;
+ }
+
+ /**
+ * Sets the factory used to create descriptors
+ *
+ * @param factory
+ * the factory used to create descriptors
+ */
+ public void setDescriptorFactory(IPropertyEditorControllerDescriptorFactory factory) {
+ assert (factory != null) : "factory should not be null for configuration " + getId();
+ this.factory = factory;
+ }
+
+ /**
+ * Sets the identifier for this configuration
+ *
+ * @param id
+ * the id to set
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+ /**
+ * Returns the id of this configuration
+ *
+ * @return the id of this configuration
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Instantiates the controller.
+ *
+ * @return the controller instantiated
+ * @throws CoreException
+ * exception thrown when something went wrong during creation of the controller
+ */
+ public PropertyEditorController instanciateController() throws CoreException {
+ return (PropertyEditorController)getElement().createExecutableExtension("class");
+ }
+
+ /**
+ * Generates the descriptor for the given configuration node
+ *
+ * @param controllerNode
+ * the configuration node of the controller
+ * @param bundle
+ * the bundle used to load classes
+ * @return the configured descriptor
+ */
+ public IPropertyEditorControllerDescriptor createControllerDescriptor(Node controllerNode, Bundle bundle) {
+ return factory.createDescriptor(controllerNode, bundle);
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/PropertyEditorControllerProvider.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/PropertyEditorControllerProvider.java
new file mode 100644
index 00000000000..b305e200b9a
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/PropertyEditorControllerProvider.java
@@ -0,0 +1,122 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.gmf.runtime.common.core.service.AbstractProvider;
+import org.eclipse.gmf.runtime.common.core.service.IOperation;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IPropertyEditorControllerDescriptor;
+import org.osgi.framework.Bundle;
+import org.w3c.dom.Node;
+
+/**
+ * Provider for property editors
+ */
+public class PropertyEditorControllerProvider extends AbstractProvider {
+
+ /** map that stores the mapping id -> editor class */
+ private Map<String, PropertyEditorControllerConfiguration> controllers = new HashMap<String, PropertyEditorControllerConfiguration>();
+
+ private Bundle bundle;
+
+ /**
+ * Creates the property editor managed by this provider
+ *
+ * @param controllerIdentifier
+ * identifier of the controller
+ *
+ * @return the property editor managed by this provider
+ */
+ public IPropertyEditorController createPropertyEditorController(String controllerIdentifier) {
+ // retrieve property class managed by this provider
+ try {
+ PropertyEditorControllerConfiguration configuration = controllers.get(controllerIdentifier);
+ if(configuration == null) {
+ Activator.log.error("impossible to find the configuration for controller " + controllerIdentifier, null);
+ return null;
+ }
+ Object controller = configuration.instanciateController();
+ return (IPropertyEditorController)controller;
+ } catch (CoreException e) {
+ e.printStackTrace();
+ Activator.log.error(e);
+ }
+ return null;
+ }
+
+ /**
+ * Configures the provider, given the {@link IConfigurationElement}
+ *
+ * @param providerConfiguration
+ * the configuration element from the xml plugin file
+ */
+ public void configure(IConfigurationElement providerConfiguration) {
+ try {
+ bundle = Platform.getBundle(providerConfiguration.getContributor().getName());
+
+ // for each property editors defined in the provider, retrieves important information
+ for(IConfigurationElement element : providerConfiguration.getChildren()) {
+ // check this child is really configuring editors (not a Priority child...)
+ if("PropertyEditorController".equals(element.getName())) {
+ // parse this editor configuration
+ PropertyEditorControllerConfiguration configuration = PropertyEditorControllerConfiguration.parse(element);
+ controllers.put(configuration.getId(), configuration);
+ }
+ }
+ } catch (CoreException e) {
+ e.printStackTrace();
+ Activator.log.error(e);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean provides(IOperation operation) {
+ if(operation instanceof CreatePropertyEditorControllerOperation) {
+ CreatePropertyEditorControllerOperation createPropertyEditorOperation = (CreatePropertyEditorControllerOperation)operation;
+
+ // test if the configuration corresponds to the feature or the id of the operation
+ // first test the id (specific editor)
+ // then test the feature
+
+ String operationIdentifier = createPropertyEditorOperation.getControllerIdentifier();
+ return controllers.containsKey(operationIdentifier);
+ }
+ if(operation instanceof CreatePropertyEditorControllerDescriptorOperation) {
+ CreatePropertyEditorControllerDescriptorOperation controllerDescriptorOperation = (CreatePropertyEditorControllerDescriptorOperation)operation;
+ return controllers.containsKey(controllerDescriptorOperation.getControllerID());
+ }
+ return false;
+ }
+
+ /**
+ * Generates the {@link IPropertyEditorControllerDescriptor} that configures the controller
+ *
+ * @param controllerID
+ * the id of the controller to configure
+ * @param contentNode
+ * the content node that configures the controller
+ * @return the created {@link IPropertyEditorControllerDescriptor}
+ */
+ public IPropertyEditorControllerDescriptor generateDescriptor(String controllerID, Node contentNode) {
+ PropertyEditorControllerConfiguration configuration = controllers.get(controllerID);
+ return configuration.createControllerDescriptor(contentNode, bundle);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/PropertyEditorControllerService.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/PropertyEditorControllerService.java
new file mode 100644
index 00000000000..b9732b14a76
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/PropertyEditorControllerService.java
@@ -0,0 +1,196 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.gmf.runtime.common.core.service.ExecutionStrategy;
+import org.eclipse.gmf.runtime.common.core.service.IOperation;
+import org.eclipse.gmf.runtime.common.core.service.IProvider;
+import org.eclipse.gmf.runtime.common.core.service.Service;
+import org.eclipse.gmf.runtime.common.ui.services.util.ActivityFilterProviderDescriptor;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IPropertyEditorControllerDescriptor;
+import org.eclipse.papyrus.properties.runtime.controller.predefined.CreatePredefinedPropertyControllerProviderOperation;
+import org.eclipse.papyrus.properties.runtime.controller.predefined.GetAllPredefinedPropertyEditorControllersOperation;
+import org.eclipse.papyrus.properties.runtime.controller.predefined.PredefinedControllerDescriptor;
+import org.eclipse.papyrus.properties.runtime.controller.predefined.PredefinedPropertyControllerProvider;
+import org.eclipse.swt.widgets.Composite;
+import org.osgi.framework.Bundle;
+import org.w3c.dom.Node;
+
+
+/**
+ * Service to provide property editor controllers.
+ */
+public class PropertyEditorControllerService extends Service {
+
+ /** instance of this service */
+ protected static PropertyEditorControllerService instance;
+
+ /**
+ * Creates a new PropertyEditorControllerService. This constructor is not visible, using singleton pattern.
+ */
+ protected PropertyEditorControllerService() {
+ super();
+ }
+
+ /**
+ * Returns the singleton instance of this service.
+ *
+ * @return the singleton instance of this service
+ */
+ /**
+ * Returns the singleton instance of this service
+ *
+ * @return the singleton instance of this service
+ */
+ public synchronized static PropertyEditorControllerService getInstance() {
+ if(instance == null) {
+ instance = new PropertyEditorControllerService();
+ instance.configureProviders(Activator.ID, "propertyEditorControllerProvider"); //$NON-NLS-1$
+ }
+ return instance;
+ }
+
+ /**
+ * Creates the descriptor that will parse the content of the xml file
+ *
+ * @param controllerId
+ * the id of the configured controller
+ * @param controllerNode
+ * the content node
+ * @param bundle
+ * the bundle used to load classes for the controller
+ * @return the created descriptor
+ */
+ public IPropertyEditorControllerDescriptor createPropertyEditorControllerDescriptor(String controllerId, Node controllerNode, Bundle bundle) {
+ return (IPropertyEditorControllerDescriptor)executeUnique(ExecutionStrategy.REVERSE, new CreatePropertyEditorControllerDescriptorOperation(controllerId, controllerNode, bundle));
+ }
+
+ /**
+ * Creates the descriptor for a predefined controller
+ *
+ * @param predefinedID
+ * the id of the predefined controller
+ * @return the created descriptor
+ */
+ public IPropertyEditorControllerDescriptor createPredefinedControllerDescriptor(String predefinedID) {
+ return (IPropertyEditorControllerDescriptor)executeUnique(ExecutionStrategy.REVERSE, new CreatePredefinedPropertyControllerProviderOperation(predefinedID));
+ }
+
+ /**
+ * Returns the flatten collection of all available predefined controllers
+ *
+ * @return the flatten collection of all available predefined controllers
+ */
+ @SuppressWarnings("unchecked")
+ public Map<String, PredefinedControllerDescriptor> getAllPredefinedControllers() {
+ List<Map<String, PredefinedControllerDescriptor>> predefinedControllers = (List<Map<String, PredefinedControllerDescriptor>>)execute(ExecutionStrategy.REVERSE, new GetAllPredefinedPropertyEditorControllersOperation());
+ Map<String, PredefinedControllerDescriptor> flattenMap = new HashMap<String, PredefinedControllerDescriptor>();
+ for(Map<String, PredefinedControllerDescriptor> subList : predefinedControllers) {
+ flattenMap.putAll(subList);
+ }
+ return flattenMap;
+ }
+
+ /**
+ * Creates the property editor controller
+ *
+ * @param objectsToEdit
+ * list of objects to edit
+ * @param parent
+ * parent of all controls created by the editor
+ * @param descriptor
+ * the controller descriptor that manages the editor
+ * @return the created property editor controller
+ */
+ public PropertyEditorController createPropertyEditorController(List<Object> objectsToEdit, Composite parent, IPropertyEditorControllerDescriptor descriptor) {
+
+ Object result = executeUnique(ExecutionStrategy.REVERSE, new CreatePropertyEditorControllerOperation(descriptor.getControllerID(), objectsToEdit, parent, descriptor));
+ return (PropertyEditorController)result;
+ }
+
+ /**
+ * @see org.eclipse.gmf.runtime.common.core.service.Service#newProviderDescriptor(org.eclipse.core.runtime.IConfigurationElement)
+ */
+ protected Service.ProviderDescriptor newProviderDescriptor(IConfigurationElement element) {
+ return new ProviderDescriptor(element);
+ }
+
+ /**
+ * A descriptor for property editor controller providers defined by a configuration element.
+ */
+ protected static class ProviderDescriptor extends ActivityFilterProviderDescriptor {
+
+ /**
+ * Constructs a <code>ISemanticProvider</code> descriptor for
+ * the specified configuration element.
+ *
+ * @param element
+ * The configuration element describing the provider.
+ */
+ public ProviderDescriptor(IConfigurationElement element) {
+ super(element);
+ }
+
+ /**
+ * @see org.eclipse.gmf.runtime.common.core.service.IProvider#provides(org.eclipse.gmf.runtime.common.core.service.IOperation)
+ */
+ public boolean provides(IOperation operation) {
+ if(!super.provides(operation)) {
+ return false;
+ }
+ if(operation instanceof CreatePropertyEditorControllerOperation) {
+ // test if the configuration corresponds to the feature or the id of the operation
+ return getProvider().provides(operation);
+ }
+
+ if(operation instanceof CreatePredefinedPropertyControllerProviderOperation) {
+ // test if the configuration corresponds to the feature or the id of the operation
+ return getProvider().provides(operation);
+ }
+
+ if(operation instanceof CreatePropertyEditorControllerDescriptorOperation) {
+ return getProvider().provides(operation);
+ }
+
+ if(operation instanceof GetAllPredefinedPropertyEditorControllersOperation) {
+ return getProvider().provides(operation);
+ }
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IProvider getProvider() {
+ if(provider == null) {
+ IProvider newProvider = super.getProvider();
+ if(provider instanceof PropertyEditorControllerProvider) {
+ PropertyEditorControllerProvider defaultProvider = (PropertyEditorControllerProvider)newProvider;
+ defaultProvider.configure(getElement());
+ } else if(provider instanceof PredefinedPropertyControllerProvider) {
+ PredefinedPropertyControllerProvider defaultProvider = (PredefinedPropertyControllerProvider)newProvider;
+ defaultProvider.configure(getElement());
+ }
+ return newProvider;
+ }
+ return super.getProvider();
+ }
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/BeanPropertyEditorControllerDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/BeanPropertyEditorControllerDescriptor.java
new file mode 100644
index 00000000000..2b197ba8983
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/BeanPropertyEditorControllerDescriptor.java
@@ -0,0 +1,121 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller.descriptor;
+
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.constraints.IConstraintDescriptor;
+import org.eclipse.swt.graphics.Image;
+
+/**
+ * Descriptor for controller based on java.beans properties
+ */
+public class BeanPropertyEditorControllerDescriptor implements IPropertyEditorControllerDescriptor {
+
+ /** id of the controller described by this descriptor */
+ private final String controllerID;
+
+ /** indicates if the controller can handle several objects to edit */
+ private final boolean multiSelection;
+
+ /** name of the property to edit */
+ private final String propertyName;
+
+ /** descriptor of the editor managed by the controller */
+ private final IPropertyEditorDescriptor editorDescriptor;
+
+ /** list of constraints applied to this descriptor */
+ private final List<IConstraintDescriptor> constraints;
+
+ /**
+ * Creates a new BeanPropertyEditorControllerDescriptor.
+ *
+ * @param controllerID
+ * id of the controller described by this descriptor
+ * @param multiSelection
+ * <code>true</code> when the controller can handle several objects to edit
+ * @param propertyName
+ * the name of the property to edit
+ * @param editorDescriptor
+ * the descriptor of the editor managed by this controller
+ * @param constraints
+ * list of constraints that should be verified for this descriptor
+ */
+ public BeanPropertyEditorControllerDescriptor(String controllerID, boolean multiSelection, String propertyName, IPropertyEditorDescriptor editorDescriptor, List<IConstraintDescriptor> constraints) {
+ this.controllerID = controllerID;
+ this.multiSelection = multiSelection;
+ this.propertyName = propertyName;
+ this.editorDescriptor = editorDescriptor;
+ this.constraints = constraints;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "Bean controller: " + getControllerID();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return Activator.getImage("/icons/BeanController.gif");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean acceptMultiSelection() {
+ return multiSelection;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getControllerID() {
+ return controllerID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IPropertyEditorDescriptor getEditorDescriptor() {
+ return editorDescriptor;
+ }
+
+ /**
+ * Returns the name of the property to edit
+ *
+ * @return the name of the property to edit
+ */
+ public String getPropertyName() {
+ return propertyName;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<IConstraintDescriptor> getConstraintDescriptors() {
+ return constraints;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ControllerDescriptorState createState(boolean readOnly) {
+ return new ControllerDescriptorState(this, readOnly);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/BeanPropertyEditorControllerDescriptorFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/BeanPropertyEditorControllerDescriptorFactory.java
new file mode 100644
index 00000000000..01e0fa38221
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/BeanPropertyEditorControllerDescriptorFactory.java
@@ -0,0 +1,88 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller.descriptor;
+
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.modelhandler.emf.IEMFModelHandler;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.PropertyEditorService;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.constraints.ConstraintParser;
+import org.eclipse.papyrus.properties.runtime.view.constraints.IConstraintDescriptor;
+import org.osgi.framework.Bundle;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+
+/**
+ * Factory for Property editor controllers based on java.beans properties
+ */
+public class BeanPropertyEditorControllerDescriptorFactory implements IPropertyEditorControllerDescriptorFactory {
+
+ /**
+ * {@inheritDoc}
+ */
+ public IPropertyEditorControllerDescriptor createDescriptor(Node controllerNode, Bundle bundle) {
+ // parse content of the node
+
+ String controllerID = "";
+ boolean multiSelection = true;
+
+ NamedNodeMap attributes = controllerNode.getAttributes();
+ for(int i = 0; i < attributes.getLength(); i++) {
+ Node attribute = attributes.item(i);
+
+ if("id".equals(attribute.getNodeName())) {
+ controllerID = attribute.getNodeValue();
+ }
+ }
+
+ String propertyName = null;
+ IEMFModelHandler modelHandler = null;
+ IPropertyEditorDescriptor editorDescriptor = null;
+ List<IConstraintDescriptor> constraints = null;
+ NodeList children = controllerNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if("property".equals(child.getNodeName())) {
+ // retrieve feature name, handler Id, etc.
+ NamedNodeMap featureAttributes = child.getAttributes();
+ if(featureAttributes != null) {
+ Node featureNameNode = featureAttributes.getNamedItem("name");
+ if(featureNameNode != null) {
+ propertyName = featureNameNode.getNodeValue();
+ }
+
+ // modelHandler = parseModelHandler(child);
+ }
+ } else if("editor".equals(child.getNodeName())) {
+ // retrieve editor id
+ if(child.hasAttributes()) {
+ Node editorIDNode = child.getAttributes().getNamedItem("id");
+ editorDescriptor = PropertyEditorService.getInstance().createPropertyEditorDescriptor(editorIDNode.getNodeValue(), child);
+ }
+ } else if("constraints".equals(child.getNodeName())) {
+ constraints = ConstraintParser.parseConstraints(child, bundle);
+ }
+ }
+
+ assert (modelHandler != null) : "impossible to find handler for controller " + controllerID;
+ assert (propertyName != null && !"".equals(propertyName)) : "impossible to find feature name for controller " + controllerID;
+ assert (editorDescriptor != null) : "impossible to create editor descriptor";
+ assert (constraints != null) : "Impossible to parse constraints";
+
+ return new BeanPropertyEditorControllerDescriptor(controllerID, multiSelection, propertyName, editorDescriptor, constraints);
+ }
+
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/ControllerDescriptorState.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/ControllerDescriptorState.java
new file mode 100644
index 00000000000..9ee1da4313a
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/ControllerDescriptorState.java
@@ -0,0 +1,144 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller.descriptor;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.state.AbstractState;
+import org.eclipse.papyrus.properties.runtime.state.ITraversableModelElement;
+import org.eclipse.swt.widgets.Composite;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+
+/**
+ * State for controller descriptors
+ */
+public class ControllerDescriptorState extends AbstractState {
+
+ /** identifier for the controller descriptor editor dialog */
+ private static final String CONTROLLER_DESCRIPTOR_EDITOR_DLG = "ControllerDescriptorEditorDialog";
+
+ /** descriptor managed by this state */
+ protected IPropertyEditorControllerDescriptor descriptor;
+
+ /** id of the controller managed by this state */
+ protected String id;
+
+ /** change support for this bean */
+ private PropertyChangeSupport changeSupport;
+
+ /**
+ * Creates a new ControllerDescriptorState.
+ *
+ * @param descriptor
+ * descriptor to manage
+ * @param readOnly
+ * the read only mode of this state
+ */
+ public ControllerDescriptorState(IPropertyEditorControllerDescriptor descriptor, boolean readOnly) {
+ super(readOnly);
+ this.descriptor = descriptor;
+ id = descriptor.getControllerID();
+
+ // register change support
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ /**
+ * Returns the descriptor managed by this state
+ *
+ * @return the descriptor managed by this state
+ */
+ public IPropertyEditorControllerDescriptor getDescriptor() {
+ return descriptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEditionDialogId() {
+ return CONTROLLER_DESCRIPTOR_EDITOR_DLG;
+ }
+
+ /**
+ * Sets the id of the controller managed by this state
+ *
+ * @param id
+ * the id to set
+ */
+ public void setId(String id) {
+ String oldId = this.id;
+ this.id = id;
+
+ changeSupport.firePropertyChange("id", oldId, id);
+ }
+
+ /**
+ * Returns the id of the controller managed by this state
+ *
+ * @return the id of the controller managed by this state
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Adds a property change listener to this class
+ *
+ * @param listener
+ * the listener to add
+ */
+ public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * Removes a property change listener from this class
+ *
+ * @param listener
+ * the listener to remove
+ */
+ public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<? extends ITraversableModelElement> getChildren() {
+ return Collections.emptyList();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node generateNode(Document document) {
+ // should be subclassed...
+ Activator.log.error("not implemented", null);
+ return null;
+ }
+
+ /**
+ * Generates the preview for this controller
+ *
+ * @param composite
+ * the parent composite where to create the view for this controller
+ */
+ public void createPreview(Composite composite) {
+ Activator.log.error("not implements...", null);
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/EMFTBindingPropertyEditorControllerDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/EMFTBindingPropertyEditorControllerDescriptor.java
new file mode 100644
index 00000000000..466b1c67407
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/EMFTBindingPropertyEditorControllerDescriptor.java
@@ -0,0 +1,118 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller.descriptor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.modelhandler.emf.IEMFModelHandler;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.constraints.IConstraintDescriptor;
+import org.eclipse.uml2.uml.StructuralFeature;
+
+/**
+ * Basic configuration for property editor controllers
+ */
+public class EMFTBindingPropertyEditorControllerDescriptor extends EMFTPropertyEditorControllerDescriptor implements IBindingLabelProviderDescriptor {
+
+ /** message to bind */
+ private String message;
+
+ /** name of the features to bind */
+ private String[] featuresName;
+
+ /**
+ * Creates a new EMFTBindingPropertyEditorControllerDescriptor.
+ *
+ * @param controllerID
+ * the id of the controller
+ * @param multiSelection
+ * indicates if the controller accepts multi-selection
+ * @param featureNameToEdit
+ * name of the features to edit
+ * @param handler
+ * model handler used to interact with the model
+ * @param editorDescriptor
+ * descriptor of the editor
+ * @param constraints
+ * the list of constraints for this descriptor
+ * @param message
+ * message to bind
+ * @param featuresName
+ * names of the features to bind
+ */
+ public EMFTBindingPropertyEditorControllerDescriptor(String controllerID, boolean multiSelection, String featureNameToEdit, IEMFModelHandler handler, IPropertyEditorDescriptor editorDescriptor, List<IConstraintDescriptor> constraints, String message, String[] featuresName) {
+ super(controllerID, multiSelection, featureNameToEdit, handler, editorDescriptor, constraints);
+ this.message = message;
+ this.featuresName = featuresName;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getMessage() {
+ return message;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String[] getFeaturesNameToBind() {
+ return featuresName;
+ }
+
+ /**
+ * computes bindings from the given descriptor
+ *
+ * @param objectToEdit
+ * the object to edit
+ * @return the list of values to bind
+ */
+ public String computeBindings(Object objectToEdit) {
+ List<Object> bindings = new ArrayList<Object>();
+
+ if(objectToEdit instanceof EObject) {
+ for(String name : getFeaturesNameToBind()) {
+ EStructuralFeature feature = getFeatureByName(((EObject)objectToEdit), name);
+ if(feature != null) {
+ Object value = ((EObject)objectToEdit).eGet(feature);
+ bindings.add(value);
+ } else {
+ Activator.log.error("impossible to find the feature with name : " + name, null);
+ }
+ }
+ }
+
+ return NLS.bind(getMessage(), bindings.toArray(new String[]{}));
+ }
+
+ /**
+ * Returns the feature given its name
+ *
+ * @param objectToEdit
+ * the object to edit
+ * @param name
+ * the name of the feature to find
+ * @return the {@link StructuralFeature} found
+ */
+ protected EStructuralFeature getFeatureByName(EObject objectToEdit, String name) {
+ EStructuralFeature feature = objectToEdit.eClass().getEStructuralFeature(name);
+ if(feature != null) {
+ return feature;
+ }
+ return null;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/EMFTBindingPropertyEditorControllerDescriptorFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/EMFTBindingPropertyEditorControllerDescriptorFactory.java
new file mode 100644
index 00000000000..b8f3f2d9d83
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/EMFTBindingPropertyEditorControllerDescriptorFactory.java
@@ -0,0 +1,113 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller.descriptor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.modelhandler.emf.IEMFModelHandler;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.PropertyEditorService;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.constraints.ConstraintParser;
+import org.eclipse.papyrus.properties.runtime.view.constraints.IConstraintDescriptor;
+import org.osgi.framework.Bundle;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+
+/**
+ * Factory that creates the configuration for the EMFTPropertyEditorController.
+ */
+public class EMFTBindingPropertyEditorControllerDescriptorFactory extends EMFTPropertyEditorControllerDescriptorFactory {
+
+ /** message to bind */
+ private String message;
+
+ /** name of the features */
+ private List<String> featuresName = new ArrayList<String>();
+
+ /**
+ * Creates a new EMFTPropertyEditorControllerDescriptorFactory.
+ */
+ public EMFTBindingPropertyEditorControllerDescriptorFactory() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public EMFTPropertyEditorControllerDescriptor createDescriptor(Node controllerNode, Bundle bundle) {
+ // parse content of the node
+
+ String controllerID = "";
+ boolean multiSelection = true;
+
+ NamedNodeMap attributes = controllerNode.getAttributes();
+ for(int i = 0; i < attributes.getLength(); i++) {
+ Node attribute = attributes.item(i);
+
+ if("id".equals(attribute.getNodeName())) {
+ controllerID = attribute.getNodeValue();
+ }
+ }
+
+ IEMFModelHandler modelHandler = null;
+ String featureName = null;
+ IPropertyEditorDescriptor editorDescriptor = null;
+ List<IConstraintDescriptor> constraints = null;
+ NodeList children = controllerNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if("feature".equals(child.getNodeName())) {
+ // retrieve feature name, handler Id, etc.
+ NamedNodeMap featureAttributes = child.getAttributes();
+ if(featureAttributes != null) {
+ Node featureNameNode = featureAttributes.getNamedItem("name");
+ if(featureNameNode != null) {
+ featureName = featureNameNode.getNodeValue();
+ }
+
+ modelHandler = parseModelHandler(child);
+ }
+ } else if("editor".equals(child.getNodeName())) {
+ // retrieve editor id
+ if(child.hasAttributes()) {
+ Node editorIDNode = child.getAttributes().getNamedItem("id");
+ editorDescriptor = PropertyEditorService.getInstance().createPropertyEditorDescriptor(editorIDNode.getNodeValue(), child);
+ }
+ } else if("binding".equals(child.getNodeName())) {
+ if(child.hasAttributes()) {
+ Node messageNode = child.getAttributes().getNamedItem("message");
+ message = messageNode.getNodeValue();
+ }
+ NodeList features = child.getChildNodes();
+ for(int j = 0; j < features.getLength(); j++) {
+ Node featureNode = features.item(j);
+ if("feature".equals(featureNode.getNodeName())) {
+ if(featureNode.hasAttributes()) {
+ featuresName.add(featureNode.getAttributes().getNamedItem("name").getNodeValue());
+ }
+ }
+ }
+ } else if("constraints".equals(child.getNodeName())) {
+ constraints = ConstraintParser.parseConstraints(child, bundle);
+ }
+ }
+
+ assert (modelHandler != null) : "impossible to find handler for controller " + controllerID;
+ assert (featureName != null && !"".equals(featureName)) : "impossible to find feature name for controller " + controllerID;
+ assert (editorDescriptor != null) : "impossible to create editor descriptor";
+ assert (constraints != null) : "Impossible to parse constraints";
+
+ return new EMFTBindingPropertyEditorControllerDescriptor(controllerID, multiSelection, featureName, modelHandler, editorDescriptor, constraints, message, featuresName.toArray(new String[]{}));
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/EMFTPropertyEditorControllerDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/EMFTPropertyEditorControllerDescriptor.java
new file mode 100644
index 00000000000..858fe8b4e2b
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/EMFTPropertyEditorControllerDescriptor.java
@@ -0,0 +1,338 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller.descriptor;
+
+import java.beans.PropertyChangeSupport;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.PropertyEditorController;
+import org.eclipse.papyrus.properties.runtime.controller.PropertyEditorControllerService;
+import org.eclipse.papyrus.properties.runtime.modelhandler.emf.IEMFModelHandler;
+import org.eclipse.papyrus.properties.runtime.modelhandler.emf.IEMFModelHandlerState;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.papyrus.properties.runtime.state.IState;
+import org.eclipse.papyrus.properties.runtime.state.ITraversableModelElement;
+import org.eclipse.papyrus.properties.runtime.view.constraints.IConstraintDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Basic configuration for property editor controllers
+ */
+public class EMFTPropertyEditorControllerDescriptor implements IPropertyEditorControllerDescriptor {
+
+ /** handler used by this controller */
+ protected final IEMFModelHandler handler;
+
+ /** boolean that indicates if the controller accepts multi selection */
+ protected final boolean multiSelection;
+
+ /** controller unique identifier */
+ protected final String controllerID;
+
+ /** name of the feature to edit */
+ protected final String featureNameToEdit;
+
+ /** editor descriptor */
+ protected final IPropertyEditorDescriptor editorDescriptor;
+
+ /** list of constraints for this descriptors */
+ private final List<IConstraintDescriptor> constraints;
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean acceptMultiSelection() {
+ return multiSelection;
+ }
+
+ /**
+ * Returns the name of the feature to edit
+ *
+ * @return the name of the feature to edit
+ */
+ public String getFeatureNameToEdit() {
+ return featureNameToEdit;
+ }
+
+ /**
+ * Returns the handler id for the controller
+ *
+ * @return the handler id for the controller
+ */
+ public IEMFModelHandler getHandler() {
+ return handler;
+ }
+
+ /**
+ * Creates a new PropertyEditorDescriptor.
+ *
+ * @param controllerID
+ * id of the controller described by this element
+ * @param multiSelection
+ * boolean that indicates if the controller described accepts multi-selection
+ * @param featureNameToEdit
+ * the name of feature to edit for the controller configured by this descriptor
+ * @param handler
+ * the handler id for the controller
+ * @param editorDescriptor
+ * descriptor of the editor managed by this controller
+ * @param constraints
+ * list of constraints applying on this descriptor
+ */
+ public EMFTPropertyEditorControllerDescriptor(String controllerID, boolean multiSelection, String featureNameToEdit, IEMFModelHandler handler, IPropertyEditorDescriptor editorDescriptor, List<IConstraintDescriptor> constraints) {
+ this.controllerID = controllerID;
+ this.multiSelection = multiSelection;
+ this.featureNameToEdit = featureNameToEdit;
+ this.handler = handler;
+ this.editorDescriptor = editorDescriptor;
+ this.constraints = constraints;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getControllerID() {
+ return controllerID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IPropertyEditorDescriptor getEditorDescriptor() {
+ return editorDescriptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<IConstraintDescriptor> getConstraintDescriptors() {
+ return constraints;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return Activator.getImage("/icons/EMFTController.gif"); //$NON-NLS-1$
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "Property editor for: " + getFeatureNameToEdit();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ControllerDescriptorState createState(boolean readOnly) {
+ return new EMFTPropertyEditorControllerDescriptorState(this, readOnly);
+ }
+
+ /**
+ * state for {@link EMFTPropertyEditorControllerDescriptor}
+ */
+ public class EMFTPropertyEditorControllerDescriptorState extends ControllerDescriptorState {
+
+ /** change support for this bean */
+ private PropertyChangeSupport changeSupport;
+
+ /** state for the feature name */
+ private String featureNameState;
+
+ /** model handler state */
+ private IEMFModelHandlerState modelHandlerState;
+
+ /** multi selection state */
+ private boolean multiSelectionState;
+
+ /** state of the editor */
+ private IState editorState;
+
+ /**
+ * Creates a new EMFTPropertyEditorControllerDescriptorState.
+ *
+ * @param descriptor
+ * descriptor to manage
+ * @param readOnly
+ * the read only mode of this state
+ */
+ public EMFTPropertyEditorControllerDescriptorState(EMFTPropertyEditorControllerDescriptor descriptor, boolean readOnly) {
+ super(descriptor, readOnly);
+ featureNameState = descriptor.getFeatureNameToEdit();
+ multiSelectionState = descriptor.acceptMultiSelection();
+ modelHandlerState = descriptor.getHandler().createState(true); // read only element
+ editorState = descriptor.getEditorDescriptor().createState(readOnly);
+ // register change support
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public EMFTPropertyEditorControllerDescriptor getDescriptor() {
+ return (EMFTPropertyEditorControllerDescriptor)super.getDescriptor();
+ }
+
+
+ /**
+ * Returns the changeSupport for this state
+ *
+ * @return the changeSupport for this state
+ */
+ public PropertyChangeSupport getChangeSupport() {
+ return changeSupport;
+ }
+
+ /**
+ * Sets the changeSupport for this state
+ *
+ * @param changeSupport
+ * the changeSupport to set
+ */
+ public void setChangeSupport(PropertyChangeSupport changeSupport) {
+ this.changeSupport = changeSupport;
+ }
+
+ /**
+ * Returns the featureNameState for this state
+ *
+ * @return the featureNameState for this state
+ */
+ public String getFeatureNameState() {
+ return featureNameState;
+ }
+
+ /**
+ * Sets the featureNameState for this state
+ *
+ * @param featureNameState
+ * the featureNameState to set
+ */
+ public void setFeatureNameState(String featureNameState) {
+ String oldName = this.featureNameState;
+ this.featureNameState = featureNameState;
+
+ changeSupport.firePropertyChange("featureNameState", oldName, this.featureNameState);
+ }
+
+ /**
+ * Returns the modelHandler for this state
+ *
+ * @return the modelHandler for this state
+ */
+ public IEMFModelHandlerState getModelHandlerState() {
+ return modelHandlerState;
+ }
+
+ /**
+ * Sets the modelHandler for this state
+ *
+ * @param modelHandlerState
+ * the modelHandler to set
+ */
+ public void setModelHandler(IEMFModelHandlerState modelHandlerState) {
+ IEMFModelHandlerState oldHandlerState = this.modelHandlerState;
+ this.modelHandlerState = modelHandlerState;
+
+ changeSupport.firePropertyChange("modelHandler", oldHandlerState, this.modelHandlerState);
+ }
+
+ /**
+ * Returns the multiSelection for this state
+ *
+ * @return the multiSelection for this state
+ */
+ public boolean isMultiSelection() {
+ return multiSelection;
+ }
+
+ /**
+ * Sets the multiSelection for this state
+ *
+ * @param multiSelectionState
+ * the multiSelection to set
+ */
+ public void setMultiSelection(boolean multiSelectionState) {
+ boolean oldSelection = this.multiSelectionState;
+ this.multiSelectionState = multiSelectionState;
+ changeSupport.firePropertyChange("multiSelection", oldSelection, this.multiSelectionState);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<? extends ITraversableModelElement> getChildren() {
+ List<ITraversableModelElement> children = new ArrayList<ITraversableModelElement>(1);
+ children.add(modelHandlerState);
+ return children;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Node generateNode(Document document) {
+ Element node = document.createElement("controller");
+ node.setAttribute("id", getId());
+
+ // <controller id="emftStructuralFeatureController">
+ // <feature name="qualifiedName" handlerID="String"/>
+ // <editor id="org.eclipse.papyrus.properties.runtime.textPropertyEditor" label="Qualified Name:" labelPosition="16384">
+ // <icon pluginID="org.eclipse.papyrus.properties.tabbed.uml" path="/icons/tool.gif"/>
+ // </editor>
+ // </controller>
+
+ node.appendChild(modelHandlerState.generateNode(document));
+
+ generateEditorNode(node, document);
+ return node;
+ }
+
+ /**
+ * Generates the editor node for the controller
+ *
+ * @param node
+ * the parent node for generated nodes
+ * @param document
+ * the document used to create elements
+ */
+ protected void generateEditorNode(Element node, Document document) {
+ Node editorNode = editorState.generateNode(document);
+ node.appendChild(editorNode);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void createPreview(org.eclipse.swt.widgets.Composite composite) {
+ PropertyEditorController controller = PropertyEditorControllerService.getInstance().createPropertyEditorController(Collections.emptyList(), composite, descriptor);
+
+ if(controller != null) {
+ // use the state to create this
+ controller.createPropertyEditor(this.getDescriptor().getEditorDescriptor(), new TabbedPropertySheetWidgetFactory());
+ }
+ }
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/EMFTPropertyEditorControllerDescriptorFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/EMFTPropertyEditorControllerDescriptorFactory.java
new file mode 100644
index 00000000000..461a9f77a01
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/EMFTPropertyEditorControllerDescriptorFactory.java
@@ -0,0 +1,127 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller.descriptor;
+
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.modelhandler.ModelHandlerService;
+import org.eclipse.papyrus.properties.runtime.modelhandler.emf.IEMFModelHandler;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.PropertyEditorService;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.constraints.ConstraintParser;
+import org.eclipse.papyrus.properties.runtime.view.constraints.IConstraintDescriptor;
+import org.osgi.framework.Bundle;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+
+/**
+ * Factory that creates the configuration for the EMFTPropertyEditorController.
+ */
+public class EMFTPropertyEditorControllerDescriptorFactory implements IPropertyEditorControllerDescriptorFactory {
+
+
+ /**
+ * Creates a new EMFTPropertyEditorControllerDescriptorFactory.
+ */
+ public EMFTPropertyEditorControllerDescriptorFactory() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public EMFTPropertyEditorControllerDescriptor createDescriptor(Node controllerNode, Bundle bundle) {
+ // parse content of the node
+
+ String controllerID = "";
+ boolean multiSelection = true;
+
+ NamedNodeMap attributes = controllerNode.getAttributes();
+ for(int i = 0; i < attributes.getLength(); i++) {
+ Node attribute = attributes.item(i);
+
+ if("id".equals(attribute.getNodeName())) {
+ controllerID = attribute.getNodeValue();
+ }
+ }
+
+ String featureName = null;
+ IEMFModelHandler modelHandler = null;
+ IPropertyEditorDescriptor editorDescriptor = null;
+ List<IConstraintDescriptor> constraints = null;
+ NodeList children = controllerNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if("feature".equals(child.getNodeName())) {
+ // retrieve feature name, handler Id, etc.
+ NamedNodeMap featureAttributes = child.getAttributes();
+ if(featureAttributes != null) {
+ Node featureNameNode = featureAttributes.getNamedItem("name");
+ if(featureNameNode != null) {
+ featureName = featureNameNode.getNodeValue();
+ }
+
+ modelHandler = parseModelHandler(child);
+ }
+ } else if("editor".equals(child.getNodeName())) {
+ // retrieve editor id
+ if(child.hasAttributes()) {
+ Node editorIDNode = child.getAttributes().getNamedItem("id");
+ editorDescriptor = PropertyEditorService.getInstance().createPropertyEditorDescriptor(editorIDNode.getNodeValue(), child);
+ if(editorDescriptor == null) {
+ Activator.log.error("impossible to create editor descriptor", null);
+ }
+ }
+
+ } else if("constraints".equals(child.getNodeName())) {
+ constraints = ConstraintParser.parseConstraints(child, bundle);
+ }
+ }
+
+ assert (modelHandler != null) : "impossible to find handler for controller " + controllerID;
+ assert (featureName != null && !"".equals(featureName)) : "impossible to find feature name for controller " + controllerID;
+ assert (constraints != null) : "Impossible to parse constraints";
+
+ return new EMFTPropertyEditorControllerDescriptor(controllerID, multiSelection, featureName, modelHandler, editorDescriptor, constraints);
+ }
+
+ /**
+ * Parses the feature node to retrieve the right model handler
+ *
+ * @param node
+ * the feature node
+ * @return the model handler created
+ */
+ protected IEMFModelHandler parseModelHandler(Node node) {
+ String handlerID = null;
+ NamedNodeMap featureAttributes = node.getAttributes();
+ if(featureAttributes != null) {
+ // retrieve handler id
+ Node handlerIDNameNode = featureAttributes.getNamedItem("handlerID");
+ if(handlerIDNameNode != null) {
+ handlerID = handlerIDNameNode.getNodeValue();
+ }
+ }
+
+ // check found handler id
+ if(handlerID == null) {
+ Activator.log.error("impossible to find model handler for node " + node, null);
+ return null;
+ }
+
+ Object modelHandler = ModelHandlerService.getInstance().createModelHandler(handlerID, node);
+ return (modelHandler instanceof IEMFModelHandler) ? (IEMFModelHandler)modelHandler : null;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/IBindingLabelProviderDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/IBindingLabelProviderDescriptor.java
new file mode 100644
index 00000000000..0ef556d1fca
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/IBindingLabelProviderDescriptor.java
@@ -0,0 +1,44 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller.descriptor;
+
+
+
+/**
+ * Descriptors for controllers that provides message binding facilities
+ */
+public interface IBindingLabelProviderDescriptor {
+
+ /**
+ * returns the message to bind
+ *
+ * @return the message to bind
+ */
+ public String getMessage();
+
+ /**
+ * Returns the ordered list of feature names that are binded
+ *
+ * @return the ordered list of feature names that are binded
+ */
+ public String[] getFeaturesNameToBind();
+
+ /**
+ * Computes the result of the binding for the given set of objects
+ *
+ * @param objectToEdit
+ * the object to edit
+ * @return the string result of the binding
+ */
+ public String computeBindings(Object objectToEdit);
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/IPropertyEditorControllerDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/IPropertyEditorControllerDescriptor.java
new file mode 100644
index 00000000000..09e31d19d3a
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/IPropertyEditorControllerDescriptor.java
@@ -0,0 +1,65 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller.descriptor;
+
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.IConfigurableDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.constraints.IConstraintDescriptor;
+
+
+/**
+ * interface for all property editor controllers
+ */
+public interface IPropertyEditorControllerDescriptor extends IConfigurableDescriptor {
+
+ /**
+ * Indicates if the controller accepts multi selection
+ *
+ * @return <code>true</code> if the controller accepts multi-selection
+ */
+ public boolean acceptMultiSelection();
+
+ /**
+ * Returns the unique identifier of the controller described by this element
+ *
+ * @return the unique identifier of the controller described by this element
+ */
+ public String getControllerID();
+
+ /**
+ * Returns the editor descriptor for this controller
+ *
+ * @return the editor descriptor for this controller
+ */
+ public IPropertyEditorDescriptor getEditorDescriptor();
+
+ /**
+ * Returns the list of constraints for this descriptor
+ *
+ * @return the list of constraints for this descriptor
+ */
+ public List<IConstraintDescriptor> getConstraintDescriptors();
+
+ /**
+ * {@inheritDoc}
+ */
+ public ControllerDescriptorState createState(boolean readOnly);
+
+ // /**
+ // * Returns the predefined id of the described controller
+ // *
+ // * @return the predefined id of the described controller
+ // */
+ // public String getPredefinedId();
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/IPropertyEditorControllerDescriptorFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/IPropertyEditorControllerDescriptorFactory.java
new file mode 100644
index 00000000000..9ef3dda479b
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/IPropertyEditorControllerDescriptorFactory.java
@@ -0,0 +1,33 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller.descriptor;
+
+import org.osgi.framework.Bundle;
+import org.w3c.dom.Node;
+
+
+/**
+ * factory for {@link IPropertyEditorControllerDescriptor}
+ */
+public interface IPropertyEditorControllerDescriptorFactory {
+
+ /**
+ * Creates the descriptor for the given configuration
+ *
+ * @param controllerNode
+ * the configuration node
+ * @param bundle
+ * the bundle used to load classes for the created controller
+ * @return a configured {@link IPropertyEditorControllerDescriptor}
+ */
+ IPropertyEditorControllerDescriptor createDescriptor(Node controllerNode, Bundle bundle);
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/NullPropertyEditorControllerDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/NullPropertyEditorControllerDescriptor.java
new file mode 100644
index 00000000000..9d50b6b9f78
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/NullPropertyEditorControllerDescriptor.java
@@ -0,0 +1,91 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller.descriptor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.controller.NullPropertyEditorController;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.constraints.IConstraintDescriptor;
+import org.eclipse.swt.graphics.Image;
+
+
+/**
+ * Descriptor for {@link NullPropertyEditorController}
+ */
+public class NullPropertyEditorControllerDescriptor implements IPropertyEditorControllerDescriptor {
+
+ /** editor descriptor */
+ protected final IPropertyEditorDescriptor editorDescriptor;
+
+
+ /**
+ * Creates a new NullPropertyEditorControllerDescriptor.
+ *
+ * @param editorDescriptor
+ * the descriptor of the editor controller
+ */
+ public NullPropertyEditorControllerDescriptor(IPropertyEditorDescriptor editorDescriptor) {
+ this.editorDescriptor = editorDescriptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "NullController";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean acceptMultiSelection() {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getControllerID() {
+ return NullPropertyEditorController.ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IPropertyEditorDescriptor getEditorDescriptor() {
+ return editorDescriptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<IConstraintDescriptor> getConstraintDescriptors() {
+ return new ArrayList<IConstraintDescriptor>();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ControllerDescriptorState createState(boolean readOnly) {
+ return new ControllerDescriptorState(this, readOnly);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/NullPropertyEditorControllerDescriptorFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/NullPropertyEditorControllerDescriptorFactory.java
new file mode 100644
index 00000000000..8ce934a2474
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/descriptor/NullPropertyEditorControllerDescriptorFactory.java
@@ -0,0 +1,52 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller.descriptor;
+
+import org.eclipse.papyrus.properties.runtime.controller.NullPropertyEditorController;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.PropertyEditorService;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.osgi.framework.Bundle;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+
+/**
+ * Factory for {@link NullPropertyEditorController}.
+ */
+public class NullPropertyEditorControllerDescriptorFactory implements IPropertyEditorControllerDescriptorFactory {
+
+ /**
+ * {@inheritDoc}
+ */
+ public IPropertyEditorControllerDescriptor createDescriptor(Node controllerNode, Bundle bundle) {
+ // parse content of the node
+
+ IPropertyEditorDescriptor editorDescriptor = null;
+ NodeList children = controllerNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if("editor".equals(child.getNodeName())) {
+ // retrieve editor id
+ if(child.hasAttributes()) {
+ Node editorIDNode = child.getAttributes().getNamedItem("id");
+ editorDescriptor = PropertyEditorService.getInstance().createPropertyEditorDescriptor(editorIDNode.getNodeValue(), child);
+ }
+
+ }
+ }
+
+ assert (editorDescriptor != null) : "impossible to create editor descriptor";
+
+ return new NullPropertyEditorControllerDescriptor(editorDescriptor);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/predefined/CreatePredefinedPropertyControllerProviderOperation.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/predefined/CreatePredefinedPropertyControllerProviderOperation.java
new file mode 100644
index 00000000000..9b03b6ebef6
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/predefined/CreatePredefinedPropertyControllerProviderOperation.java
@@ -0,0 +1,56 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller.predefined;
+
+import org.eclipse.gmf.runtime.common.core.service.IOperation;
+import org.eclipse.gmf.runtime.common.core.service.IProvider;
+
+
+/**
+ * Operation that retrieves a predefined property editor controller
+ */
+public class CreatePredefinedPropertyControllerProviderOperation implements IOperation {
+
+ /** identifier of the controller to retrieve */
+ private final String predefinedID;
+
+ /**
+ * Creates a new CreatePredefinedPropertyControllerProviderOperation.
+ *
+ * @param predefinedID
+ * id of the controller to retrieve
+ *
+ */
+ public CreatePredefinedPropertyControllerProviderOperation(String predefinedID) {
+ this.predefinedID = predefinedID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object execute(IProvider provider) {
+ if(provider instanceof PredefinedPropertyControllerProvider) {
+ return ((PredefinedPropertyControllerProvider)provider).retrievePropertyEditorControllerDescriptor(getPredefinedID());
+ }
+ return null;
+ }
+
+ /**
+ * Returns the identifier of the controller to create
+ *
+ * @return the identifier of the controller to create
+ */
+ public String getPredefinedID() {
+ return predefinedID;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/predefined/GetAllPredefinedPropertyEditorControllersOperation.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/predefined/GetAllPredefinedPropertyEditorControllersOperation.java
new file mode 100644
index 00000000000..bded7c50b05
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/predefined/GetAllPredefinedPropertyEditorControllersOperation.java
@@ -0,0 +1,35 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller.predefined;
+
+import java.util.Collections;
+import java.util.Map;
+
+import org.eclipse.gmf.runtime.common.core.service.IOperation;
+import org.eclipse.gmf.runtime.common.core.service.IProvider;
+
+
+/**
+ * Operation that returns the list of all predefined controllers for this element
+ */
+public class GetAllPredefinedPropertyEditorControllersOperation implements IOperation {
+
+ /**
+ * {@inheritDoc}
+ */
+ public Map<String, PredefinedControllerDescriptor> execute(IProvider provider) {
+ if(provider instanceof PredefinedPropertyControllerProvider) {
+ return ((PredefinedPropertyControllerProvider)provider).getAllPredefinedProviders();
+ }
+ return Collections.emptyMap();
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/predefined/PredefinedControllerDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/predefined/PredefinedControllerDescriptor.java
new file mode 100644
index 00000000000..8f8c929e366
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/predefined/PredefinedControllerDescriptor.java
@@ -0,0 +1,115 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller.predefined;
+
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.ControllerDescriptorState;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IPropertyEditorControllerDescriptor;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.constraints.IConstraintDescriptor;
+import org.eclipse.swt.graphics.Image;
+
+
+/**
+ * Descriptor for predefined controllers
+ */
+public class PredefinedControllerDescriptor implements IPropertyEditorControllerDescriptor {
+
+ /** real descriptor */
+ private final IPropertyEditorControllerDescriptor descriptor;
+
+ /**
+ * Returns the predefined descriptor
+ *
+ * @return the predefined descriptor
+ */
+ public IPropertyEditorControllerDescriptor getDescriptor() {
+ return descriptor;
+ }
+
+ /** predefined id of the controller */
+ private final String predefinedId;
+
+ /**
+ * Creates a new PredefinedControllerDescriptor.
+ *
+ * @param predefinedId
+ * the id of the predefined descriptor
+ *
+ * @param descriptor
+ * the predefined descriptor
+ */
+ public PredefinedControllerDescriptor(String predefinedId, IPropertyEditorControllerDescriptor descriptor) {
+ this.predefinedId = predefinedId;
+ this.descriptor = descriptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return descriptor.getText();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return descriptor.getImage();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean acceptMultiSelection() {
+ return descriptor.acceptMultiSelection();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getControllerID() {
+ return descriptor.getControllerID();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IPropertyEditorDescriptor getEditorDescriptor() {
+ return descriptor.getEditorDescriptor();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<IConstraintDescriptor> getConstraintDescriptors() {
+ return descriptor.getConstraintDescriptors();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ControllerDescriptorState createState(boolean readOnly) {
+ return new PredefinedControllerState(this, readOnly);
+ }
+
+ /**
+ * Returns the predefinedId of the controller
+ *
+ * @return the predefinedId of the controller
+ */
+ public String getPredefinedId() {
+ return predefinedId;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/predefined/PredefinedControllerState.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/predefined/PredefinedControllerState.java
new file mode 100644
index 00000000000..24e131fa662
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/predefined/PredefinedControllerState.java
@@ -0,0 +1,132 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller.predefined;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.Collections;
+
+import org.eclipse.papyrus.properties.runtime.controller.PropertyEditorController;
+import org.eclipse.papyrus.properties.runtime.controller.PropertyEditorControllerService;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.ControllerDescriptorState;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * State for predefined controllers
+ */
+public class PredefinedControllerState extends ControllerDescriptorState {
+
+ /** change support for this bean */
+ private PropertyChangeSupport changeSupport;
+
+ /** id of the controller managed by this state */
+ private String predefinedIdState;
+
+ /**
+ * Creates a new PredefinedControllerState.
+ *
+ * @param propertyEditorControllerDescriptor
+ * descriptor managed by this state
+ * @param readOnly
+ * the read only mode of this state
+ */
+ public PredefinedControllerState(PredefinedControllerDescriptor propertyEditorControllerDescriptor, boolean readOnly) {
+ super(propertyEditorControllerDescriptor, readOnly);
+
+ predefinedIdState = propertyEditorControllerDescriptor.getPredefinedId();
+
+ // register change support
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public PredefinedControllerDescriptor getDescriptor() {
+ return (PredefinedControllerDescriptor)super.getDescriptor();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEditionDialogId() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node generateNode(Document document) {
+ Element node = document.createElement("controller");
+ node.setAttribute("predefinedId", getPredefinedIdState());
+ return node;
+ }
+
+ /**
+ * Sets the predefinedIdState
+ *
+ * @param predefinedIdState
+ * the predefinedIdState to set
+ */
+ public void setPredefinedIdState(String predefinedIdState) {
+ String oldPredefinedIdState = this.predefinedIdState;
+ this.predefinedIdState = predefinedIdState;
+
+ // change also the controller descriptor as a consequence
+ this.descriptor = PropertyEditorControllerService.getInstance().createPredefinedControllerDescriptor(predefinedIdState);
+
+ changeSupport.firePropertyChange("predefinedId", oldPredefinedIdState, this.predefinedIdState);
+ changeSupport.firePropertyChange("descriptor", null, descriptor);
+ }
+
+ /**
+ * Returns the predefinedIdState
+ *
+ * @return the predefinedIdState
+ */
+ public String getPredefinedIdState() {
+ return predefinedIdState;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void createPreview(Composite composite) {
+ PropertyEditorController controller = PropertyEditorControllerService.getInstance().createPropertyEditorController(Collections.emptyList(), composite, descriptor);
+
+ if(controller != null) {
+ // use the state to create this
+ controller.createPropertyEditor(this.getDescriptor().getEditorDescriptor(), new TabbedPropertySheetWidgetFactory());
+ }
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/predefined/PredefinedPropertyControllerProvider.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/predefined/PredefinedPropertyControllerProvider.java
new file mode 100644
index 00000000000..92b5359fc1b
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/controller/predefined/PredefinedPropertyControllerProvider.java
@@ -0,0 +1,218 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.controller.predefined;
+
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.gmf.runtime.common.core.service.AbstractProvider;
+import org.eclipse.gmf.runtime.common.core.service.IOperation;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.PropertyEditorControllerService;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IPropertyEditorControllerDescriptor;
+import org.osgi.framework.Bundle;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+
+/**
+ * Provider for property controllers that are configured using an xml file
+ */
+public class PredefinedPropertyControllerProvider extends AbstractProvider {
+
+ /** PREDEFINED_ID */
+ public static final String PREDEFINED_ID = "predefinedId";
+
+ /** key for the value: path to the xml file */
+ protected static final String XML_PATH = "path";
+
+ /** predefined controllers identified by their unique predefined identifier (faster search) */
+ private Map<String, PredefinedControllerDescriptor> predefinedControllers = new HashMap<String, PredefinedControllerDescriptor>();
+
+ /** bundle that declares this provider */
+ private Bundle bundle = null;
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean provides(IOperation operation) {
+ if(operation instanceof CreatePredefinedPropertyControllerProviderOperation) {
+ return predefinedControllers.containsKey(((CreatePredefinedPropertyControllerProviderOperation)operation).getPredefinedID());
+ } else if(operation instanceof GetAllPredefinedPropertyEditorControllersOperation) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Configures this provider, given the configuration element
+ *
+ * @param providerConfiguration
+ * the configuration element
+ */
+ public void configure(IConfigurationElement providerConfiguration) {
+ // for each property editors defined in the provider, retrieves important information
+ for(IConfigurationElement element : providerConfiguration.getChildren()) {
+ // check this child is really configuring editors (not a Priority child...)
+ if("PredefinedControllers".equals(element.getName())) {
+ // parse this editor configuration
+ // there should be an xml path
+ bundle = Platform.getBundle(providerConfiguration.getContributor().getName());
+ assert (bundle != null) : "bundle should not be null when loading predefined controllers";
+
+ readXMLConfiguration(element);
+ //controllers.put(configuration.getId(), configuration);
+ }
+ }
+ }
+
+ /**
+ * Reads the xml configuration file and constructs the descriptors
+ *
+ * @param element
+ * the configuration element to read
+ */
+ protected void readXMLConfiguration(IConfigurationElement element) {
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setNamespaceAware(true);
+ try {
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+
+ // retrieve xml file from path
+ String pluginID = element.getContributor().getName();
+ Bundle bundle = Platform.getBundle(pluginID);
+ if(bundle != null) {
+ URL xmlURL = bundle.getEntry(element.getAttribute(XML_PATH));
+ Document document = documentBuilder.parse(new InputSource(xmlURL.toString()));
+ NodeList views = document.getChildNodes();
+ for(int i = 0; i < views.getLength(); i++) {
+ Node predefinedControllerNode = views.item(i);
+ // check this is a property view, not a comment or a text format node.
+ if("predefinedControllers".equals(predefinedControllerNode.getNodeName())) {
+ parsePredefinedControllersNode(predefinedControllerNode);
+ }
+ }
+ }
+ } catch (ParserConfigurationException e) {
+ Activator.log.error(e);
+ } catch (IOException e) {
+ Activator.log.error(e);
+ } catch (SAXException e) {
+ Activator.log.error(e);
+ }
+ }
+
+ /**
+ * Creates, configures and returns the controller.
+ *
+ * @param predefinedID
+ * the id of the controller to create
+ *
+ * @return the created controller
+ */
+ public IPropertyEditorControllerDescriptor retrievePropertyEditorControllerDescriptor(String predefinedID) {
+ return predefinedControllers.get(predefinedID);
+ }
+
+ /**
+ * Returns the list of all predefined controllers proposed by this provider
+ *
+ * @return the list of all predefined controllers proposed by this provider
+ */
+ public Map<String, PredefinedControllerDescriptor> getAllPredefinedProviders() {
+ return predefinedControllers;
+ }
+
+ /**
+ * Retrieves the xml file configuring the property view
+ *
+ * @param element
+ * the configuration element to read
+ * @param path
+ * the path for the file to retrieve
+ * @return the file that configures the controllers
+ * @throws IOException
+ * exception thrown when the file could not be read
+ */
+ public File getXmlFile(IConfigurationElement element, String path) throws IOException {
+ // try to read it in a plugin...
+ Bundle bundle = Platform.getBundle(element.getContributor().getName());
+ Activator.log.debug((bundle != null) ? bundle.toString() : "not a bundle");
+
+ if(bundle != null) {
+ URL urlFile = bundle.getEntry(path);
+ urlFile = FileLocator.resolve(urlFile);
+ urlFile = FileLocator.toFileURL(urlFile);
+ if("file".equals(urlFile.getProtocol())) { //$NON-NLS-1$
+ return new File(urlFile.getFile());
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Parses the predefined Controllers node
+ *
+ * @param predefinedControllerNode
+ * the configuration node of the predefined Controllers
+ */
+ protected void parsePredefinedControllersNode(Node predefinedControllerNode) {
+ // retrieve each child node which is a view
+ NodeList children = predefinedControllerNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ // check this is a view node (not a comment or a formatting children)
+
+ Node childNode = children.item(i);
+ if("predefinedController".equals(childNode.getNodeName())) {
+ parsePredefinedController(childNode);
+ }
+ }
+
+ }
+
+ /**
+ * Parses the predefined controller node
+ *
+ * @param childNode
+ * the node to parse
+ */
+ protected void parsePredefinedController(Node childNode) {
+ if(childNode.hasAttributes()) {
+ Node controllerIDNode = childNode.getAttributes().getNamedItem("id");
+ Node predefinedIDNode = childNode.getAttributes().getNamedItem(PREDEFINED_ID);
+
+ if(controllerIDNode != null && predefinedIDNode != null) {
+ String controllerID = controllerIDNode.getNodeValue();
+ String predefinedID = predefinedIDNode.getNodeValue();
+
+ // retrieve other informations using the specific descriptors of each controller
+ IPropertyEditorControllerDescriptor descriptor = PropertyEditorControllerService.getInstance().createPropertyEditorControllerDescriptor(controllerID, childNode, bundle);
+ predefinedControllers.put(predefinedID, new PredefinedControllerDescriptor(predefinedID, descriptor));
+ }
+ } else {
+ Activator.log.error("Impossible to find attributes for predefined controller node", null);
+ }
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/dialogs/EMFFeatureBindingLabelProviderDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/dialogs/EMFFeatureBindingLabelProviderDescriptor.java
new file mode 100644
index 00000000000..cdbe159dfc0
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/dialogs/EMFFeatureBindingLabelProviderDescriptor.java
@@ -0,0 +1,104 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.dialogs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.osgi.util.NLS;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IBindingLabelProviderDescriptor;
+import org.eclipse.uml2.uml.StructuralFeature;
+
+/**
+ * Descriptor used for message binding on features
+ */
+public class EMFFeatureBindingLabelProviderDescriptor implements IBindingLabelProviderDescriptor {
+
+ /** message to bind */
+ private final String message;
+
+ /** name of features used to bind message */
+ private String[] featuresNameToEdit;
+
+ /**
+ * Creates a new EMFFeatureBindingLabelProviderDescriptor.
+ *
+ * @param message
+ * the message to bind
+ * @param featuresNameToEdit
+ * the name of features binded
+ *
+ */
+ public EMFFeatureBindingLabelProviderDescriptor(String message, String[] featuresNameToEdit) {
+ this.message = message;
+ this.featuresNameToEdit = featuresNameToEdit;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getMessage() {
+ return message;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String[] getFeaturesNameToBind() {
+ return featuresNameToEdit;
+ }
+
+ /**
+ * computes bindings from the given descriptor
+ *
+ * @param objectToEdit
+ * the object to edit
+ * @return the list of values to bind
+ */
+ public String computeBindings(Object objectToEdit) {
+ List<Object> bindings = new ArrayList<Object>();
+
+ if(objectToEdit instanceof EObject) {
+ for(String name : getFeaturesNameToBind()) {
+ EStructuralFeature feature = getFeatureByName(((EObject)objectToEdit), name);
+ if(feature != null) {
+ Object value = ((EObject)objectToEdit).eGet(feature);
+ bindings.add(value);
+ } else {
+ Activator.log.error("impossible to find the feature with name : " + name, null);
+ }
+ }
+ }
+
+ return NLS.bind(getMessage(), bindings.toArray(new String[]{}));
+ }
+
+ /**
+ * Returns the feature given its name
+ *
+ * @param objectToEdit
+ * the object to edit
+ * @param name
+ * the name of the feature to find
+ * @return the {@link StructuralFeature} found
+ */
+ protected EStructuralFeature getFeatureByName(EObject objectToEdit, String name) {
+ EStructuralFeature feature = objectToEdit.eClass().getEStructuralFeature(name);
+ if(feature != null) {
+ return feature;
+ }
+ return null;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/dialogs/GetDialogDescriptorOperation.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/dialogs/GetDialogDescriptorOperation.java
new file mode 100644
index 00000000000..5de6d391bff
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/dialogs/GetDialogDescriptorOperation.java
@@ -0,0 +1,59 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.dialogs;
+
+import java.util.List;
+
+import org.eclipse.gmf.runtime.common.core.service.IProvider;
+import org.eclipse.papyrus.properties.runtime.view.DialogDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.IPropertyViewOperation;
+import org.eclipse.papyrus.properties.runtime.view.IPropertyViewProvider;
+
+
+/**
+ * Operation that retrieves a Dialog descriptor
+ */
+public class GetDialogDescriptorOperation implements IPropertyViewOperation {
+
+ /** id of the dialog descriptor to retrieve */
+ private final List<Object> objectstoEdit;
+
+ /**
+ * Creates a new GetDialogDescriptorOperationById.
+ *
+ * @param objectstoEdit
+ * list of objects to edit
+ */
+ public GetDialogDescriptorOperation(List<Object> objectstoEdit) {
+ this.objectstoEdit = objectstoEdit;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<DialogDescriptor> execute(IProvider provider) {
+ if(provider instanceof IPropertyViewProvider) {
+ return ((IPropertyViewProvider)provider).getDialogDescriptor(getObjectstoEdit());
+ }
+ return null;
+ }
+
+ /**
+ * Returns the list of objects to edit
+ *
+ * @return the list of objects to edit
+ */
+ public List<Object> getObjectstoEdit() {
+ return objectstoEdit;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/dialogs/GetDialogDescriptorOperationById.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/dialogs/GetDialogDescriptorOperationById.java
new file mode 100644
index 00000000000..eba7a14bb56
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/dialogs/GetDialogDescriptorOperationById.java
@@ -0,0 +1,57 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.dialogs;
+
+import org.eclipse.gmf.runtime.common.core.service.IProvider;
+import org.eclipse.papyrus.properties.runtime.view.DialogDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.IPropertyViewOperation;
+import org.eclipse.papyrus.properties.runtime.view.IPropertyViewProvider;
+
+
+/**
+ * Operation that retrieves a Dialog descriptor
+ */
+public class GetDialogDescriptorOperationById implements IPropertyViewOperation {
+
+ /** id of the dialog descriptor to retrieve */
+ protected final String descriptorID;
+
+ /**
+ * Creates a new GetDialogDescriptorOperationById.
+ *
+ * @param descriptorID
+ * id of the descriptor to retrieve
+ */
+ public GetDialogDescriptorOperationById(String descriptorID) {
+ this.descriptorID = descriptorID;
+ }
+
+ /**
+ * Returns the descriptor id for this operation
+ *
+ * @return the descriptor id for this operation
+ */
+ public String getDescriptorID() {
+ return descriptorID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public DialogDescriptor execute(IProvider provider) {
+ if(provider instanceof IPropertyViewProvider) {
+ return ((IPropertyViewProvider)provider).getDialogDescriptor(descriptorID);
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/dialogs/PropertyDialog.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/dialogs/PropertyDialog.java
new file mode 100644
index 00000000000..69b6c03ec7a
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/dialogs/PropertyDialog.java
@@ -0,0 +1,215 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.dialogs;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.StatusDialog;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IBindingLabelProviderDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.DialogDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.IFragmentDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.content.AbstractContainerDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.ScrolledComposite;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+
+
+/**
+ * Dialog displaying properties of an element
+ */
+public class PropertyDialog extends StatusDialog {
+
+ /** descriptor of this dialog */
+ private final DialogDescriptor descriptor;
+
+ /** list of objects to edit */
+ private final List<Object> objectsToEdit;
+
+ /** widget factory */
+ private final TabbedPropertySheetWidgetFactory widgetFactory;
+
+ /** ok button */
+ protected Button okButton;
+
+ /**
+ * Creates a new PropertyDialog.
+ *
+ * @param parent
+ * the parent shell for this dialog
+ * @param descriptor
+ * the dialog descriptor used to create this dialog
+ * @param objectsToEdit
+ * the list of objects to edit
+ * @param widgetFactory
+ * the factory used to create the content of the dialog
+ */
+ public PropertyDialog(Shell parent, DialogDescriptor descriptor, List<Object> objectsToEdit, TabbedPropertySheetWidgetFactory widgetFactory) {
+ super(parent);
+ this.descriptor = descriptor;
+ this.objectsToEdit = objectsToEdit;
+ this.widgetFactory = widgetFactory;
+ // adding resize, close and trim abilities
+ setShellStyle(getShellStyle() | SWT.SHELL_TRIM);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void createButtonsForButtonBar(Composite parent) {
+ okButton = createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+ //no cancel button
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void configureShell(Shell shell) {
+ super.configureShell(shell);
+ shell.setSize(640, 480);
+ shell.setText(getTitle());
+ }
+
+ /**
+ * Returns the title, using the dialog descriptor
+ *
+ * @return the string to display as title
+ */
+ protected String getTitle() {
+ return getMessageFromDescriptor(descriptor.getTitle());
+ }
+
+ /**
+ * Returns the message, using the dialog descriptor
+ *
+ * @return the string to display as message
+ */
+ protected String getMessage() {
+ return getMessageFromDescriptor(descriptor.getMessage());
+ }
+
+ /**
+ * Returns a string, given an object
+ *
+ * @param object
+ * should be a {@link String} or a {@link IBindingLabelProviderDescriptor}
+ * @return the string given by the object
+ */
+ protected String getMessageFromDescriptor(Object object) {
+ if(object instanceof String) {
+ return ((String)object);
+ } else if(object instanceof IBindingLabelProviderDescriptor) {
+ if(objectsToEdit.size() == 1) {
+ return ((IBindingLabelProviderDescriptor)object).computeBindings(objectsToEdit.get(0));
+ } else if(objectsToEdit.size() > 1) {
+ return ((IBindingLabelProviderDescriptor)object).computeBindings(objectsToEdit.get(0)) + " (and others)";
+ } else {
+ // should never happen
+ return "No object to edit";
+ }
+ } else {
+ Activator.log.warn("the object from which string is computed is not a String either a label descriptor");
+ return "";
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Control createDialogArea(Composite parent) {
+ Composite composite = (Composite)super.createDialogArea(parent);
+
+ getWidgetFactory().setBackground(composite.getBackground());
+
+ // creates the content, given the configuration
+ Label messageLabel = getWidgetFactory().createLabel(composite, getMessage(), SWT.NONE);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
+ messageLabel.setLayoutData(data);
+
+ Label separator = getWidgetFactory().createSeparator(composite, SWT.HORIZONTAL);
+ separator.setLayoutData(data);
+
+ Color defaultColor = getShell().getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND);
+ getWidgetFactory().setBackground(defaultColor);
+ ScrolledComposite scrolledComposite = getWidgetFactory().createScrolledComposite(composite, SWT.BORDER);
+ scrolledComposite.setAlwaysShowScrollBars(false);
+ GridLayout layout = new GridLayout(1, false);
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ scrolledComposite.setLayout(layout);
+ data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ scrolledComposite.setLayoutData(data);
+
+ Composite containerComposite = getWidgetFactory().createComposite(scrolledComposite);
+ layout = new GridLayout(1, false);
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ containerComposite.setLayout(layout);
+ scrolledComposite.setLayout(layout);
+ scrolledComposite.setContent(containerComposite);
+ scrolledComposite.setExpandVertical(true);
+ scrolledComposite.setExpandHorizontal(true);
+
+ List<AbstractContainerDescriptor> containers = new ArrayList<AbstractContainerDescriptor>();
+ for(IFragmentDescriptor fragmentDescriptor : getFragmentsId()) {
+ if(fragmentDescriptor != null) {
+ for(AbstractContainerDescriptor descriptor : fragmentDescriptor.getContainerDescriptors()) {
+ descriptor.createContent(containerComposite, getWidgetFactory(), objectsToEdit);
+ containers.add(descriptor);
+ }
+ }
+ }
+
+ return composite;
+ }
+
+ /**
+ * Returns the list of identifier of fragments for this dialog
+ *
+ * @return the list of identifier of fragments for this dialog
+ */
+ protected List<IFragmentDescriptor> getFragmentsId() {
+ return descriptor.getFragmentDescriptors();
+ }
+
+ /**
+ * Returns the objects edited in this dialog
+ *
+ * @return the objects edited in this dialog
+ */
+ protected List<Object> getObjectsToEdit() {
+ return objectsToEdit;
+ }
+
+ /**
+ * Returns the widget factory
+ *
+ * @return the widget factory
+ */
+ protected TabbedPropertySheetWidgetFactory getWidgetFactory() {
+ return widgetFactory;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/dialogs/ReferenceExplorerDialog.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/dialogs/ReferenceExplorerDialog.java
new file mode 100644
index 00000000000..300c72629c7
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/dialogs/ReferenceExplorerDialog.java
@@ -0,0 +1,215 @@
+package org.eclipse.papyrus.properties.runtime.dialogs;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.List;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.IDialogSettings;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.IBoundedValuesController;
+import org.eclipse.papyrus.properties.runtime.controller.PropertyEditorController;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.FilteredItemsSelectionDialog;
+
+/**
+ * Selection dialog for icons in bundles
+ */
+public class ReferenceExplorerDialog extends FilteredItemsSelectionDialog {
+
+ /** preference key for the dialog settings */
+ private static final String DIALOG_SETTINGS = "org.eclipse.papyrus.properties.runtime.dialogs.ReferenceExplorerDialog"; //$NON-NLS-1$
+
+ /** current filter string */
+ protected String filter = null;
+
+ /** controller used to retrieve values */
+ private IBoundedValuesController controller;
+
+ /** label Provider used in this window */
+ private ILabelProvider labelProvider;
+
+ /** reference comparator */
+ private Comparator<?> referenceComparator = new ReferenceComparator();
+
+ /**
+ * Creates a new ReferenceExplorerDialog
+ *
+ * @param parentShell
+ * the parent shell for the dialog
+ * @param controller
+ * the controller managing the property editor
+ * @param allowMultiple
+ * <code>true</code> if multi selection is allowed
+ */
+ public ReferenceExplorerDialog(Shell parentShell, IBoundedValuesController controller, boolean allowMultiple) {
+ super(parentShell, allowMultiple);
+ this.controller = controller;
+ labelProvider = controller.getBrowserLabelProvider();
+ setTitle("Select " + ((PropertyEditorController)controller).getPropertyEditor().getDescriptor().getLabel());
+ setMessage("Select the reference you want for " + ((PropertyEditorController)controller).getPropertyEditor().getDescriptor().getLabel() + "\nTooltip: " + ((PropertyEditorController)controller).getPropertyEditor().getTooltipText());
+ setListLabelProvider(labelProvider);
+ setDetailsLabelProvider(labelProvider);
+ setInitialPattern("**");
+ setInitialSelections(controller.getCurrentValues());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Control createExtendedContentArea(Composite parent) {
+ // should create here the create wizard part
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected IDialogSettings getDialogSettings() {
+ IDialogSettings settings = Activator.getDefault().getDialogSettings().getSection(DIALOG_SETTINGS);
+ if(settings == null) {
+ settings = Activator.getDefault().getDialogSettings().addNewSection(DIALOG_SETTINGS);
+ }
+ return settings;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected IStatus validateItem(Object item) {
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected ItemsFilter createFilter() {
+ return new ObjectItemFilter();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Comparator<?> getItemsComparator() {
+ return referenceComparator;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void fillContentProvider(AbstractContentProvider contentProvider, ItemsFilter itemsFilter, IProgressMonitor progressMonitor) throws CoreException {
+ Object[] elements = getElements();
+ if(elements == null) {
+ return;
+ }
+ progressMonitor.beginTask("Filling reference list", elements.length);
+ for(int i = 0; i < elements.length && !progressMonitor.isCanceled(); i++) {
+ contentProvider.add(elements[i], itemsFilter);
+ progressMonitor.worked(1);
+ }
+ progressMonitor.done();
+ }
+
+ /**
+ * Returns the list of elements to be displayed
+ *
+ * @return the list of elements to be displayed
+ */
+ protected Object[] getElements() {
+ Object values = controller.getAvailableValues();
+ if(values instanceof Object[]) {
+ return (Object[])values;
+ } else if(values instanceof List<?>) {
+ return ((List<?>)values).toArray();
+ } else if(values instanceof Object) {
+ return Arrays.asList(values).toArray();
+ }
+ return new Object[]{ values };
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getElementName(Object item) {
+ return labelProvider.getText(item);
+ }
+
+ /**
+ * Comparator for the content of the dialog
+ */
+ @SuppressWarnings("rawtypes")
+ private static class ReferenceComparator implements Comparator {
+
+ /**
+ * Creates a new ReferenceComparator.
+ */
+ public ReferenceComparator() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int compare(Object o1, Object o2) {
+ return 1;
+ }
+ }
+
+ /**
+ * Items filter the the elements in the dialog
+ */
+ private class ObjectItemFilter extends ItemsFilter {
+
+ /**
+ * Creates a new ObjectItemFilter.
+ */
+ public ObjectItemFilter() {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean matchItem(Object item) {
+ String value = labelProvider.getText(item);
+ if(value != null) {
+ return (matches(value));
+ }
+ Activator.log.debug("Value should not be null for object :" + item);
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean matches(String text) {
+ String pattern = patternMatcher.getPattern();
+ if(pattern.indexOf("*") != 0 & pattern.indexOf("?") != 0 & pattern.indexOf(".") != 0) {//$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ pattern = "*" + pattern; //$NON-NLS-1$
+ patternMatcher.setPattern(pattern);
+ }
+ return patternMatcher.matches(text);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isConsistentItem(Object item) {
+ return true;
+ }
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/messages.properties b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/messages.properties
new file mode 100644
index 00000000000..9a93214aa9f
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/messages.properties
@@ -0,0 +1,3 @@
+EMFTEReferenceController_CreationOperationMenuLabel=Create a new {0}
+EMFTEReferenceController_DeleteElement_OperationLabel=Delete elements
+ReferenceEMFModelHandler_Select_Values=Select Values
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/IPropertyModelHandlerFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/IPropertyModelHandlerFactory.java
new file mode 100644
index 00000000000..b50d27a20ef
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/IPropertyModelHandlerFactory.java
@@ -0,0 +1,29 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler;
+
+import org.w3c.dom.Node;
+
+/**
+ * Interface implemented by all model handler factories
+ */
+public interface IPropertyModelHandlerFactory {
+
+ /**
+ * Creates an instance of the model handler, given the configuration node
+ *
+ * @param modelHandlerNode
+ * the configuration node for the instance of the model handler to create
+ * @return the created model handler
+ */
+ Object createModelHandler(Node modelHandlerNode);
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/ModelHandlerFactoryDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/ModelHandlerFactoryDescriptor.java
new file mode 100644
index 00000000000..0b719c2a67a
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/ModelHandlerFactoryDescriptor.java
@@ -0,0 +1,145 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.swt.graphics.Image;
+
+
+/**
+ * Descriptor for model handler factories
+ */
+public class ModelHandlerFactoryDescriptor {
+
+ /** default description label */
+ protected static final String DEFAULT_DESCRIPTION = "";
+
+ /** name of the described model handler */
+ protected final String name;
+
+ /** id of the described model handler */
+ protected final String id;
+
+ /** description of the described model handler */
+ protected final String description;
+
+ /** plugin-relative path to the icon */
+ protected final String iconPath;
+
+ /** id of the plugin that contributes to this descriptor */
+ protected final String pluginId;
+
+ /** name of the class implementing the model handler factory */
+ // protected final String className;
+
+ /** configuration element */
+ protected IConfigurationElement element;
+
+ /** implementation class of the factory (lazy initialization) */
+ protected IPropertyModelHandlerFactory factory;
+
+ /** boolean that indicates that instantiating the factory crashed */
+ private boolean parseFailed = false;
+
+ /** attribute: name */
+ public static String ATTRIBUTE_NAME = "name";
+
+ /** attribute: description */
+ public static String ATTRIBUTE_DESCRIPTION = "description";
+
+ /** attribute: id */
+ public static String ATTRIBUTE_ID = "id";
+
+ /** attribute: icon */
+ public static String ATTRIBUTE_ICON = "icon";
+
+ /** attribute: class name */
+ public static String ATTRIBUTE_CLASS_NAME = "class";
+
+ /**
+ * Creates a new ModelHandlerFactoryDescriptor.
+ *
+ * @param element
+ * the configuration element that configures this descriptor
+ */
+ public ModelHandlerFactoryDescriptor(IConfigurationElement element) {
+ // create model handler factory descriptors from the extension points
+ // retrieve information from the configuration element
+ name = element.getAttribute(ATTRIBUTE_NAME);
+ id = element.getAttribute(ATTRIBUTE_ID);
+ // className = element.getAttribute(ATTRIBUTE_CLASS_NAME);
+ String tmpDesc = element.getAttribute(ATTRIBUTE_DESCRIPTION);
+ description = (tmpDesc != null) ? tmpDesc : DEFAULT_DESCRIPTION;
+ iconPath = element.getAttribute(ATTRIBUTE_ICON);
+ pluginId = element.getContributor().getName();
+ this.element = element;
+ }
+
+
+ /**
+ * Returns the name of the model handler
+ *
+ * @return the name of the model handler
+ */
+ public String getName() {
+ return name;
+ }
+
+
+ /**
+ * Returns the description of the model handler
+ *
+ * @return the description of the model handler
+ */
+ public String getDescription() {
+ return description;
+ }
+
+
+ /**
+ * Returns the id of this model handler
+ *
+ * @return the id of this model handler
+ */
+ public String getId() {
+ return id;
+ }
+
+
+ /**
+ * Returns the iconPath
+ *
+ * @return the iconPath
+ */
+ public Image getImage() {
+ return Activator.getImageFromDescriptor(Activator.imageDescriptorFromPlugin(pluginId, iconPath));
+ }
+
+ /**
+ * Returns the factory described by this configuration element
+ *
+ * @return the factory described by this configuration element
+ */
+ public IPropertyModelHandlerFactory getModelHandlerFactory() {
+ if(factory == null && !parseFailed) {
+ try {
+ factory = (IPropertyModelHandlerFactory)element.createExecutableExtension(ATTRIBUTE_CLASS_NAME);
+ } catch (CoreException e) {
+ Activator.log.error(e);
+ parseFailed = true;
+ }
+ }
+ return factory;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/ModelHandlerService.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/ModelHandlerService.java
new file mode 100644
index 00000000000..484389b8de9
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/ModelHandlerService.java
@@ -0,0 +1,101 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.w3c.dom.Node;
+
+
+
+/**
+ * Service to retrieve model handlers
+ */
+public class ModelHandlerService {
+
+ /** identifier for the model handler extension point */
+ public static final String EXTENSION_POINT_ID = "org.eclipse.papyrus.properties.runtime.propertyModelHandler";
+
+ /** list of registered model handlers factories descriptors */
+ protected final List<ModelHandlerFactoryDescriptor> modelHandlerFactoryDescriptors;
+
+ /** singleton instance of the service */
+ protected static ModelHandlerService instance;
+
+ /**
+ * Creates a new ModelHandlerService.
+ *
+ * @param modelHandlerFactoryDescriptors
+ * list of model handler factory descriptors proposed by this service
+ */
+ protected ModelHandlerService(List<ModelHandlerFactoryDescriptor> modelHandlerFactoryDescriptors) {
+ this.modelHandlerFactoryDescriptors = modelHandlerFactoryDescriptors;
+ }
+
+ /**
+ * returns the singleton instance of this class
+ *
+ * @return the singleton instance of this class
+ */
+ public static synchronized ModelHandlerService getInstance() {
+ if(instance == null) {
+ instance = createService();
+ }
+ return instance;
+ }
+
+ /**
+ * Creates the singleton instance of the service
+ *
+ * @return the singleton instance of the service
+ */
+ protected static ModelHandlerService createService() {
+ // read extension points and initialize the factories
+ // Reading data from plugins
+ List<ModelHandlerFactoryDescriptor> modelHandlers = new ArrayList<ModelHandlerFactoryDescriptor>();
+
+ IConfigurationElement[] configElements = Platform.getExtensionRegistry().getConfigurationElementsFor(EXTENSION_POINT_ID);
+ for(IConfigurationElement element : configElements) {
+ ModelHandlerFactoryDescriptor descriptor = new ModelHandlerFactoryDescriptor(element);
+ modelHandlers.add(descriptor);
+ }
+ return new ModelHandlerService(modelHandlers);
+ }
+
+ /**
+ * Creates and return a model handler, given the configuration node
+ *
+ * @param id
+ * the id of the handler to create
+ * @param featureNode
+ * the node configuring the model handler
+ * @return the create model handler
+ */
+ public Object createModelHandler(String id, Node featureNode) {
+ // retrieve the model handler factory that has the correct id
+ for(ModelHandlerFactoryDescriptor descriptor : modelHandlerFactoryDescriptors) {
+ if(id.equals(descriptor.getId())) {
+ IPropertyModelHandlerFactory factory = descriptor.getModelHandlerFactory();
+ if(factory != null) {
+ return factory.createModelHandler(featureNode);
+ } else {
+ // descriptor already send a message, no need to send there one more.
+ }
+ }
+ }
+
+ return null;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/BooleanEMFModelHandler.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/BooleanEMFModelHandler.java
new file mode 100644
index 00000000000..bc73a83321a
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/BooleanEMFModelHandler.java
@@ -0,0 +1,158 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ * Vincent Lorenzo (CEA-LIST) vincent.lorenzo@cea.fr
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IBoundedValuesPropertyEditorDescriptor;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+
+/**
+ * Model Handler for enumeration
+ */
+public class BooleanEMFModelHandler extends EnumerationEMFModelHandler {
+
+ /** id of this model handler */
+ public static final String ID = "Boolean"; //$NON-NLS-1$
+
+ /**
+ * Creates a new BooleanEMFModelHandler.
+ *
+ * @param featureName
+ * the name of the feature to edit
+ */
+ public BooleanEMFModelHandler(String featureName) {
+ super(featureName);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getValueToEdit(EObject objectToEdit) {
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return null;
+ }
+ Object value = objectToEdit.eGet(featureToEdit);
+
+ // should perhaps take into account default values in case the feature is not set...
+ return (value instanceof Boolean) ? ((Boolean)value).toString() : value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public void setValueInModel(EObject objectToEdit, Object newValue) {
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return;
+ }
+ // remove value if result of the editor is empty
+ if(newValue == null || newValue.equals("")) { //$NON-NLS-1$
+ objectToEdit.eUnset(featureToEdit);
+ } else if(newValue instanceof String) {
+ objectToEdit.eSet(featureToEdit, Boolean.parseBoolean((String)newValue));
+ } else if(newValue instanceof Boolean) {
+ objectToEdit.eSet(featureToEdit, newValue);
+ } else if(newValue instanceof List<?>) {
+ List<Object> newValues = new ArrayList<Object>();
+ for(Object value : (List<Object>)newValue) {
+ if(value instanceof String) {
+ newValues.add(Boolean.parseBoolean((String)value));
+ } else if(value instanceof Boolean) {
+ newValues.add(value);
+ }
+ }
+ objectToEdit.eSet(featureToEdit, newValues);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void completeEditorDescriptor(IPropertyEditorDescriptor descriptor, List<? extends EObject> objectToEdit) {
+ if(objectToEdit.size() < 1) {
+ return;
+ }
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit.get(0));
+ if(featureToEdit == null) {
+ return;
+ }
+ // test enumeration, reference, etc.
+ List<String> values = new ArrayList<String>();
+
+ // check if there is an empty string at the beginning. there is one if the lower bound of the feature to edit equal 0
+ if(featureToEdit.getLowerBound() == 0) {
+ values.add(""); //$NON-NLS-1$
+ }
+
+ values.add("true"); //$NON-NLS-1$
+ values.add("false"); //$NON-NLS-1$
+ if(descriptor instanceof IBoundedValuesPropertyEditorDescriptor) {
+ ((IBoundedValuesPropertyEditorDescriptor)descriptor).setAvailableValues(values);
+ } else {
+ Activator.log.debug("Warning: " + descriptor + "could not be completed."); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getId() {
+ return ID;
+ }
+
+ /**
+ *
+ * @param objectToEdit
+ * @param newValue
+ * @return
+ */
+ @Override
+ public SetRequest[] getSetRequest(TransactionalEditingDomain domain, EObject objectToEdit, Object newValue) {
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return null;
+ }
+ // remove value if result of the editor is empty
+ if(newValue == null || newValue.equals("")) { //$NON-NLS-1$
+ return new SetRequest[]{ new SetRequest(domain, objectToEdit, featureToEdit, featureToEdit.getDefaultValue()) };
+ } else if(newValue instanceof String) {
+ return new SetRequest[]{ new SetRequest(domain, objectToEdit, featureToEdit, Boolean.parseBoolean((String)newValue)) };
+ } else if(newValue instanceof Boolean) {
+ return new SetRequest[]{ new SetRequest(domain, objectToEdit, featureToEdit, newValue) };
+ } else if(newValue instanceof List<?>) {
+ List<Object> newValues = new ArrayList<Object>();
+ for(Object value : (List<?>)newValue) {
+ if(value instanceof String) {
+ newValues.add(Boolean.parseBoolean((String)value));
+ } else if(value instanceof Boolean) {
+ newValues.add(value);
+ }
+ }
+ return new SetRequest[]{ new SetRequest(domain, objectToEdit, featureToEdit, newValues) };
+ }
+ return null;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/BooleanEMFModelHandlerFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/BooleanEMFModelHandlerFactory.java
new file mode 100644
index 00000000000..8e40dda985b
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/BooleanEMFModelHandlerFactory.java
@@ -0,0 +1,45 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.modelhandler.IPropertyModelHandlerFactory;
+import org.w3c.dom.Node;
+
+
+/**
+ * Factory that creates {@link BooleanEMFModelHandler}.
+ */
+public class BooleanEMFModelHandlerFactory extends EMFModelHandlerFactory implements IPropertyModelHandlerFactory {
+
+ /**
+ * Creates a new BooleanEMFModelHandlerFactory.
+ */
+ public BooleanEMFModelHandlerFactory() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public BooleanEMFModelHandler createModelHandler(Node modelHandlerNode) {
+ // specific code to parse the given element
+ String featureName = retrieveFeatureName(modelHandlerNode);
+
+ if(featureName == null) {
+ Activator.log.warn("Impossible to retrieve feature from node " + modelHandlerNode);
+ return null;
+ }
+
+ return new BooleanEMFModelHandler(featureName);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/BooleanStereotypeModelHandler.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/BooleanStereotypeModelHandler.java
new file mode 100644
index 00000000000..9bc4a039bce
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/BooleanStereotypeModelHandler.java
@@ -0,0 +1,134 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IBoundedValuesPropertyEditorDescriptor;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Stereotype;
+import org.eclipse.uml2.uml.StructuralFeature;
+
+
+/**
+ * Model Handler for Boolean-typed stereotype properties
+ */
+public class BooleanStereotypeModelHandler extends EnumerationStereotypeModelHandler {
+
+ /**
+ * Creates a new BooleanStereotypeModelHandler.
+ *
+ * @param stereotypeName
+ * the name of the stereotype
+ * @param featureName
+ * the name of the feature
+ */
+ public BooleanStereotypeModelHandler(String stereotypeName, String featureName) {
+ super(stereotypeName, featureName);
+ }
+
+ /** identifier for this model handler */
+ public static final String ID = "BooleanStereotype";
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getValueToEdit(EObject objectToEdit) {
+ if(!(objectToEdit instanceof Element)) {
+ Activator.log.warn("the element selected is not a UML element: " + objectToEdit);
+ return null;
+ }
+ Element elementToEdit = (Element)objectToEdit;
+ Stereotype stereotype = retrieveStereotype(elementToEdit);
+ if(stereotype == null) {
+ Activator.log.warn("Impossible to find the stereotype " + getStereotypeName() + " for the given element" + elementToEdit);
+ return null;
+ }
+ Object value = elementToEdit.getValue(stereotype, getFeatureName());
+
+ // should perhaps take into account default values in case the feature is not set...
+ return (value instanceof Boolean) ? ((Boolean)value).toString() : value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setValueInModel(EObject objectToEdit, Object newValue) {
+ if(!(objectToEdit instanceof Element)) {
+ Activator.log.warn("the element selected is not a UML element: " + objectToEdit);
+ return;
+ }
+ Element elementToEdit = (Element)objectToEdit;
+ Stereotype stereotype = retrieveStereotype(elementToEdit);
+ if(stereotype == null) {
+ Activator.log.warn("Impossible to find the stereotype " + getStereotypeName() + " for the given element" + elementToEdit);
+ return;
+ }
+
+ // remove value if result of the editor is empty
+ if(newValue == null || newValue.equals("")) {
+ elementToEdit.setValue(stereotype, getFeatureName(), null);
+ } else if(newValue instanceof String) {
+ elementToEdit.setValue(stereotype, getFeatureName(), Boolean.parseBoolean((String)newValue));
+ } else if(newValue instanceof Boolean) {
+ elementToEdit.setValue(stereotype, getFeatureName(), (Boolean)newValue);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void completeEditorDescriptor(IPropertyEditorDescriptor descriptor, List<? extends EObject> objectToEdit) {
+ Element elementToEdit = retrieveElement(objectToEdit);
+ if(elementToEdit == null) {
+ return;
+ }
+ Stereotype stereotype = retrieveStereotype(elementToEdit);
+
+ if(stereotype == null) {
+ Activator.log.warn("Impossible to find stereotype: " + getStereotypeName() + " for element: " + elementToEdit);
+ return;
+ }
+
+ StructuralFeature featureToEdit = retrieveStructuralFeature(elementToEdit, stereotype);
+
+ // test enumeration, reference, etc.
+ List<String> values = new ArrayList<String>();
+
+ // check if there is an empty string at the beginning. there is one if the lower bound of the feature to edit equal 0
+ if(featureToEdit.getLower() == 0) {
+ values.add("");
+ }
+
+ values.add("true");
+ values.add("false");
+ if(descriptor instanceof IBoundedValuesPropertyEditorDescriptor) {
+ ((IBoundedValuesPropertyEditorDescriptor)descriptor).setAvailableValues(values);
+ } else {
+ Activator.log.error("Warning: " + descriptor + "could not be completed.", null);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getId() {
+ return ID;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/BooleanStereotypeModelHandlerFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/BooleanStereotypeModelHandlerFactory.java
new file mode 100644
index 00000000000..51b6199ef57
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/BooleanStereotypeModelHandlerFactory.java
@@ -0,0 +1,44 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.modelhandler.IPropertyModelHandlerFactory;
+import org.w3c.dom.Node;
+
+
+/**
+ * Factory that creates {@link BooleanStereotypeModelHandler}.
+ */
+public class BooleanStereotypeModelHandlerFactory extends StereotypeModelHandlerFactory implements IPropertyModelHandlerFactory {
+
+ /**
+ * Creates a new BooleanStereotypeModelHandlerFactory.
+ */
+ public BooleanStereotypeModelHandlerFactory() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public BooleanStereotypeModelHandler createModelHandler(Node modelHandlerNode) {
+ // specific code to parse the given element
+ String featureName = retrieveFeatureName(modelHandlerNode);
+ String stereotypeName = retrieveStereotypeName(modelHandlerNode);
+ if(featureName == null || stereotypeName == null) {
+ Activator.log.warn("Impossible to retrieve feature name and/or stereotype name from node " + modelHandlerNode);
+ return null;
+ }
+ return new BooleanStereotypeModelHandler(stereotypeName, featureName);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFFeatureModelHandler.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFFeatureModelHandler.java
new file mode 100644
index 00000000000..853da8ae2d2
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFFeatureModelHandler.java
@@ -0,0 +1,1004 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ * Vincent Lorenzo (CEA-LIST) vincent.lorenzo@cea.fr
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.commands.operations.IUndoableOperation;
+import org.eclipse.emf.common.notify.AdapterFactory;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.ecore.impl.BasicEObjectImpl;
+import org.eclipse.emf.edit.provider.ComposedAdapterFactory;
+import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
+import org.eclipse.emf.edit.provider.IItemPropertySource;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand;
+import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.EMFPropertyEditorController;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * Abstract class for EMF Model handlers
+ */
+public abstract class EMFFeatureModelHandler implements IEMFModelHandler {
+
+ /** name of the feature to edit */
+ private final String featureName;
+
+ /** factory used by EMF objects */
+ protected AdapterFactory factory = new ComposedAdapterFactory(ComposedAdapterFactory.Descriptor.Registry.INSTANCE);
+
+ /** value of unset new value index */
+ public static final int NEW_VALUE_NOT_SET_INDEX = -2;
+
+ /** value of single value property */
+ public static final int SINGLE_VALUE_PROPERTY_INDEX = -1;
+
+ /**
+ * Creates a new EMFFeatureModelHandler.
+ *
+ * @param featureName
+ * the name of the feature to edit
+ */
+ public EMFFeatureModelHandler(String featureName) {
+ this.featureName = featureName;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object getValueToEdit(EObject objectToEdit) {
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return null;
+ }
+ return objectToEdit.eGet(featureToEdit);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public abstract void setValueInModel(EObject objectToEdit, Object newValue);
+
+ /**
+ * {@inheritDoc}
+ */
+ public abstract void completeEditorDescriptor(IPropertyEditorDescriptor descriptor, List<? extends EObject> objectToEdit);
+
+ /**
+ * Returns the name of the feature to edit
+ *
+ * @return the name of the feature to edit
+ */
+ public String getFeatureName() {
+ return featureName;
+ }
+
+ /**
+ * Retrieve the main {@link EStructuralFeature} of this model handler
+ *
+ * @param objectToEdit
+ * the object being edited
+ * @return the feature found <code>null</code> if not found
+ */
+ public EStructuralFeature getFeatureByName(EObject objectToEdit) {
+ return EMFUtils.getFeatureByName(objectToEdit, featureName);
+ }
+
+ /**
+ * checks if the feature is changeable
+ *
+ * @param objectsToEdit
+ * the list of objects to edit
+ * @return <code>true</code> if the feature is changeable
+ */
+ public boolean isChangeable(List<? extends EObject> objectsToEdit) {
+ if(objectsToEdit.size() < 1) {
+ return false;
+ }
+ // retrieve the feature
+ EStructuralFeature feature = getFeatureByName(objectsToEdit.get(0));
+ return (feature != null) ? feature.isChangeable() : false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "EMF Handler \"" + getId() + "\" -> " + getFeatureName(); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return Activator.getImage("/icons/ModelHandler.gif"); //$NON-NLS-1$
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IEMFModelHandlerState createState(boolean readOnly) {
+ return new EMFFeatureModelHandlerState(this, readOnly);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object getAvailableValues(EObject eObject) {
+ EClass eClass = eObject.eClass();
+ if(eClass == null) {
+ Activator.log.debug("problems during initialization, looking for availables values"); //$NON-NLS-1$
+ return null;
+ }
+ EStructuralFeature feature = getFeatureByName(eObject);
+ if(!(feature instanceof EReference)) {
+ Activator.log.debug("feature is not a reference, looking for availables values: " + feature); //$NON-NLS-1$
+ return null;
+ }
+
+ IItemPropertySource itemPropertySource = (IItemPropertySource)factory.adapt(eObject, IItemPropertySource.class);
+ if(itemPropertySource == null) {
+ Activator.log.debug("impossible to find item Property source for " + eObject); //$NON-NLS-1$
+ return null;
+ }
+ IItemPropertyDescriptor itemPropertyDescriptor = itemPropertySource.getPropertyDescriptor(eObject, feature);
+ if(itemPropertyDescriptor == null) {
+ Activator.log.debug("impossible to find item Property descriptor for " + eObject + " and " + feature); //$NON-NLS-1$ //$NON-NLS-2$
+ return null;
+ }
+ return itemPropertyDescriptor.getChoiceOfValues(eObject);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ public void handleNotifyChange(Notification notification, List<? extends EObject> objects, EMFPropertyEditorController adapter) {
+ // if one element is added to the feature, should also add this as a listener
+ // if one element is removed from the feature, should also remove this as a listener
+ // in other case, except removing adapters, should refresh
+ Object notificationFeature = notification.getFeature();
+ switch(notification.getEventType()) {
+ case Notification.ADD:
+ // check which feature has been modified
+ for(EObject eObject : objects) {
+ EStructuralFeature feature = getFeatureByName(eObject);
+ if(notificationFeature.equals(feature)) {
+ Object newValue = notification.getNewValue();
+ if(newValue instanceof EObject) {
+ ((EObject)newValue).eAdapters().add(adapter);
+ }
+ // refresh the editors
+ adapter.refreshDisplay();
+ }
+ }
+ break;
+ case Notification.ADD_MANY:
+ // check which feature has been modified
+ for(EObject eObject : objects) {
+ EStructuralFeature feature = getFeatureByName(eObject);
+ if(notificationFeature.equals(feature)) {
+ for(Object newValue : ((List<Object>)notification.getNewValue())) {
+ if(newValue instanceof EObject) {
+ ((EObject)newValue).eAdapters().add(adapter);
+ }
+ }
+ // refresh the editors
+ adapter.refreshDisplay();
+ }
+ }
+ break;
+
+ case Notification.REMOVE:
+ // check which feature has been modified
+ for(EObject eObject : objects) {
+ EStructuralFeature feature = getFeatureByName(eObject);
+ if(notificationFeature.equals(feature)) {
+ Object oldValue = notification.getOldValue();
+ if(oldValue instanceof EObject) {
+ ((EObject)oldValue).eAdapters().remove(this);
+ }
+
+ // refresh the editors
+ adapter.refreshDisplay();
+ }
+ }
+ break;
+
+ case Notification.REMOVE_MANY:
+ for(EObject eObject : objects) {
+ EStructuralFeature feature = getFeatureByName(eObject);
+ if(notificationFeature.equals(feature)) {
+ for(Object oldValue : ((List<Object>)notification.getOldValue())) {
+ if(oldValue instanceof EObject) {
+ ((EObject)oldValue).eAdapters().add(adapter);
+ }
+ }
+ // refresh the editors
+ adapter.refreshDisplay();
+ }
+ }
+ break;
+ case Notification.SET:
+ case Notification.UNSET:
+ adapter.refreshDisplay();
+ break;
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addListenersToModel(List<? extends EObject> objectsToEdit, EMFPropertyEditorController controller) {
+ for(EObject object : objectsToEdit) {
+ object.eAdapters().add(controller);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removeListenersFromModel(List<? extends EObject> objectsToEdit, EMFPropertyEditorController controller) {
+ for(EObject object : objectsToEdit) {
+ object.eAdapters().remove(controller);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public abstract List<IUndoableOperation> getCreateValueOperations(List<? extends EObject> objectsToEdit, Composite parent);
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean canCreateValueOperations(List<? extends EObject> objectsToEdit) {
+ for(EObject objectToEdit : objectsToEdit) {
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return false;
+ }
+
+ if(!featureToEdit.isChangeable()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IUndoableOperation getDeleteValueOperation(List<? extends EObject> objectsToEdit, Composite parent, List<Integer> indexes) {
+ TransactionalEditingDomain editingDomain = EMFUtils.getTransactionalEditingDomain(objectsToEdit);
+ if(editingDomain == null) {
+ Activator.log.error("Impossible during creation operation to find the editing domain for objects: " + objectsToEdit, null); //$NON-NLS-1$
+ return null;
+ }
+ CompositeTransactionalCommand command = new CompositeTransactionalCommand(editingDomain, "Edit Value"); //$NON-NLS-1$
+ for(EObject objectToEdit : objectsToEdit) {
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return null;
+ }
+ // DeleteStringValueOperation operation = new DeleteStringValueOperation(editingDomain, "Edit Value", objectToEdit, indexes, parent);
+ IUndoableOperation operation = getDeleteStringValueOperation(editingDomain, "Edit Value", objectToEdit, indexes, parent); //$NON-NLS-1$
+ if(operation != null) {
+ command.add(operation);
+ }
+ }
+ return command.reduce();
+ }
+
+ /**
+ * Returns the command to remove String values
+ *
+ * @param editingDomain
+ * the editing domain
+ * @param string
+ * the name of the command
+ * @param objectToEdit
+ * the object to edit
+ * @param indexes
+ * the index of the element to remove
+ * @param parent
+ * the composite parent
+ * @return
+ * the command to remove String values
+ */
+ protected IUndoableOperation getDeleteStringValueOperation(TransactionalEditingDomain editingDomain, String string, EObject objectToEdit, List<Integer> indexes, Composite parent) {
+ CompositeTransactionalCommand command = new CompositeTransactionalCommand(editingDomain, string);
+ // get the feature to modify
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return null;
+ }
+ Object newValue;
+ if(featureToEdit.getUpperBound() == 1) {
+ newValue = featureToEdit.getDefaultValue();
+ } else {
+ @SuppressWarnings("unchecked")
+ List<Object> values = new ArrayList<Object>((List<Object>)getValueToEdit(objectToEdit));
+ for(int index : indexes) {
+ values.remove(index);
+ }
+ newValue = values;
+ }
+ SetRequest[] requests = getSetRequest(editingDomain, objectToEdit, newValue);
+ org.eclipse.papyrus.service.edit.service.IElementEditService provider = org.eclipse.papyrus.service.edit.service.ElementEditServiceUtils.getCommandProvider(objectToEdit);
+ if(provider != null) {
+
+ ICommand editCommand = null;
+ for(SetRequest current : requests) {
+ editCommand = provider.getEditCommand(current);
+
+ if(editCommand != null && editCommand.canExecute()) {
+ command.add(editCommand);
+ }
+ }
+ }
+ return command;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean canCreateDeleteValueOperation(List<? extends EObject> objectsToEdit) {
+ return false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IUndoableOperation getEditValueOperation(List<? extends EObject> objectsToEdit, int index, Composite parent, Object value) {
+ TransactionalEditingDomain editingDomain = EMFUtils.getTransactionalEditingDomain(objectsToEdit);
+ if(editingDomain == null) {
+ Activator.log.error("Impossible during creation operation to find the editing domain for objects: " + objectsToEdit, null); //$NON-NLS-1$
+ return null;
+ }
+ CompositeTransactionalCommand command = new CompositeTransactionalCommand(editingDomain, "Edit Value"); //$NON-NLS-1$
+ for(EObject objectToEdit : objectsToEdit) {
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return null;
+ }
+ // EditStringValueOperation operation = new EditStringValueOperation(editingDomain, "Edit Value", objectToEdit, index, parent, value);
+ IUndoableOperation operation = getEditStringValueOperation(editingDomain, "Edit Value", objectToEdit, index, parent, value); //$NON-NLS-1$
+ if(operation != null) {
+ command.add(operation);
+ }
+ }
+ return command.reduce();
+ }
+
+ /**
+ * Returns the Operation to edit the String value
+ *
+ * @param editingDomain
+ * the editing domain
+ * @param string
+ * the name of the command
+ * @param objectToEdit
+ * the object to edit
+ * @param index
+ * the index of the String to edit
+ * @param parent
+ * the composite parent
+ * @param value
+ * the value to set
+ * @return
+ * the Operation to edit the String value
+ */
+ protected IUndoableOperation getEditStringValueOperation(TransactionalEditingDomain editingDomain, String string, EObject objectToEdit, int index, Composite parent, Object value) {
+ CompositeTransactionalCommand command = new CompositeTransactionalCommand(editingDomain, string);
+ // get the feature to modify
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return null;
+ }
+ Object newValue;
+ if(featureToEdit.getUpperBound() == 1) {
+ newValue = value;
+ } else {
+ @SuppressWarnings("unchecked")
+ List<Object> values = new ArrayList<Object>((List<Object>)getValueToEdit(objectToEdit));
+ values.set(index, value);
+ newValue = values;
+ }
+ SetRequest[] requests = getSetRequest(editingDomain, objectToEdit, newValue);
+ org.eclipse.papyrus.service.edit.service.IElementEditService provider = org.eclipse.papyrus.service.edit.service.ElementEditServiceUtils.getCommandProvider(objectToEdit);
+ if(provider != null) {
+
+ ICommand editCommand = null;
+ for(SetRequest current : requests) {
+ editCommand = provider.getEditCommand(current);
+
+ if(editCommand != null && editCommand.canExecute()) {
+ command.add(editCommand);
+ }
+ }
+ }
+ return command;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean canCreateEditValueOperation(List<? extends EObject> objectsToEdit) {
+ // try to retrieve editor for this property
+ // if one exists, return yes
+ // or try to open an inline-editor for simple values
+ return true;
+ }
+
+ /**
+ * Returns the feature ID
+ *
+ * @param feature
+ * the feature
+ * @param elementToEdit
+ * the element to edit
+ * @return
+ * the feature ID
+ */
+ protected int getFeatureID(EStructuralFeature feature, BasicEObjectImpl elementToEdit) {
+ return (elementToEdit).eDerivedStructuralFeatureID(feature);
+ }
+
+ /**
+ * Returns the structural feature of elementToEdit corresponding to this ID
+ *
+ * @param ID
+ * the ID of the feature
+ * @param elementToEdit
+ * the element to edit
+ * @return
+ * the structural feature of elementToEdit corresponding to this ID
+ */
+ protected EStructuralFeature getStructuralFeature(int ID, EObject elementToEdit) {
+ if(elementToEdit instanceof BasicEObjectImpl) {
+ EClass eClass = elementToEdit.eClass();
+ return eClass.getEStructuralFeature(ID);
+ }
+ return null;
+ }
+
+ // /**
+ // * Operation to edit a String value for the controlled property
+ // */
+ // protected class EditStringValueOperation extends AbstractTransactionalCommand {
+ //
+ // /** object to edit */
+ // protected final EObject objectToEdit;
+ //
+ // /** index of the value to edit */
+ // protected final int index;
+ //
+ // /** composite parent for the editor */
+ // protected final Composite parent;
+ //
+ // /** value to set */
+ // protected final Object value;
+ //
+ // /**
+ // * Initializes me with the editing domain, a label, transaction options, and
+ // * a list of {@link IFile}s that anticipate modifying when I am executed,
+ // * undone or redone.
+ // *
+ // * @param domain
+ // * the editing domain used to modify the model
+ // * @param label
+ // * my user-readable label, should never be <code>null</code>.
+ // * @param objectToEdit
+ // * object to edit
+ // * @param index
+ // * the index of the value to edit
+ // * @param parent
+ // * the graphical composite element
+ // * @param value
+ // */
+ // public EditStringValueOperation(TransactionalEditingDomain domain, String label, EObject objectToEdit, int index, Composite parent, Object value) {
+ // super(domain, (label == null) ? "" : label, null);
+ // this.objectToEdit = objectToEdit;
+ // this.index = index;
+ // this.parent = parent;
+ // this.value = value;
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // @Override
+ // protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+ // // get the feature to modify
+ // EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ // if(featureToEdit == null) {
+ // return CommandResult.newErrorCommandResult("Impossible to find the feature " + getFeatureName());
+ // }
+ // Object newValue;
+ // if(featureToEdit.getUpperBound() == 1) {
+ // newValue = value;
+ // } else {
+ // @SuppressWarnings("unchecked")
+ // List<Object> values = new ArrayList<Object>((List<Object>)getValueToEdit(objectToEdit));
+ // values.set(index, value);
+ // newValue = values;
+ // }
+ // setValueInModel(objectToEdit, newValue);
+ // return CommandResult.newOKCommandResult();
+ // }
+ // }
+
+ // /**
+ // * Operation to edit a String value for the controlled property
+ // */
+ // protected class DeleteStringValueOperation extends AbstractTransactionalCommand {
+ //
+ // /** object to edit */
+ // protected final EObject objectToEdit;
+ //
+ // /** indexes of the value to delete */
+ // protected final List<Integer> indexes;
+ //
+ // /** composite parent for the editor */
+ // protected final Composite parent;
+ //
+ // /**
+ // * Initializes me with the editing domain, a label, transaction options, and
+ // * a list of {@link IFile}s that anticipate modifying when I am executed,
+ // * undone or redone.
+ // *
+ // * @param domain
+ // * the editing domain used to modify the model
+ // * @param label
+ // * my user-readable label, should never be <code>null</code>.
+ // * @param objectToEdit
+ // * object to edit
+ // * @param indexes
+ // * the indexes of the values to remove
+ // * @param parent
+ // * the graphical composite element
+ // */
+ // public DeleteStringValueOperation(TransactionalEditingDomain domain, String label, EObject objectToEdit, List<Integer> indexes, Composite parent) {
+ // super(domain, (label == null) ? "" : label, null);
+ // this.objectToEdit = objectToEdit;
+ // this.indexes = indexes;
+ // this.parent = parent;
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // @Override
+ // protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+ // // get the feature to modify
+ // EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ // if(featureToEdit == null) {
+ // return CommandResult.newErrorCommandResult("Impossible to find the feature " + getFeatureName());
+ // }
+ // Object newValue;
+ // if(featureToEdit.getUpperBound() == 1) {
+ // objectToEdit.eUnset(featureToEdit);
+ // } else {
+ // @SuppressWarnings("unchecked")
+ // List<Object> values = new ArrayList<Object>((List<Object>)getValueToEdit(objectToEdit));
+ // for(int index : indexes) {
+ // values.remove(index);
+ // }
+ // newValue = values;
+ // setValueInModel(objectToEdit, newValue);
+ // }
+ // return CommandResult.newOKCommandResult();
+ // }
+ // }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IUndoableOperation getMoveValueOperation(List<? extends EObject> objectsToEdit, List<Integer> indexes, Composite parent, int delta) {
+ TransactionalEditingDomain editingDomain = EMFUtils.getTransactionalEditingDomain(objectsToEdit);
+ if(editingDomain == null) {
+ Activator.log.error("Impossible during move operation to find the editing domain for objects: " + objectsToEdit, null); //$NON-NLS-1$
+ return null;
+ }
+ CompositeTransactionalCommand command = new CompositeTransactionalCommand(editingDomain, "Move Values"); //$NON-NLS-1$
+ for(EObject objectToEdit : objectsToEdit) {
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return null;
+ }
+ // MoveStringValueOperation operation = new MoveStringValueOperation(editingDomain, "Move Value", objectToEdit, indexes, parent, delta);
+ IUndoableOperation operation = getMoveStringValueOperation(editingDomain, "Move Value", objectToEdit, indexes, parent, delta); //$NON-NLS-1$
+ if(operation != null) {
+ command.add(operation);
+ }
+ }
+ return command.reduce();
+ }
+
+ /**
+ * Returns the command to move String values
+ *
+ * @param editingDomain
+ * the editing domain
+ * @param string
+ * the name of the command
+ * @param objectToEdit
+ * the object to edit
+ * @param indexes
+ * the index of the elements to move
+ * @param parent
+ * the composite parent
+ * @param delta
+ * the delta
+ * @return
+ * the command to move String values
+ */
+ protected IUndoableOperation getMoveStringValueOperation(TransactionalEditingDomain editingDomain, String string, EObject objectToEdit, List<Integer> indexes, Composite parent, int delta) {
+ CompositeTransactionalCommand command = new CompositeTransactionalCommand(editingDomain, string);
+ if(canMoveStringValue(objectToEdit, indexes, delta)) {
+
+ EClass eClass = objectToEdit.eClass();
+ if(eClass == null) {
+ return null;
+ }
+ // retrieve the current value (should be a list)
+ EStructuralFeature feature = getFeatureByName(objectToEdit);
+ Object currentValue = objectToEdit.eGet(feature);
+ if(currentValue instanceof List<?>) {
+ @SuppressWarnings("unchecked")
+ List<Object> values = (List<Object>)currentValue;
+ List<Object> copy = new ArrayList<Object>(values);
+ // make modification in copy list
+ // check indices
+ int min = copy.size();
+ int max = 0;
+
+ for(int index : indexes) {
+ if(index < min) {
+ min = index;
+ }
+ if(index > max) {
+ max = index;
+ }
+ }
+
+ // check that min and max are in the bounds of the list, with the
+ // delta applied
+ min += delta;
+ max += delta;
+ // check the bounds of the list
+ if(min < 0) {
+ Activator.log.debug("Trying to move up the elements, with a move which will cause an IndexOutOfBound exception"); //$NON-NLS-1$
+ return null;
+ } else if(max >= copy.size()) {
+ Activator.log.debug("Trying to move down the elements, with a move which will cause an IndexOutOfBound exception"); //$NON-NLS-1$
+ return null;
+ }
+
+ // now, do the move in the copy
+ if(delta < 0) {
+ moveUpElementsInCollection(copy, indexes, delta);
+ } else {
+ moveDownElementsOperation(copy, indexes, delta);
+ }
+
+ // setValueInModel(objectToEdit, copy);
+ SetRequest[] requests = getSetRequest(editingDomain, objectToEdit, copy);
+ if(requests != null) {
+
+ org.eclipse.papyrus.service.edit.service.IElementEditService provider = org.eclipse.papyrus.service.edit.service.ElementEditServiceUtils.getCommandProvider(objectToEdit);
+ if(provider != null) {
+
+ ICommand editCommand = null;
+ for(SetRequest current : requests) {
+ editCommand = provider.getEditCommand(current);
+
+ if(editCommand != null && editCommand.canExecute()) {
+ command.add(editCommand);
+ }
+ }
+ }
+ }
+ }
+ }
+ return command;
+ }
+
+ /**
+ * Tests if we can move values
+ *
+ * @param objectToEdit
+ * the object to edit
+ * @param indexes
+ * the indexes
+ * @param delta
+ * the delta
+ * @return
+ * <code>true</code> if we can move the values <code>false</code> if not
+ */
+ protected boolean canMoveStringValue(EObject objectToEdit, List<Integer> indexes, int delta) {
+ EClass eClass = objectToEdit.eClass();
+ if(eClass == null) {
+ return false;
+ }
+ // retrieve the current value (should be a list)
+ EStructuralFeature feature = getFeatureByName(objectToEdit);
+ Object currentValue = objectToEdit.eGet(feature);
+ if(currentValue instanceof List<?>) {
+ @SuppressWarnings("unchecked")
+ List<Object> values = (List<Object>)currentValue;
+ List<Object> copy = new ArrayList<Object>(values);
+ // make modification in copy list
+ // check indices
+ int min = copy.size();
+ int max = 0;
+
+ for(int index : indexes) {
+ if(index < min) {
+ min = index;
+ }
+ if(index > max) {
+ max = index;
+ }
+ }
+
+ // check that min and max are in the bounds of the list, with the
+ // delta applied
+ min += delta;
+ max += delta;
+ // check the bounds of the list
+ if(min < 0) {
+ return false;
+ } else if(max >= copy.size()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean canCreateMoveValueOperation(List<? extends EObject> objectsToEdit, List<Integer> indexes, Composite parent, int delta) {
+ TransactionalEditingDomain editingDomain = EMFUtils.getTransactionalEditingDomain(objectsToEdit);
+ if(editingDomain == null) {
+ Activator.log.error("Impossible during move operation to find the editing domain for objects: " + objectsToEdit, null); //$NON-NLS-1$
+ return false;
+ }
+ CompositeTransactionalCommand command = new CompositeTransactionalCommand(editingDomain, "Move Values"); //$NON-NLS-1$
+ for(EObject objectToEdit : objectsToEdit) {
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return false;
+ }
+ //MoveStringValueOperation operation = new MoveStringValueOperation(editingDomain, "Move Value", objectToEdit, indexes, parent, delta);
+ IUndoableOperation operation = getMoveStringValueOperation(editingDomain, "Move Value", objectToEdit, indexes, parent, delta); //$NON-NLS-1$
+ if(operation != null) {
+ command.add(operation);
+ }
+ }
+ return command.canExecute();
+ }
+
+ /**
+ * Moves the element in the specified list, when the elements are moved down
+ * in the list
+ *
+ * @param modifiedElements
+ * list of elements modified
+ * @param indexes
+ * list of indexes of objects to move
+ * @param move
+ * delta for the move. should be positive integer
+ */
+ protected void moveDownElementsOperation(List<Object> modifiedElements, List<Integer> indexes, int move) {
+ // if moving down, starting from the end to move elements, assuming they
+ // are in the increasing order by default
+ Collections.sort(indexes);
+ Collections.reverse(indexes);
+ for(int index : indexes) {
+ Object objectToMove = modifiedElements.get(index);
+ // remove element
+ modifiedElements.remove(index);
+ // change index
+ if(index == -1) {
+ return;
+ }
+ index += move;
+ // add the element to the new index
+ modifiedElements.add(index, objectToMove);
+ }
+ }
+
+ /**
+ * Moves the element in the specified list, when the elements are moved up
+ * in the list
+ *
+ * @param modifiedElements
+ * list of elements modified
+ * @param indexes
+ * list of indexes of objects to move
+ * @param move
+ * delta for the move. should be positive integer
+ */
+ protected void moveUpElementsInCollection(List<Object> modifiedElements, List<Integer> indexes, int move) {
+ Collections.sort(indexes);
+ for(int index : indexes) {
+ // retrieve index
+ Object objectToMove = modifiedElements.get(index);
+ // remove element
+ modifiedElements.remove(index);
+ // change index
+ if(index == -1) {
+ return;
+ }
+ index += move;
+ // add the element to the new index
+ modifiedElements.add(index, objectToMove);
+ }
+ }
+
+ // /**
+ // * Operation to edit a String value for the controlled property
+ // */
+ // protected class MoveStringValueOperation extends AbstractTransactionalCommand {
+ //
+ // /** object to edit */
+ // protected final EObject objectToEdit;
+ //
+ // /** indexes of the value to delete */
+ // protected final List<Integer> indexes;
+ //
+ // /** composite parent for the editor */
+ // protected final Composite parent;
+ //
+ // /** delta applied to all indexes */
+ // protected final int delta;
+ //
+ // /**
+ // * Initializes me with the editing domain, a label, transaction options, and
+ // * a list of {@link IFile}s that anticipate modifying when I am executed,
+ // * undone or redone.
+ // *
+ // * @param domain
+ // * the editing domain used to modify the model
+ // * @param label
+ // * my user-readable label, should never be <code>null</code>.
+ // * @param objectToEdit
+ // * object to edit
+ // * @param indexes
+ // * the indexes of the values to remove
+ // * @param parent
+ // * the graphical composite element
+ // * @param delta
+ // * the delta applied to all indexes
+ // */
+ // public MoveStringValueOperation(TransactionalEditingDomain domain, String label, EObject objectToEdit, List<Integer> indexes, Composite parent, int delta) {
+ // super(domain, (label == null) ? "" : label, null);
+ // this.objectToEdit = objectToEdit;
+ // this.indexes = indexes;
+ // this.parent = parent;
+ // this.delta = delta;
+ // }
+ //
+ // @Override
+ // public boolean canExecute() {
+ // EClass eClass = objectToEdit.eClass();
+ // if(eClass == null) {
+ // return false;
+ // }
+ // // retrieve the current value (should be a list)
+ // EStructuralFeature feature = getFeatureByName(objectToEdit);
+ // Object currentValue = objectToEdit.eGet(feature);
+ // if(currentValue instanceof List<?>) {
+ // @SuppressWarnings("unchecked")
+ // List<Object> values = (List<Object>)currentValue;
+ // List<Object> copy = new ArrayList<Object>(values);
+ // // make modification in copy list
+ // // check indices
+ // int min = copy.size();
+ // int max = 0;
+ //
+ // for(int index : indexes) {
+ // if(index < min) {
+ // min = index;
+ // }
+ // if(index > max) {
+ // max = index;
+ // }
+ // }
+ //
+ // // check that min and max are in the bounds of the list, with the
+ // // delta applied
+ // min += delta;
+ // max += delta;
+ // // check the bounds of the list
+ // if(min < 0) {
+ // return false;
+ // } else if(max >= copy.size()) {
+ // return false;
+ // }
+ // }
+ // return true;
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // @Override
+ // protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+ // EClass eClass = objectToEdit.eClass();
+ // if(eClass == null) {
+ // return CommandResult.newErrorCommandResult("Impossible to find the EClass for object: " + objectToEdit);
+ // }
+ // // retrieve the current value (should be a list)
+ // EStructuralFeature feature = getFeatureByName(objectToEdit);
+ // Object currentValue = objectToEdit.eGet(feature);
+ // if(currentValue instanceof List<?>) {
+ // @SuppressWarnings("unchecked")
+ // List<Object> values = (List<Object>)currentValue;
+ // List<Object> copy = new ArrayList<Object>(values);
+ // // make modification in copy list
+ // // check indices
+ // int min = copy.size();
+ // int max = 0;
+ //
+ // for(int index : indexes) {
+ // if(index < min) {
+ // min = index;
+ // }
+ // if(index > max) {
+ // max = index;
+ // }
+ // }
+ //
+ // // check that min and max are in the bounds of the list, with the
+ // // delta applied
+ // min += delta;
+ // max += delta;
+ // // check the bounds of the list
+ // if(min < 0) {
+ // Activator.log.debug("Trying to move up the elements, with a move which will cause an IndexOutOfBound exception");
+ // return CommandResult.newErrorCommandResult("Trying to move up the elements, with a move which will cause an IndexOutOfBound exception");
+ // } else if(max >= copy.size()) {
+ // Activator.log.debug("Trying to move down the elements, with a move which will cause an IndexOutOfBound exception");
+ // return CommandResult.newErrorCommandResult("Trying to move down the elements, with a move which will cause an IndexOutOfBound exception");
+ // }
+ //
+ // // now, do the move in the copy
+ // if(delta < 0) {
+ // moveUpElementsInCollection(copy, indexes, delta);
+ // } else {
+ // moveDownElementsOperation(copy, indexes, delta);
+ // }
+ //
+ // setValueInModel(objectToEdit, copy);
+ // }
+ //
+ // return CommandResult.newOKCommandResult();
+ // }
+ // }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFFeatureModelHandlerState.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFFeatureModelHandlerState.java
new file mode 100644
index 00000000000..01781e7b34d
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFFeatureModelHandlerState.java
@@ -0,0 +1,143 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.state.AbstractState;
+import org.eclipse.papyrus.properties.runtime.state.ITraversableModelElement;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+
+/**
+ * State for model handlers
+ */
+public class EMFFeatureModelHandlerState extends AbstractState implements IEMFModelHandlerState {
+
+ /** managed model handler */
+ private EMFFeatureModelHandler modelHandler;
+
+ /** change support */
+ private PropertyChangeSupport changeSupport;
+
+ /** name of the feature to edit */
+ private String name;
+
+ /** id of the model handler */
+ private String id;
+
+ /**
+ * Creates a new EMFFeatureModelHandlerState.
+ *
+ * @param modelHandler
+ * managed model handler
+ *
+ * @param readOnly
+ */
+ public EMFFeatureModelHandlerState(IEMFModelHandler modelHandler, boolean readOnly) {
+ super(readOnly);
+ assert (modelHandler instanceof EMFFeatureModelHandler);
+ this.modelHandler = (EMFFeatureModelHandler)modelHandler;
+ this.name = ((EMFFeatureModelHandler)modelHandler).getFeatureName();
+ this.id = ((EMFFeatureModelHandler)modelHandler).getId();
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public EMFFeatureModelHandler getDescriptor() {
+ return modelHandler;
+ }
+
+ /**
+ * Sets the name
+ *
+ * @param name
+ * the name to set
+ */
+ public void setName(String name) {
+ changeSupport.firePropertyChange("name", this.name, this.name = name);
+ }
+
+ /**
+ * Returns the name
+ *
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEditionDialogId() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Element generateNode(Document document) {
+ //<feature name="ownedAttribute" handlerID="Reference"/>
+ Element element = document.createElement("feature");
+ element.setAttribute("name", name);
+ element.setAttribute("handlerID", id);
+ return element;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<? extends ITraversableModelElement> getChildren() {
+ return Collections.emptyList();
+ }
+
+ /**
+ * Sets the id
+ *
+ * @param id
+ * the id to set
+ */
+ public void setId(String id) {
+ changeSupport.firePropertyChange("id", this.id, this.id = id);
+ }
+
+ /**
+ * Returns the id
+ *
+ * @return the id
+ */
+ public String getId() {
+ return id;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFModelHandlerFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFModelHandlerFactory.java
new file mode 100644
index 00000000000..9110c3d2e8c
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFModelHandlerFactory.java
@@ -0,0 +1,48 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import org.eclipse.papyrus.properties.runtime.modelhandler.IPropertyModelHandlerFactory;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+
+/**
+ * Abstract factory for EMF Model Handlers
+ */
+public abstract class EMFModelHandlerFactory implements IPropertyModelHandlerFactory {
+
+ /**
+ * {@inheritDoc}
+ */
+ public abstract IEMFModelHandler createModelHandler(Node modelHandlerNode);
+
+ /**
+ * Retrieve the name of the feature to modify, from a given configuration node
+ *
+ * @param node
+ * the configuration node
+ * @return the name of the feature to modify or <code>null</code>
+ */
+ protected String retrieveFeatureName(Node node) {
+ String featureName = null;
+ NamedNodeMap featureAttributes = node.getAttributes();
+ if(featureAttributes != null) {
+ Node featureNameNode = featureAttributes.getNamedItem("name");
+ if(featureNameNode != null) {
+ featureName = featureNameNode.getNodeValue();
+ }
+ }
+ return featureName;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFStereotypeFeatureModelHandler.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFStereotypeFeatureModelHandler.java
new file mode 100644
index 00000000000..fe5203e4774
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFStereotypeFeatureModelHandler.java
@@ -0,0 +1,310 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ * Vincent Lorenzo (CEA-LIST) vincent.lorenzo@cea.fr
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.edit.provider.IItemPropertyDescriptor;
+import org.eclipse.emf.edit.provider.IItemPropertySource;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.EMFPropertyEditorController;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Property;
+import org.eclipse.uml2.uml.Stereotype;
+import org.eclipse.uml2.uml.StructuralFeature;
+
+
+/**
+ * Abstract Model handler for stereotype properties
+ */
+public abstract class EMFStereotypeFeatureModelHandler extends EMFFeatureModelHandler {
+
+ /** name of the stereotype to edit */
+ private final String stereotypeName;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void addListenersToModel(List<? extends EObject> objectsToEdit, EMFPropertyEditorController controller) {
+ super.addListenersToModel(objectsToEdit, controller);
+ for(EObject object : objectsToEdit) {
+ if(object instanceof Element) {
+ Iterator<EObject> it = ((Element)object).getStereotypeApplications().iterator();
+ while(it.hasNext()) {
+ it.next().eAdapters().add(controller);
+ }
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removeListenersFromModel(List<? extends EObject> objectsToEdit, EMFPropertyEditorController controller) {
+ super.removeListenersFromModel(objectsToEdit, controller);
+ for(EObject object : objectsToEdit) {
+ if(object instanceof Element) {
+ Iterator<EObject> it = ((Element)object).getStereotypeApplications().iterator();
+ while(it.hasNext()) {
+ it.next().eAdapters().remove(controller);
+ }
+ }
+ }
+ }
+
+ /**
+ * Creates a new EMFStereotypeFeatureModelHandler.
+ *
+ * @param stereotypeName
+ * name of the stereotype to which this feature belongs
+ *
+ * @param featureName
+ * he name of the feature to edit
+ */
+ public EMFStereotypeFeatureModelHandler(String stereotypeName, String featureName) {
+ super(featureName);
+ this.stereotypeName = stereotypeName;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public EStructuralFeature getFeatureByName(EObject objectToEdit) {
+ if(objectToEdit instanceof Element) {
+ return EMFUtils.getStereotypeFeatureByName((Element)objectToEdit, retrieveStereotype((Element)objectToEdit), getFeatureName());
+ }
+ Activator.log.error("Impossible to cast into UML element: " + objectToEdit, null); //$NON-NLS-1$
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getAvailableValues(EObject eObject) {
+ EClass eClass = eObject.eClass();
+ if(eClass == null) {
+ Activator.log.debug("problems during initialization, looking for availables values"); //$NON-NLS-1$
+ return null;
+ }
+ EStructuralFeature feature = getFeatureByName(eObject);
+ if(!(feature instanceof EReference)) {
+ Activator.log.debug("feature is not a reference, looking for availables values: " + feature); //$NON-NLS-1$
+ return null;
+ }
+
+ IItemPropertySource itemPropertySource = (IItemPropertySource)factory.adapt(((Element)eObject).getStereotypeApplication(retrieveStereotype((Element)eObject)), IItemPropertySource.class);
+ if(itemPropertySource == null) {
+ Activator.log.debug("impossible to find item Property source for " + retrieveStereotype((Element)eObject)); //$NON-NLS-1$
+ return null;
+ }
+ IItemPropertyDescriptor itemPropertyDescriptor = itemPropertySource.getPropertyDescriptor(retrieveStereotype((Element)eObject), feature);
+ if(itemPropertyDescriptor == null) {
+ Activator.log.debug("impossible to find item Property descriptor for " + retrieveStereotype((Element)eObject) + " and " + feature); //$NON-NLS-1$ //$NON-NLS-2$
+ return null;
+ }
+ return itemPropertyDescriptor.getChoiceOfValues(eObject);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getValueToEdit(EObject objectToEdit) {
+ if(!(objectToEdit instanceof Element)) {
+ Activator.log.warn("the object to edit is not a UML2 Element: " + objectToEdit); //$NON-NLS-1$
+ return null;
+ }
+ Element elementToEdit = (Element)objectToEdit;
+ Stereotype stereotype = retrieveStereotype(elementToEdit);
+ if(stereotype != null) {
+ return getValueForElement(elementToEdit, stereotype);
+ } else {
+ Activator.log.warn("Impossible to get the stereotype: " + stereotypeName + " on the element: " + elementToEdit + " for feature " + getFeatureName()); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+ return null;
+ }
+
+ /**
+ * Returns the value for the given element
+ *
+ * @param elementToEdit
+ * the element being edited
+ * @param stereotype
+ * the stereotype to edit
+ * @return the value of the stereotype feature
+ */
+ protected Object getValueForElement(Element elementToEdit, Stereotype stereotype) {
+ return elementToEdit.getValue(stereotype, getFeatureName());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setValueInModel(EObject objectToEdit, Object newValue) {
+ if(!(objectToEdit instanceof Element)) {
+ Activator.log.warn("the object to edit is not a UML2 Element: " + objectToEdit); //$NON-NLS-1$
+ return;
+ }
+ Element elementToEdit = (Element)objectToEdit;
+ Stereotype stereotype = retrieveStereotype(elementToEdit);
+ if(stereotype != null) {
+ setValueForElement(elementToEdit, stereotype, newValue);
+ } else {
+ Activator.log.warn("Impossible to set value to the stereotype: " + stereotypeName + " on the element: " + elementToEdit); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ /**
+ * Sets the given value to the stereotype of the element
+ *
+ * @param elementToEdit
+ * the element to modify
+ * @param stereotype
+ * the stereotype that contains the feature to modify
+ * @param newValue
+ * the new value for the feature
+ */
+ protected void setValueForElement(Element elementToEdit, Stereotype stereotype, Object newValue) {
+ elementToEdit.setValue(stereotype, getFeatureName(), newValue);
+ }
+
+ /**
+ * Retrieve the stereotype given its qualified name
+ *
+ * @param elementToEdit
+ * the element being edited
+ * @return the stereotype found or <code>null</code> if no stereotype was found
+ */
+ protected Stereotype retrieveStereotype(Element elementToEdit) {
+ return elementToEdit.getAppliedStereotype(getStereotypeName());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void completeEditorDescriptor(IPropertyEditorDescriptor descriptor, List<? extends EObject> objectToEdit) {
+
+ }
+
+ /**
+ * Returns the name of the stereotype to edit
+ *
+ * @return the name of the stereotype to edit
+ */
+ public String getStereotypeName() {
+ return stereotypeName;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isChangeable(List<? extends EObject> objectsToEdit) {
+ if(objectsToEdit.size() < 1) {
+ return false;
+ }
+
+ Element element = retrieveElement(objectsToEdit);
+ if(element == null) {
+ return false;
+ }
+
+ // retrieve the feature
+ Stereotype stereotype = retrieveStereotype(element);
+ if(stereotype == null) {
+ return false;
+ }
+
+ StructuralFeature feature = retrieveStructuralFeature(element, stereotype);
+ return (feature != null) ? !feature.isReadOnly() : false;
+ }
+
+ /**
+ * Retrieve the element to edit
+ *
+ * @param objectToEdit
+ * the list of objects selected
+ * @return the element or null
+ */
+ protected Element retrieveElement(List<? extends EObject> objectToEdit) {
+ if(objectToEdit.size() < 1) {
+ return null;
+ }
+
+ EObject firstObject = objectToEdit.get(0);
+ if(!(firstObject instanceof Element)) {
+ Activator.log.warn("Object to edit should be a UML2 element: " + firstObject); //$NON-NLS-1$
+ return null;
+ }
+
+ Element elementToEdit = (Element)firstObject;
+ return elementToEdit;
+ }
+
+ /**
+ * Retrieves the structural feature
+ *
+ * @param elementToEdit
+ * the element for wich the structural feature should be retrieved
+ * @param stereotype
+ * the stereotype for which the structural feature should be retrieved
+ *
+ * @return the structural feature
+ */
+ protected StructuralFeature retrieveStructuralFeature(Element elementToEdit, Stereotype stereotype) {
+ for(Property property : stereotype.getAllAttributes()) {
+ if(getFeatureName().equals(property.getName())) {
+ return property;
+ }
+ }
+ Activator.log.warn("No feature fond with name:" + getFeatureName() + " for stereotype " + stereotypeName); //$NON-NLS-1$ //$NON-NLS-2$
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IEMFModelHandlerState createState(boolean readOnly) {
+ return new EMFStereotypeFeatureModelHandlerState(this, readOnly);
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.properties.runtime.modelhandler.emf.IEMFModelHandler#getSetRequest(org.eclipse.emf.transaction.TransactionalEditingDomain,
+ * org.eclipse.emf.ecore.EObject, java.lang.Object)
+ *
+ * @param domain
+ * @param objectToEdit
+ * @param newValue
+ * @return
+ */
+ public SetRequest[] getSetRequest(TransactionalEditingDomain domain, EObject objectToEdit, Object newValue) {
+ return null; //TODO
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFStereotypeFeatureModelHandlerState.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFStereotypeFeatureModelHandlerState.java
new file mode 100644
index 00000000000..4287457c429
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFStereotypeFeatureModelHandlerState.java
@@ -0,0 +1,111 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.state.ITraversableModelElement;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+
+
+/**
+ * State for model handlers
+ */
+public class EMFStereotypeFeatureModelHandlerState extends EMFFeatureModelHandlerState {
+
+ /** managed model handler */
+ private String stereotypeName;
+
+ /** change support */
+ private PropertyChangeSupport changeSupport;
+
+ /**
+ * Creates a new EMFFeatureModelHandlerState.
+ *
+ * @param modelHandler
+ * the model handler to manage
+ *
+ * @param readOnly
+ */
+ public EMFStereotypeFeatureModelHandlerState(IEMFModelHandler modelHandler, boolean readOnly) {
+ super(modelHandler, readOnly);
+ stereotypeName = getDescriptor().getStereotypeName();
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public EMFStereotypeFeatureModelHandler getDescriptor() {
+ return (EMFStereotypeFeatureModelHandler)super.getDescriptor();
+ }
+
+ /**
+ * Sets the stereotypeName
+ *
+ * @param stereotypeName
+ * the stereotypeName to set
+ */
+ public void setStereotypeName(String stereotypeName) {
+ changeSupport.firePropertyChange("stereotypeName", this.stereotypeName, this.stereotypeName = stereotypeName);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ super.addPropertyChangeListener(listener);
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ super.removePropertyChangeListener(listener);
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+
+ /**
+ * Returns the stereotypeName
+ *
+ * @return the stereotypeName
+ */
+ public String getStereotypeName() {
+ return stereotypeName;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Element generateNode(Document document) {
+ Element element = super.generateNode(document);
+ element.setAttribute("stereotypeName", stereotypeName);
+ return element;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<? extends ITraversableModelElement> getChildren() {
+ return Collections.emptyList();
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFUtils.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFUtils.java
new file mode 100644
index 00000000000..90ef012180e
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EMFUtils.java
@@ -0,0 +1,113 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import java.util.Iterator;
+import java.util.List;
+
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.transaction.util.TransactionUtil;
+import org.eclipse.papyrus.core.utils.EditorUtils;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.uml2.common.util.UML2Util;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.NamedElement;
+import org.eclipse.uml2.uml.Stereotype;
+
+
+/**
+ * Util class for EMF and UML
+ */
+public class EMFUtils {
+
+ /**
+ * Retrieve a {@link EStructuralFeature} by its name
+ *
+ * @param objectToEdit
+ * the object being edited
+ * @param featureName
+ * the name of the feature to retrieve
+ * @return the feature found <code>null</code> if not found
+ */
+ public static EStructuralFeature getFeatureByName(EObject objectToEdit, String featureName) {
+ EStructuralFeature feature = objectToEdit.eClass().getEStructuralFeature(featureName);
+ if(feature != null) {
+ return feature;
+ }
+ Activator.log.error("impossible to find feature " + featureName + " for object " + objectToEdit, null);
+ return null;
+ }
+
+ /**
+ * Retrieve the stereotype structural feature
+ *
+ * @param elementToEdit
+ * the UML element on which the stereotype is applied
+ * @param stereotype
+ * the stereotype for which estructural feature is searched
+ * @param featureName
+ * the name of the feature to find
+ * @return the feature found or <code>null</code>
+ */
+ public static EStructuralFeature getStereotypeFeatureByName(Element elementToEdit, Stereotype stereotype, String featureName) {
+ EObject eObject = elementToEdit.getStereotypeApplication(stereotype);
+
+ if(eObject == null) {
+ Activator.log.error("Impossible to find stereotype application", null);
+ return null;
+ }
+
+ EClass eClass = eObject.eClass();
+ String[] segments = featureName.split(NamedElement.SEPARATOR);
+
+ String segment = segments[0];
+ EStructuralFeature eStructuralFeature = null;
+
+ if(segment.indexOf('[') == -1) {
+ eStructuralFeature = eClass.getEStructuralFeature(UML2Util.getValidJavaIdentifier(segment));
+ } else {
+ eStructuralFeature = eClass.getEStructuralFeature(UML2Util.getValidJavaIdentifier(segment.substring(0, segment.indexOf('['))));
+ }
+
+ if(eStructuralFeature == null) {
+ Activator.log.error("Impossible to find structural feature", null);
+ return null;
+ }
+
+ return eStructuralFeature;
+ }
+
+ /**
+ * Returns the editing domain for a set of elements
+ *
+ * @param objects
+ * the objects from which the editing domain can be retrieved
+ * @return the editing domain found or <code>null</code>
+ */
+ public static TransactionalEditingDomain getTransactionalEditingDomain(List<? extends Object> objects) {
+ TransactionalEditingDomain editingDomain = null;
+ Iterator<? extends Object> it2 = objects.iterator();
+ while(it2.hasNext() && editingDomain == null) {
+ editingDomain = TransactionUtil.getEditingDomain(it2.next());
+ }
+
+ // if impossible to find editing domain this way: Tries the Papyrus service
+ if(editingDomain == null) {
+ editingDomain = EditorUtils.getTransactionalEditingDomain();
+ }
+ return editingDomain;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EnumerationEMFModelHandler.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EnumerationEMFModelHandler.java
new file mode 100644
index 00000000000..9c54bd305e9
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EnumerationEMFModelHandler.java
@@ -0,0 +1,344 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ * Vincent Lorenzo (CEA-LIST) vincent.lorenzo@cea.fr
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.commands.operations.IUndoableOperation;
+import org.eclipse.emf.common.util.Enumerator;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EEnumLiteral;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand;
+import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IBoundedValuesPropertyEditorDescriptor;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.swt.widgets.Composite;
+
+/**
+ * Model Handler for enumeration
+ */
+public class EnumerationEMFModelHandler extends EMFFeatureModelHandler {
+
+ /**
+ * Creates a new EnumerationEMFModelHandler.
+ *
+ * @param featureName
+ * the name of the feature to edit
+ */
+ public EnumerationEMFModelHandler(String featureName) {
+ super(featureName);
+ }
+
+
+ /** id of this model handler */
+ public static final String ID = "Enumeration"; //$NON-NLS-1$
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getValueToEdit(EObject objectToEdit) {
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return null;
+ }
+ Object value = objectToEdit.eGet(featureToEdit);
+ return (value instanceof Enumerator) ? ((Enumerator)value).getLiteral() : value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setValueInModel(EObject objectToEdit, Object newValue) {
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return;
+ }
+ // remove value if result of the editor is empty
+ if(newValue == null || newValue.equals("")) { //$NON-NLS-1$
+ objectToEdit.eUnset(featureToEdit);
+ } else {
+ // retrieve the real value for the enumeration
+ if(newValue instanceof String) {
+ EEnum type = (EEnum)featureToEdit.getEType();
+ EEnumLiteral literal = type.getEEnumLiteral((String)newValue);
+ Enumerator instance = literal.getInstance();
+ objectToEdit.eSet(featureToEdit, instance);
+ }
+ }
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void completeEditorDescriptor(IPropertyEditorDescriptor descriptor, List<? extends EObject> objectToEdit) {
+ if(objectToEdit.size() < 1) {
+ return;
+ }
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit.get(0));
+ if(featureToEdit == null) {
+ return;
+ }
+
+
+ // test enumeration, reference, etc.
+ List<String> values = new ArrayList<String>();
+
+ // check if there is an empty string at the beginning. there is one if the lower bound of the feature to edit equal 0
+ if(featureToEdit.getLowerBound() == 0) {
+ values.add(""); //$NON-NLS-1$
+ }
+
+ if(featureToEdit.getEType() instanceof EEnum) {
+ EEnum type = ((EEnum)featureToEdit.getEType());
+ for(EEnumLiteral literal : type.getELiterals()) {
+ values.add(literal.getLiteral());
+ }
+ }
+ if(descriptor instanceof IBoundedValuesPropertyEditorDescriptor) {
+ ((IBoundedValuesPropertyEditorDescriptor)descriptor).setAvailableValues(values);
+ } else {
+ Activator.log.warn("Warning: " + descriptor + "could not be completed."); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getId() {
+ return ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<IUndoableOperation> getCreateValueOperations(List<? extends EObject> objectsToEdit, Composite parent) {
+
+ List<IUndoableOperation> operations = new ArrayList<IUndoableOperation>(1);
+ TransactionalEditingDomain editingDomain = EMFUtils.getTransactionalEditingDomain(objectsToEdit);
+ if(editingDomain == null) {
+ Activator.log.error("Impossible during creation operation to find the editing domain for objects: " + objectsToEdit, null); //$NON-NLS-1$
+ return null;
+ }
+ int indexOfNewValue = NEW_VALUE_NOT_SET_INDEX;
+ CompositeTransactionalCommand command = new CompositeTransactionalCommand(editingDomain, "Create new Enumeration Value"); //$NON-NLS-1$
+ for(EObject objectToEdit : objectsToEdit) {
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return null;
+ }
+ // CreateEnumerationValueOperation operation = new CreateEnumerationValueOperation(editingDomain, "Create new Enumeration Value", objectToEdit);
+ IUndoableOperation operation = getCreateEnumerationValueOperation(editingDomain, "Create new Enumeration Value", objectToEdit); //$NON-NLS-1$
+ if(operation != null) {
+ command.add(operation);
+ }
+ if(indexOfNewValue == NEW_VALUE_NOT_SET_INDEX) { // try to update
+ }
+ }
+
+ operations.add(command.reduce());
+
+ return operations;
+ }
+
+ /**
+ * Returns the command to edit the object
+ *
+ * @param editingDomain
+ * the editing domain
+ * @param string
+ * the name of the command
+ * @param objectToEdit
+ * the object to edit
+ * @return
+ * the command to edit the object
+ */
+ protected IUndoableOperation getCreateEnumerationValueOperation(TransactionalEditingDomain editingDomain, String string, EObject objectToEdit) {
+ CompositeTransactionalCommand command = new CompositeTransactionalCommand(editingDomain, string);
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ Activator.log.error("Impossible to find the feature " + getFeatureName(), null); //$NON-NLS-1$
+ return command;
+ }
+
+ // create the value and add it to the feature
+ // if feature = simple valued => set
+ // if feature = multi valued => add at the end
+
+ Object newValue;
+ if(featureToEdit.getUpperBound() == 1) {
+ newValue = getInitialValue(objectToEdit);
+ } else {
+ @SuppressWarnings("unchecked")
+ List<Object> values = new ArrayList<Object>((List<Object>)getValueToEdit(objectToEdit));
+ values.add(values.size(), getInitialValue(objectToEdit));
+ newValue = values;
+ }
+
+ SetRequest[] requests = getSetRequest(editingDomain, objectToEdit, newValue);
+ if(requests != null) {
+
+ org.eclipse.papyrus.service.edit.service.IElementEditService provider = org.eclipse.papyrus.service.edit.service.ElementEditServiceUtils.getCommandProvider(objectToEdit);
+ if(provider != null) {
+
+ ICommand editCommand = null;
+ for(SetRequest current : requests) {
+ editCommand = provider.getEditCommand(current);
+
+ if(editCommand != null && editCommand.canExecute()) {
+ command.add(editCommand);
+ }
+ }
+ }
+ }
+ return command;
+ }
+
+ // /**
+ // * Operation to create a Enumeration value for the controlled property
+ // */
+ // protected class CreateEnumerationValueOperation extends AbstractTransactionalCommand {
+ //
+ // /** object to edit */
+ // protected final EObject objectToEdit;
+ //
+ // /** index of the value to add (-1 in case of single valued property) */
+ // private int indexOfNewValue = -2;
+ //
+ // /**
+ // * Initializes me with the editing domain, a label, transaction options, and
+ // * a list of {@link IFile}s that anticipate modifying when I am executed,
+ // * undone or redone.
+ // *
+ // * @param domain
+ // * the editing domain used to modify the model
+ // * @param label
+ // * my user-readable label, should never be <code>null</code>.
+ // * @param objectToEdit
+ // * the {@link EObject} to edit
+ // */
+ // public CreateEnumerationValueOperation(TransactionalEditingDomain domain, String label, EObject objectToEdit) {
+ // super(domain, (label == null) ? "" : label, null);
+ // this.objectToEdit = objectToEdit;
+ //
+ // EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ // if(featureToEdit.getUpperBound() == 1) {
+ // indexOfNewValue = -1;
+ // } else {
+ // @SuppressWarnings("unchecked")
+ // List<Object> values = new ArrayList<Object>((List<Object>)getValueToEdit(objectToEdit));
+ // indexOfNewValue = values.size();
+ // }
+ // }
+ //
+ // /**
+ // * Returns the index at which the value will be added
+ // *
+ // * @return the index at which the value will be added
+ // */
+ // public int getIndexOfNewValue() {
+ // return indexOfNewValue;
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // @Override
+ // protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+ // // create the value and add it to the feature
+ // // if feature = simple valued => set
+ // // if feature = multi valued => add at the end
+ // EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ // if(featureToEdit == null) {
+ // return CommandResult.newErrorCommandResult("Impossible to find the feature " + getFeatureName());
+ // }
+ // Object newValue;
+ // if(featureToEdit.getUpperBound() == 1) {
+ // newValue = getInitialValue(objectToEdit);
+ // } else {
+ // @SuppressWarnings("unchecked")
+ // List<Object> values = new ArrayList<Object>((List<Object>)getValueToEdit(objectToEdit));
+ // values.add(indexOfNewValue, getInitialValue(objectToEdit));
+ // newValue = values;
+ // }
+ // setValueInModel(objectToEdit, newValue);
+ // return CommandResult.newOKCommandResult();
+ // }
+ // }
+
+ /**
+ * Returns the initial value for a new value of the feature
+ *
+ * @param objectToEdit
+ * the object to edit
+ *
+ * @return the initial value, not <code>null</code>
+ */
+ public Object getInitialValue(EObject objectToEdit) {
+ String featureName = getFeatureName();
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit.getUpperBound() == 1) {
+ return featureName;
+ } else {
+ EClassifier eClassifier = featureToEdit.getEType();
+ if(eClassifier instanceof EEnum) {
+ return ((EEnum)eClassifier).getDefaultValue();
+ } else if(Boolean.TYPE.isAssignableFrom(eClassifier.getInstanceClass())) {
+ return Boolean.TRUE;
+ }
+ Activator.log.error("Impossible to find a default value", null); //$NON-NLS-1$
+ return null;
+ }
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.properties.runtime.modelhandler.emf.IEMFModelHandler#getSetRequest(org.eclipse.emf.transaction.TransactionalEditingDomain,
+ * org.eclipse.emf.ecore.EObject, java.lang.Object)
+ *
+ * @param domain
+ * @param objectToEdit
+ * @param newValue
+ * @return
+ */
+ public SetRequest[] getSetRequest(TransactionalEditingDomain domain, EObject objectToEdit, Object newValue) {
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return null;
+ }
+ // remove value if result of the editor is empty
+ if(newValue == null || newValue.equals("")) { //$NON-NLS-1$
+ return new SetRequest[]{ new SetRequest(domain, objectToEdit, featureToEdit, featureToEdit.getDefaultValue()) };
+ } else {
+ // retrieve the real value for the enumeration
+ if(newValue instanceof String) {
+ EEnum type = (EEnum)featureToEdit.getEType();
+ EEnumLiteral literal = type.getEEnumLiteral((String)newValue);
+ Enumerator instance = literal.getInstance();
+ return new SetRequest[]{ new SetRequest(domain, objectToEdit, featureToEdit, instance) };
+ }
+ }
+ return null;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EnumerationEMFModelHandlerFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EnumerationEMFModelHandlerFactory.java
new file mode 100644
index 00000000000..f9f4e3c31e7
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EnumerationEMFModelHandlerFactory.java
@@ -0,0 +1,45 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.modelhandler.IPropertyModelHandlerFactory;
+import org.w3c.dom.Node;
+
+
+/**
+ * Factory that creates {@link EnumerationEMFModelHandler}.
+ */
+public class EnumerationEMFModelHandlerFactory extends EMFModelHandlerFactory implements IPropertyModelHandlerFactory {
+
+ /**
+ * Creates a new EnumerationEMFModelHandlerFactory.
+ */
+ public EnumerationEMFModelHandlerFactory() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public EnumerationEMFModelHandler createModelHandler(Node modelHandlerNode) {
+ // specific code to parse the given element
+ String featureName = retrieveFeatureName(modelHandlerNode);
+
+ if(featureName == null) {
+ Activator.log.warn("Impossible to retrieve feature from node " + modelHandlerNode);
+ return null;
+ }
+
+ return new EnumerationEMFModelHandler(featureName);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EnumerationStereotypeModelHandler.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EnumerationStereotypeModelHandler.java
new file mode 100644
index 00000000000..929af46cd96
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EnumerationStereotypeModelHandler.java
@@ -0,0 +1,279 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.operations.IUndoableOperation;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.common.util.Enumerator;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EEnum;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IBoundedValuesPropertyEditorDescriptor;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Enumeration;
+import org.eclipse.uml2.uml.EnumerationLiteral;
+import org.eclipse.uml2.uml.Stereotype;
+import org.eclipse.uml2.uml.StructuralFeature;
+
+
+/**
+ * Model Handler for enumeration-typed stereotype properties
+ */
+public class EnumerationStereotypeModelHandler extends EMFStereotypeFeatureModelHandler {
+
+ /** identifier fot this model handler */
+ public static final String ID = "EnumerationStereotype";
+
+ /**
+ * Creates a new EnumerationStereotypeModelHandler.
+ *
+ * @param stereotypeName
+ * name of the stereotype to edit
+ * @param featureName
+ * name of the feature to edit
+ */
+ public EnumerationStereotypeModelHandler(String stereotypeName, String featureName) {
+ super(stereotypeName, featureName);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void setValueForElement(Element elementToEdit, Stereotype stereotype, Object newValue) {
+ // remove value if result of the editor is empty
+ if(newValue == null || newValue.equals("")) {
+ // no unset for values ?!
+ elementToEdit.setValue(stereotype, getFeatureName(), null);
+ } else {
+ // retrieve the real value for the enumeration
+ if(newValue instanceof String) {
+ StructuralFeature featureToEdit = retrieveStructuralFeature(elementToEdit, stereotype);
+ Enumeration type = (Enumeration)featureToEdit.getType();
+ EnumerationLiteral literal = type.getOwnedLiteral((String)newValue);
+ elementToEdit.setValue(stereotype, getFeatureName(), literal);
+ }
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getValueToEdit(EObject objectToEdit) {
+ if(!(objectToEdit instanceof Element)) {
+ Activator.log.warn("the element selected is not a UML element: " + objectToEdit);
+ return null;
+ }
+ Element elementToEdit = (Element)objectToEdit;
+ Stereotype stereotype = retrieveStereotype(elementToEdit);
+ if(stereotype == null) {
+ Activator.log.warn("Impossible to find the stereotype " + getStereotypeName() + " for the given element" + elementToEdit);
+ return null;
+ }
+ Object value = elementToEdit.getValue(stereotype, getFeatureName());
+ if(value instanceof EnumerationLiteral) {
+ return ((EnumerationLiteral)value).getName();
+ } else if(value instanceof Enumerator) {
+ return ((Enumerator)value).getLiteral();
+ }
+ return value;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void completeEditorDescriptor(IPropertyEditorDescriptor descriptor, List<? extends EObject> objectToEdit) {
+ Element elementToEdit = retrieveElement(objectToEdit);
+ if(elementToEdit == null) {
+ return;
+ }
+ Stereotype stereotype = retrieveStereotype(elementToEdit);
+
+ if(stereotype == null) {
+ Activator.log.warn("Impossible to find stereotype: " + getStereotypeName() + " for element: " + elementToEdit);
+ return;
+ }
+
+ StructuralFeature featureToEdit = retrieveStructuralFeature(elementToEdit, stereotype);
+
+ // test enumeration, reference, etc.
+ List<String> values = new ArrayList<String>();
+
+ // check if there is an empty string at the beginning. there is one if the lower bound of the feature to edit equal 0
+ if(featureToEdit.getLower() == 0) {
+ values.add("");
+ }
+
+ if(featureToEdit.getType() instanceof Enumeration) {
+ Enumeration type = ((Enumeration)featureToEdit.getType());
+ for(EnumerationLiteral literal : type.getOwnedLiterals()) {
+ values.add(literal.getName());
+ }
+ }
+ if(descriptor instanceof IBoundedValuesPropertyEditorDescriptor) {
+ ((IBoundedValuesPropertyEditorDescriptor)descriptor).setAvailableValues(values);
+ } else {
+ Activator.log.warn("Warning: " + descriptor + "could not be completed.");
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getId() {
+ return ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<IUndoableOperation> getCreateValueOperations(List<? extends EObject> objectsToEdit, Composite parent) {
+ List<IUndoableOperation> operations = new ArrayList<IUndoableOperation>(1);
+ TransactionalEditingDomain editingDomain = EMFUtils.getTransactionalEditingDomain(objectsToEdit);
+ if(editingDomain == null) {
+ Activator.log.error("Impossible during creation operation to find the editing domain for objects: " + objectsToEdit, null);
+ return null;
+ }
+ int indexOfNewValue = NEW_VALUE_NOT_SET_INDEX;
+ CompositeTransactionalCommand command = new CompositeTransactionalCommand(editingDomain, "Create new Enumeration Value");
+ for(EObject objectToEdit : objectsToEdit) {
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return null;
+ }
+ CreateEnumerationStereotypeValueOperation operation = new CreateEnumerationStereotypeValueOperation(editingDomain, "Create new Enumeration Value", objectToEdit);
+ if(operation != null) {
+ command.add(operation);
+ }
+ if(indexOfNewValue == NEW_VALUE_NOT_SET_INDEX) { // try to update
+ indexOfNewValue = operation.getIndexOfNewValue();
+ }
+ }
+
+ operations.add(command.reduce());
+
+ return operations;
+ }
+
+ /**
+ * Operation to create a Enumeration value for the controlled property of a stererotype
+ */
+ protected class CreateEnumerationStereotypeValueOperation extends AbstractTransactionalCommand {
+
+ /** object to edit */
+ protected final EObject objectToEdit;
+
+ /** index of the value to add (-1 in case of single valued property) */
+ private int indexOfNewValue = -2;
+
+ /**
+ * Initializes me with the editing domain, a label, transaction options, and
+ * a list of {@link IFile}s that anticipate modifying when I am executed,
+ * undone or redone.
+ *
+ * @param domain
+ * the editing domain used to modify the model
+ * @param label
+ * my user-readable label, should never be <code>null</code>.
+ * @param objectToEdit
+ * the {@link EObject} to edit
+ */
+ public CreateEnumerationStereotypeValueOperation(TransactionalEditingDomain domain, String label, EObject objectToEdit) {
+ super(domain, (label == null) ? "" : label, null);
+ this.objectToEdit = objectToEdit;
+
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit.getUpperBound() == 1) {
+ indexOfNewValue = -1;
+ } else {
+ @SuppressWarnings("unchecked")
+ List<Object> values = new ArrayList<Object>((List<Object>)getValueToEdit(objectToEdit));
+ indexOfNewValue = values.size();
+ }
+ }
+
+ /**
+ * Returns the index at which the value will be added
+ *
+ * @return the index at which the value will be added
+ */
+ public int getIndexOfNewValue() {
+ return indexOfNewValue;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+ // create the value and add it to the feature
+ // if feature = simple valued => set
+ // if feature = multi valued => add at the end
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return CommandResult.newErrorCommandResult("Impossible to find the feature " + getFeatureName());
+ }
+ Object newValue;
+ if(featureToEdit.getUpperBound() == 1) {
+ newValue = getInitialValue(objectToEdit);
+ } else {
+ @SuppressWarnings("unchecked")
+ List<Object> values = new ArrayList<Object>((List<Object>)getValueToEdit(objectToEdit));
+ values.add(indexOfNewValue, getInitialValue(objectToEdit));
+ newValue = values;
+ }
+ setValueInModel(objectToEdit, newValue);
+ return CommandResult.newOKCommandResult();
+ }
+ }
+
+ /**
+ * Returns the initial value for a new value of the feature
+ *
+ * @param objectToEdit
+ * the object to edit
+ *
+ * @return the initial value, not <code>null</code>
+ */
+ public Object getInitialValue(EObject objectToEdit) {
+ String featureName = getFeatureName();
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit.getUpperBound() == 1) {
+ return featureName;
+ } else {
+ for(int suffix = 0; suffix < 1000; suffix++) {
+ EClassifier eClassifier = featureToEdit.getEType();
+ if(eClassifier instanceof EEnum) {
+ return ((EEnum)eClassifier).getDefaultValue();
+ }
+ }
+ Activator.log.error("Impossible to find a default value", null);
+ return null;
+ }
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EnumerationStereotypeModelHandlerFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EnumerationStereotypeModelHandlerFactory.java
new file mode 100644
index 00000000000..617bcaf2c6b
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/EnumerationStereotypeModelHandlerFactory.java
@@ -0,0 +1,44 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.modelhandler.IPropertyModelHandlerFactory;
+import org.w3c.dom.Node;
+
+
+/**
+ * Factory that creates {@link EnumerationStereotypeModelHandler}.
+ */
+public class EnumerationStereotypeModelHandlerFactory extends StereotypeModelHandlerFactory implements IPropertyModelHandlerFactory {
+
+ /**
+ * Creates a new EnumerationStereotypeModelHandlerFactory.
+ */
+ public EnumerationStereotypeModelHandlerFactory() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public EnumerationStereotypeModelHandler createModelHandler(Node modelHandlerNode) {
+ // specific code to parse the given element
+ String featureName = retrieveFeatureName(modelHandlerNode);
+ String stereotypeName = retrieveStereotypeName(modelHandlerNode);
+ if(featureName == null || stereotypeName == null) {
+ Activator.log.warn("Impossible to retrieve feature name and/or stereotype name from node " + modelHandlerNode);
+ return null;
+ }
+ return new EnumerationStereotypeModelHandler(stereotypeName, featureName);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/IEMFModelHandler.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/IEMFModelHandler.java
new file mode 100644
index 00000000000..b42426d930e
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/IEMFModelHandler.java
@@ -0,0 +1,239 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ * Vincent Lorenzo (CEA-LIST) vincent.lorenzo@cea.fr
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import java.util.List;
+
+import org.eclipse.core.commands.operations.IUndoableOperation;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
+import org.eclipse.papyrus.properties.runtime.controller.EMFPropertyEditorController;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.IConfigurableDescriptor;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * Interface that manages conversion of values from String (coming from editors) and the model itself
+ */
+public interface IEMFModelHandler extends IConfigurableDescriptor {
+
+ /**
+ * Returns the value to edit from the model
+ *
+ * @param objectToEdit
+ * the object to edit
+ *
+ * @return the value to edit from the model
+ */
+ public Object getValueToEdit(EObject objectToEdit);
+
+ /**
+ * Sets the new Value in the model
+ *
+ * @param objectToEdit
+ * the object to edit
+ * @param newValue
+ * the new value to set
+ */
+ public void setValueInModel(EObject objectToEdit, Object newValue);
+
+ /**
+ * Returns the initialization data that will be given to the property editor
+ *
+ * @param descriptor
+ * descriptor of the editor managed by the controller linked to this model handler
+ * @param objectToEdit
+ * list of objects to edit
+ */
+ public void completeEditorDescriptor(IPropertyEditorDescriptor descriptor, List<? extends EObject> objectToEdit);
+
+ /**
+ * checks if the feature is changeable
+ *
+ * @param objectsToEdit
+ * the list of objects to edit
+ * @return <code>true</code> if the feature is changeable
+ */
+ public boolean isChangeable(List<? extends EObject> objectsToEdit);
+
+ /**
+ * Returns the identifier of this model handler
+ *
+ * @return the identifier of this model handler
+ */
+ public String getId();
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public IEMFModelHandlerState createState(boolean readOnly);
+
+ /**
+ * handle notifications for the model handler
+ *
+ * @param notification
+ * the notification to react to
+ * @param objects
+ * the list of objects on which updates should be performed
+ * @param adapter
+ * the adapter in charge of notification
+ */
+ public void handleNotifyChange(Notification notification, List<? extends EObject> objects, EMFPropertyEditorController adapter);
+
+ /**
+ * Returns available values for the feature managed by the model handler
+ *
+ * @param object
+ * the list of available values
+ * @return the list of available values
+ */
+ public Object getAvailableValues(EObject object);
+
+ /**
+ * Adds the listeners to the model
+ *
+ * @param objectsToEdit
+ * the list of object to edit
+ * @param controller
+ * the controller which uses this model handler
+ */
+ public void addListenersToModel(List<? extends EObject> objectsToEdit, EMFPropertyEditorController controller);
+
+ /**
+ * Removes the listeners from the model
+ *
+ * @param objectsToEdit
+ * the list of object to edit
+ * @param controller
+ * the controller which was using this model handler
+ */
+ public void removeListenersFromModel(List<? extends EObject> objectsToEdit, EMFPropertyEditorController controller);
+
+ /**
+ * Returns the operation to create a new value for this property
+ *
+ * @param objectsToEdit
+ * the list of object to edit
+ * @param parent
+ * the composite parent, needed in case of user interaction
+ *
+ * @return the operation to create a new value for this property
+ */
+ public List<IUndoableOperation> getCreateValueOperations(List<? extends EObject> objectsToEdit, Composite parent);
+
+ /**
+ * Returns <code>true</code> if the controller can create a new value for the property
+ *
+ * @param objectsToEdit
+ * the list of object to edit
+ * @return <code>true</code> if the controller can create a new value for the property
+ */
+ public boolean canCreateValueOperations(List<? extends EObject> objectsToEdit);
+
+ /**
+ * Returns the operation to delete a value for this property
+ *
+ * @param objectsToEdit
+ * the list of object to edit
+ * @param parent
+ * the composite parent, needed in case of user interaction
+ * @param indexes
+ * list of indexes to delete
+ * @return the operation to delete a value for this property
+ *
+ */
+ public IUndoableOperation getDeleteValueOperation(List<? extends EObject> objectsToEdit, Composite parent, List<Integer> indexes);
+
+ /**
+ * Returns <code>true</code> if the controller can delete a value for the property
+ *
+ * @param objectsToEdit
+ * the list of object to edit
+ * @return <code>true</code> if the controller can delete a value for the property
+ */
+ public boolean canCreateDeleteValueOperation(List<? extends EObject> objectsToEdit);
+
+ /**
+ * Returns the operation to edit a value for this property
+ *
+ * @param objectsToEdit
+ * the list of object to edit
+ * @param index
+ * the index of the value to edit
+ * @param parent
+ * the parent for the editor
+ * @param value
+ * the value to set
+ * @return the operation to edit a value for this property
+ */
+ public IUndoableOperation getEditValueOperation(List<? extends EObject> objectsToEdit, int index, Composite parent, Object value);
+
+ /**
+ * Returns <code>true</code> if the controller can edit a value for the property
+ *
+ * @param objectsToEdit
+ * the list of object to edit
+ * @return <code>true</code> if the controller can edit a value for the property
+ */
+ public boolean canCreateEditValueOperation(List<? extends EObject> objectsToEdit);
+
+ /**
+ * Returns the operation to move a list of values for this property
+ *
+ * @param objectsToEdit
+ * the list of object to edit
+ * @param indexes
+ * the list of indexes to move
+ * @param parent
+ * the parent for the editor
+ * @param delta
+ * the delta applied to all moved objects
+ * @return the operation to edit a value for this property
+ */
+ public IUndoableOperation getMoveValueOperation(List<? extends EObject> objectsToEdit, List<Integer> indexes, Composite parent, int delta);
+
+ /**
+ * Returns <code>true</code> if the controller can move a set of values for the property
+ *
+ * @param objectsToEdit
+ * the list of object to edit
+ * @param indexes
+ * the list of indexes to move
+ * @param parent
+ * the parent for the editor
+ * @param delta
+ * the delta applied to all moved objects
+ * @return <code>true</code> if the controller can move a set of values for the property
+ */
+ public boolean canCreateMoveValueOperation(List<? extends EObject> objectsToEdit, List<Integer> indexes, Composite parent, int delta);
+
+
+
+ /**
+ * Returns a list of SetRequest for this object, or <code>null</code> if a request can't be created
+ *
+ * @param domain
+ * the transactional editing domain
+ * @param objectToEdit
+ * the object to edit
+ * @param newValue
+ * the new value for this object
+ * @return
+ * a list of SetRequest for this object, or <code>null</code> if a request can't be created
+ */
+ public SetRequest[] getSetRequest(TransactionalEditingDomain domain, EObject objectToEdit, Object newValue);
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/IEMFModelHandlerState.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/IEMFModelHandlerState.java
new file mode 100644
index 00000000000..12e5c87c448
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/IEMFModelHandlerState.java
@@ -0,0 +1,23 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import org.eclipse.papyrus.properties.runtime.state.IState;
+import org.eclipse.papyrus.properties.runtime.state.ITraversableModelElement;
+
+
+/**
+ * interface for states for {@link IEMFModelHandler}
+ */
+public interface IEMFModelHandlerState extends IState, ITraversableModelElement {
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/ReferenceEMFModelHandler.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/ReferenceEMFModelHandler.java
new file mode 100644
index 00000000000..2b8f7f20f19
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/ReferenceEMFModelHandler.java
@@ -0,0 +1,304 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ * Vincent Lorenzo (CEA-LIST) vincent.lorenzo@cea.fr
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.commands.operations.IUndoableOperation;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EReference;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.edit.ui.celleditor.FeatureEditorDialog;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand;
+import org.eclipse.gmf.runtime.emf.type.core.IElementType;
+import org.eclipse.gmf.runtime.emf.type.core.requests.CreateElementRequest;
+import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.papyrus.core.services.ServiceException;
+import org.eclipse.papyrus.core.utils.DisplayUtils;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.Messages;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.papyrus.service.edit.service.ElementEditServiceUtils;
+import org.eclipse.papyrus.service.edit.service.IElementEditService;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.PlatformUI;
+
+
+/**
+ * Model Handler for References
+ */
+public class ReferenceEMFModelHandler extends EMFFeatureModelHandler {
+
+ /**
+ * Creates a new ReferenceEMFModelHandler.
+ *
+ * @param featureName
+ * the name of the feature to edit
+ */
+ public ReferenceEMFModelHandler(String featureName) {
+ super(featureName);
+ }
+
+ /** identifier fot this model handler */
+ public static final String ID = "Reference"; //$NON-NLS-1$
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setValueInModel(EObject objectToEdit, Object newValue) {
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return;
+ }
+ if(newValue instanceof EObject || newValue == null) {
+ objectToEdit.eSet(featureToEdit, newValue);
+ } else if(newValue instanceof List<?>) {
+ objectToEdit.eSet(featureToEdit, newValue);
+ } else {
+ Activator.log.error("impossible to set the new value", null); //$NON-NLS-1$
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void completeEditorDescriptor(IPropertyEditorDescriptor descriptor, List<? extends EObject> objectToEdit) {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getId() {
+ return ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<IUndoableOperation> getCreateValueOperations(final List<? extends EObject> objectsToEdit, Composite parent) {
+ // checks the containment feature
+ EObject eObject = objectsToEdit.get(0);
+ EStructuralFeature feature = getFeatureByName(eObject);
+ if(!(feature instanceof EReference)) {
+ return new ArrayList<IUndoableOperation>();
+ }
+ // check containment feature
+
+ boolean isContainment = ((EReference)feature).isContainment();
+ if(isContainment) {
+ // retrieve the Eclass of the elements to edit
+ List<IUndoableOperation> undoableOperations = new ArrayList<IUndoableOperation>();
+ EClass eClass = eObject.eClass();
+ if(eClass == null) {
+ return undoableOperations;
+ }
+ // Use edit service and look for element types that are possible types of the selected EReference
+ List<IElementEditService> featureTypeServices;
+ try {
+ featureTypeServices = ElementEditServiceUtils.getEditServiceProvider().getContainedTypeEditServices(eObject, (EReference)feature);
+ } catch (ServiceException e) {
+ e.printStackTrace();
+ return undoableOperations;
+ }
+
+ for(IElementEditService featureTypeService : featureTypeServices) {
+ CreateElementRequest request = new CreateElementRequest(EMFUtils.getTransactionalEditingDomain(objectsToEdit), eObject, (IElementType)featureTypeService.getAdapter(IElementType.class), (EReference)feature);
+ request.setLabel(Messages.bind(Messages.EMFTEReferenceController_CreationOperationMenuLabel, featureTypeService.getDisplayName()));
+ ICommand command = featureTypeService.getEditCommand(request);
+ if(command.canExecute()) {
+ // adds it to the list of command that can be
+ // executed
+ undoableOperations.add(command);
+ }
+ }
+
+ return undoableOperations;
+ } else {
+
+ // IUndoableOperation operation = new FindReferenceCommand(EMFUtils.getTransactionalEditingDomain(objectsToEdit), "Find and Add references", objectsToEdit);
+ IUndoableOperation operation = getFindReferenceCommand(EMFUtils.getTransactionalEditingDomain(objectsToEdit), "Find and Add references", objectsToEdit); //$NON-NLS-1$
+ return Arrays.asList(operation);
+ }
+ }
+
+ /**
+ * Returns the command to find the reference
+ *
+ * @param transactionalEditingDomain
+ * the editing domain
+ * @param string
+ * the name of the command
+ * @param objectsToEdit
+ * the lists of objects to edit
+ * @return
+ * the command to find the reference
+ */
+ public IUndoableOperation getFindReferenceCommand(TransactionalEditingDomain transactionalEditingDomain, String string, List<? extends EObject> objectsToEdit) {
+ CompositeTransactionalCommand command = new CompositeTransactionalCommand(transactionalEditingDomain, string);
+ // checks the containment feature
+ EObject eObject = objectsToEdit.get(0);
+ EStructuralFeature feature = getFeatureByName(eObject);
+ if(!(feature instanceof EReference)) {
+ return command;
+ }
+
+ // pops up a window to ask for a new reference
+ Display display = Display.getCurrent();
+ if(display == null && PlatformUI.isWorkbenchRunning()) {
+ display = PlatformUI.getWorkbench().getDisplay();
+ }
+ display = (display != null) ? display : Display.getDefault();
+ EClassifier eclassifier = feature.getEType();
+ Object availableValues = getAvailableValues(eObject);
+ List<?> values = new ArrayList<Object>();
+ if(availableValues instanceof List<?>) {
+ values = (List<?>)availableValues;
+ } else if(availableValues instanceof Object[]) {
+ values = Arrays.asList(availableValues);
+ } else {
+ values = Arrays.asList(availableValues);
+ }
+
+ @SuppressWarnings("unchecked")
+ FeatureEditorDialog dialog = new FeatureEditorDialog(display.getActiveShell(), DisplayUtils.getLabelProvider(), eObject, eclassifier, (List<EObject>)eObject.eGet(feature), Messages.ReferenceEMFModelHandler_Select_Values, values, false, feature.isOrdered(), feature.isUnique());
+ // should select the current value by default
+ if(Dialog.OK == dialog.open()) {
+ @SuppressWarnings("unchecked")
+ List<EObject> currentValues = (List<EObject>)dialog.getResult();
+ SetRequest[] requests = getSetRequest(transactionalEditingDomain, eObject, currentValues);
+ if(requests != null) {
+
+ org.eclipse.papyrus.service.edit.service.IElementEditService provider = org.eclipse.papyrus.service.edit.service.ElementEditServiceUtils.getCommandProvider(eObject);
+ if(provider != null) {
+
+ ICommand editCommand = null;
+ for(SetRequest current : requests) {
+ editCommand = provider.getEditCommand(current);
+
+ if(editCommand != null && editCommand.canExecute()) {
+ command.add(editCommand);
+ }
+ }
+ }
+ }
+ return command;
+ }
+
+ return command;
+ }
+
+ // /**
+ // * Command to create references.
+ // * Two cases:
+ // * - This is a containment reference, should create element.
+ // * - This is a simple reference, should only browse the model to get other elements
+ // */
+ // protected class FindReferenceCommand extends AbstractTransactionalCommand {
+ //
+ // /** list of objects to edit */
+ // protected final List<? extends EObject> objectsToEdit;
+ //
+ // /**
+ // * Creates a new FindReferenceCommand.
+ // *
+ // * @param domain
+ // * editing domain used to create or manipulate elements
+ // * @param label
+ // * the label of the command, used by UI.
+ // * @param objectsToEdit
+ // * the list of objects to edit
+ // */
+ // public FindReferenceCommand(TransactionalEditingDomain domain, String label, List<? extends EObject> objectsToEdit) {
+ // super(domain, label, null);
+ // this.objectsToEdit = objectsToEdit;
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // @Override
+ // protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+ //
+ // // checks the containment feature
+ // EObject eObject = objectsToEdit.get(0);
+ // EStructuralFeature feature = getFeatureByName(eObject);
+ // if(!(feature instanceof EReference)) {
+ // return CommandResult.newErrorCommandResult("the feature " + getFeatureName() + " is not a reference");
+ // }
+ //
+ // // pops up a window to ask for a new reference
+ // Display display = Display.getCurrent();
+ // if(display == null && PlatformUI.isWorkbenchRunning()) {
+ // display = PlatformUI.getWorkbench().getDisplay();
+ // }
+ // display = (display != null) ? display : Display.getDefault();
+ // EClassifier eclassifier = feature.getEType();
+ // Object availableValues = getAvailableValues(eObject);
+ // List<?> values = new ArrayList<Object>();
+ // if(availableValues instanceof List<?>) {
+ // values = (List<?>)availableValues;
+ // } else if(availableValues instanceof Object[]) {
+ // values = Arrays.asList(availableValues);
+ // } else {
+ // values = Arrays.asList(availableValues);
+ // }
+ //
+ // @SuppressWarnings("unchecked")
+ // FeatureEditorDialog dialog = new FeatureEditorDialog(display.getActiveShell(), DisplayUtils.getLabelProvider(), eObject, eclassifier, (List<EObject>)eObject.eGet(feature), "Select Values", values, false, feature.isOrdered(), feature.isUnique());
+ // // should select the current value by default
+ // if(Dialog.OK == dialog.open()) {
+ // @SuppressWarnings("unchecked")
+ // List<EObject> currentValues = (List<EObject>)dialog.getResult();
+ // eObject.eSet(feature, currentValues);
+ // }
+ // return CommandResult.newOKCommandResult();
+ // }
+ // }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.properties.runtime.modelhandler.emf.IEMFModelHandler#getSetRequest(org.eclipse.emf.transaction.TransactionalEditingDomain,
+ * org.eclipse.emf.ecore.EObject, java.lang.Object)
+ *
+ * @param domain
+ * @param objectToEdit
+ * @param newValue
+ * @return
+ */
+ public SetRequest[] getSetRequest(TransactionalEditingDomain domain, EObject objectToEdit, Object newValue) {
+
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return null;
+ }
+ if(newValue instanceof EObject || newValue == null) {
+ return new SetRequest[]{ new SetRequest(domain, objectToEdit, featureToEdit, newValue) };
+ } else if(newValue instanceof List<?>) {
+ return new SetRequest[]{ new SetRequest(domain, objectToEdit, featureToEdit, newValue) };
+ } else {
+ Activator.log.error("impossible to set the new value", null); //$NON-NLS-1$
+ }
+ return null;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/ReferenceEMFModelHandlerFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/ReferenceEMFModelHandlerFactory.java
new file mode 100644
index 00000000000..b1158706cb2
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/ReferenceEMFModelHandlerFactory.java
@@ -0,0 +1,45 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.modelhandler.IPropertyModelHandlerFactory;
+import org.w3c.dom.Node;
+
+
+/**
+ * Factory that creates {@link ReferenceEMFModelHandler}.
+ */
+public class ReferenceEMFModelHandlerFactory extends EMFModelHandlerFactory implements IPropertyModelHandlerFactory {
+
+ /**
+ * Creates a new BooleanEMFModelHandlerFactory.
+ */
+ public ReferenceEMFModelHandlerFactory() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ReferenceEMFModelHandler createModelHandler(Node modelHandlerNode) {
+ // specific code to parse the given element
+ String featureName = retrieveFeatureName(modelHandlerNode);
+
+ if(featureName == null) {
+ Activator.log.warn("Impossible to retrieve feature from node " + modelHandlerNode);
+ return null;
+ }
+
+ return new ReferenceEMFModelHandler(featureName);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/ReferenceStereotypeModelHandler.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/ReferenceStereotypeModelHandler.java
new file mode 100644
index 00000000000..a89463a0ec6
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/ReferenceStereotypeModelHandler.java
@@ -0,0 +1,73 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import java.util.List;
+
+import org.eclipse.core.commands.operations.IUndoableOperation;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * Model handler for reference properties of stereotypes
+ */
+public class ReferenceStereotypeModelHandler extends EMFStereotypeFeatureModelHandler {
+
+ /** identifier for this model handler */
+ public final static String ID = "ReferenceStereotype";
+
+ /**
+ * Creates a new ReferenceStereotypeModelHandler.
+ *
+ * @param stereotypeName
+ * the name of the stereotype that holds the property
+ * @param featureName
+ * the name of the feature to modify
+ */
+ public ReferenceStereotypeModelHandler(String stereotypeName, String featureName) {
+ super(stereotypeName, featureName);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void setValueForElement(org.eclipse.uml2.uml.Element elementToEdit, org.eclipse.uml2.uml.Stereotype stereotype, Object newValue) {
+
+ if(newValue instanceof EObject || newValue == null) {
+ elementToEdit.setValue(stereotype, getFeatureName(), newValue);
+ } else if(newValue instanceof EList<?>) {
+ elementToEdit.setValue(stereotype, getFeatureName(), newValue);
+ } else {
+ Activator.log.error("impossible to set the new value", null);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getId() {
+ return ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<IUndoableOperation> getCreateValueOperations(List<? extends EObject> objectsToEdit, Composite parent) {
+ // TODO Auto-generated method stub
+ return null;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/ReferenceStereotypeModelHandlerFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/ReferenceStereotypeModelHandlerFactory.java
new file mode 100644
index 00000000000..6b0dd829d6a
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/ReferenceStereotypeModelHandlerFactory.java
@@ -0,0 +1,44 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.modelhandler.IPropertyModelHandlerFactory;
+import org.w3c.dom.Node;
+
+
+/**
+ * Factory that creates {@link ReferenceStereotypeModelHandler}.
+ */
+public class ReferenceStereotypeModelHandlerFactory extends StereotypeModelHandlerFactory implements IPropertyModelHandlerFactory {
+
+ /**
+ * Creates a new ReferenceStereotypeModelHandlerFactory.
+ */
+ public ReferenceStereotypeModelHandlerFactory() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ReferenceStereotypeModelHandler createModelHandler(Node modelHandlerNode) {
+ // specific code to parse the given element
+ String featureName = retrieveFeatureName(modelHandlerNode);
+ String stereotypeName = retrieveStereotypeName(modelHandlerNode);
+ if(featureName == null || stereotypeName == null) {
+ Activator.log.warn("Impossible to retrieve feature name and/or stereotype name from node " + modelHandlerNode);
+ return null;
+ }
+ return new ReferenceStereotypeModelHandler(stereotypeName, featureName);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/StereotypeModelHandlerFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/StereotypeModelHandlerFactory.java
new file mode 100644
index 00000000000..85ded035f4c
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/StereotypeModelHandlerFactory.java
@@ -0,0 +1,47 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+
+/**
+ * Factory to manipulate stereotype features
+ */
+public abstract class StereotypeModelHandlerFactory extends EMFModelHandlerFactory {
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public abstract IEMFModelHandler createModelHandler(Node modelHandlerNode);
+
+ /**
+ * Retrieve the name of the stereotype to modify
+ *
+ * @param node
+ * the configuration node
+ * @return the name of the stereotype to modify or <code>null</code>
+ */
+ protected String retrieveStereotypeName(Node node) {
+ String stereotypeName = null;
+ NamedNodeMap attributes = node.getAttributes();
+ if(attributes != null) {
+ Node stereotypeNameNode = attributes.getNamedItem("stereotypeName");
+ if(stereotypeNameNode != null) {
+ stereotypeName = stereotypeNameNode.getNodeValue();
+ }
+ }
+ return stereotypeName;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/StringEMFModelHandler.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/StringEMFModelHandler.java
new file mode 100644
index 00000000000..47b30bd4cfd
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/StringEMFModelHandler.java
@@ -0,0 +1,327 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ * Vincent Lorenzo (CEA-LIST) vincent.lorenzo@cea.fr
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.commands.operations.IUndoableOperation;
+import org.eclipse.emf.ecore.EClassifier;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.ICommand;
+import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand;
+import org.eclipse.gmf.runtime.emf.type.core.requests.SetRequest;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * Extract or inject values for a string-typed feature.
+ */
+public class StringEMFModelHandler extends EMFFeatureModelHandler {
+
+ /** ID of this model handler */
+ public static final String ID = "String"; //$NON-NLS-1$
+
+ /**
+ * Creates a new StringEMFModelHandler.
+ *
+ * @param featureName
+ * the name of the feature to edit
+ */
+ public StringEMFModelHandler(String featureName) {
+ super(featureName);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setValueInModel(EObject objectToEdit, Object newValue) {
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return;
+ }
+
+ // check the type of the feature to set
+ EClassifier type = featureToEdit.getEType();
+ if(type == null) {
+ Activator.log.debug("Impossible to find the type of the feature: " + getFeatureName()); //$NON-NLS-1$
+ } else {
+ if(String.class.isAssignableFrom(type.getInstanceClass())) {
+ objectToEdit.eSet(featureToEdit, newValue);
+ } else if(Integer.TYPE.isAssignableFrom(type.getInstanceClass())) {
+ try {
+ int value = Integer.parseInt(newValue.toString());
+ objectToEdit.eSet(featureToEdit, value);
+ } catch (NumberFormatException e) {
+ Activator.log.debug(newValue + " can not be parsed as an integer"); //$NON-NLS-1$
+ }
+ } else {
+ Activator.log.error("Feature: " + getFeatureName() + ". Impossible to understand the value for the type: " + featureToEdit.getEType().getInstanceClass(), null); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void completeEditorDescriptor(IPropertyEditorDescriptor descriptor, List<? extends EObject> objectToEdit) {
+ // nothing to do here
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getId() {
+ return ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<IUndoableOperation> getCreateValueOperations(List<? extends EObject> objectsToEdit, Composite parent) {
+ List<IUndoableOperation> operations = new ArrayList<IUndoableOperation>(1);
+ TransactionalEditingDomain editingDomain = EMFUtils.getTransactionalEditingDomain(objectsToEdit);
+ if(editingDomain == null) {
+ Activator.log.error("Impossible during creation operation to find the editing domain for objects: " + objectsToEdit, null); //$NON-NLS-1$
+ return null;
+ }
+ // int indexOfNewValue = NEW_VALUE_NOT_SET_INDEX;
+ CompositeTransactionalCommand command = new CompositeTransactionalCommand(editingDomain, "Create new String Values"); //$NON-NLS-1$
+ for(EObject objectToEdit : objectsToEdit) {
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return null;
+ }
+ //CreateStringValueOperation operation = new CreateStringValueOperation(editingDomain, "Create new String Value", objectToEdit);
+ IUndoableOperation operation = getCreateStringValueCommand(editingDomain, "Create new String Value", objectToEdit); //$NON-NLS-1$
+ if(operation != null) {
+ command.add(operation);
+ }
+ // if(indexOfNewValue == NEW_VALUE_NOT_SET_INDEX) { // try to update
+ // indexOfNewValue = operation.getIndexOfNewValue();
+ // }
+ }
+
+ operations.add(command.reduce());
+
+ return operations;
+ }
+
+ /**
+ * Returns the command to create a string value
+ *
+ * @param editingDomain
+ * the editing domain
+ * @param string
+ * the command's name
+ * @param objectToEdit
+ * the object to edit
+ * @return
+ * The command to create a string value
+ */
+ protected IUndoableOperation getCreateStringValueCommand(TransactionalEditingDomain editingDomain, String string, EObject objectToEdit) {
+ CompositeTransactionalCommand command = new CompositeTransactionalCommand(editingDomain, string);
+ int indexOfNewValue = -2;
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return command;
+ }
+ if(featureToEdit.getUpperBound() == 1) {
+ indexOfNewValue = -1;
+ } else {
+ @SuppressWarnings("unchecked")
+ List<Object> values = new ArrayList<Object>((List<Object>)objectToEdit.eGet(featureToEdit));
+ indexOfNewValue = values.size();
+ }
+
+ // create the value and add it to the feature
+ // if feature = simple valued => set
+ // if feature = multi valued => add at the end
+ Object newValue;
+ if(featureToEdit.getUpperBound() == 1) {
+ newValue = getInitialValue(objectToEdit);
+ } else {
+ @SuppressWarnings("unchecked")
+ List<Object> values = new ArrayList<Object>((List<Object>)objectToEdit.eGet(featureToEdit));
+ values.add(indexOfNewValue, getInitialValue(objectToEdit));
+ newValue = values;
+ }
+ SetRequest[] requests = getSetRequest(editingDomain, objectToEdit, newValue);
+ if(requests != null) {
+
+ org.eclipse.papyrus.service.edit.service.IElementEditService provider = org.eclipse.papyrus.service.edit.service.ElementEditServiceUtils.getCommandProvider(objectToEdit);
+ if(provider != null) {
+
+ ICommand editCommand = null;
+ for(SetRequest current : requests) {
+ editCommand = provider.getEditCommand(current);
+
+ if(editCommand != null && editCommand.canExecute()) {
+ command.add(editCommand);
+ }
+ }
+ }
+ }
+ return command;
+ }
+
+ // /**
+ // * Operation to create a String value for the controlled property
+ // */
+ // protected class CreateStringValueOperation extends AbstractTransactionalCommand {
+ //
+ // /** object to edit */
+ // protected final EObject objectToEdit;
+ //
+ // /** index of the value to add (-1 in case of single valued property) */
+ // private int indexOfNewValue = -2;
+ //
+ // /**
+ // * Initializes me with the editing domain, a label, transaction options, and
+ // * a list of {@link IFile}s that anticipate modifying when I am executed,
+ // * undone or redone.
+ // *
+ // * @param domain
+ // * the editing domain used to modify the model
+ // * @param label
+ // * my user-readable label, should never be <code>null</code>.
+ // * @param objectToEdit
+ // * the {@link EObject} to edit
+ // */
+ // public CreateStringValueOperation(TransactionalEditingDomain domain, String label, EObject objectToEdit) {
+ // super(domain, (label == null) ? "" : label, null);
+ // this.objectToEdit = objectToEdit;
+ //
+ // EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ // if(featureToEdit.getUpperBound() == 1) {
+ // indexOfNewValue = -1;
+ // } else {
+ // @SuppressWarnings("unchecked")
+ // List<Object> values = new ArrayList<Object>((List<Object>)objectToEdit.eGet(featureToEdit));
+ // indexOfNewValue = values.size();
+ // }
+ // }
+ //
+ // /**
+ // * Returns the index at which the value will be added
+ // *
+ // * @return the index at which the value will be added
+ // */
+ // public int getIndexOfNewValue() {
+ // return indexOfNewValue;
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // @Override
+ // protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+ // // create the value and add it to the feature
+ // // if feature = simple valued => set
+ // // if feature = multi valued => add at the end
+ // EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ // if(featureToEdit == null) {
+ // return CommandResult.newErrorCommandResult("Impossible to find the feature " + getFeatureName());
+ // }
+ // Object newValue;
+ // if(featureToEdit.getUpperBound() == 1) {
+ // newValue = getInitialValue(objectToEdit);
+ // } else {
+ // @SuppressWarnings("unchecked")
+ // List<Object> values = new ArrayList<Object>((List<Object>)objectToEdit.eGet(featureToEdit));
+ // values.add(indexOfNewValue, getInitialValue(objectToEdit));
+ // newValue = values;
+ // }
+ // setValueInModel(objectToEdit, newValue);
+ // return CommandResult.newOKCommandResult();
+ // }
+ // }
+
+ /**
+ * Returns the initial value for a new value of the feature
+ *
+ * @param objectToEdit
+ * the object to edit
+ *
+ * @return the initial value, not <code>null</code>
+ */
+ public Object getInitialValue(EObject objectToEdit) {
+ String featureName = getFeatureName();
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit.getUpperBound() == 1) {
+ return featureName;
+ } else {
+ for(int suffix = 0; suffix < 1000; suffix++) {
+ String tmpName = featureName + suffix;
+ boolean found = false;
+ @SuppressWarnings("unchecked")
+ List<Object> values = new ArrayList<Object>((List<Object>)objectToEdit.eGet(featureToEdit));
+ for(Object value : values) {
+ if(tmpName.equals(value)) {
+ found = true;
+ }
+ }
+ if(!found) {
+ return tmpName;
+ }
+ }
+ return featureName;
+ }
+ }
+
+ /**
+ *
+ * @see org.eclipse.papyrus.properties.runtime.modelhandler.emf.IEMFModelHandler#getSetRequest(org.eclipse.emf.transaction.TransactionalEditingDomain,
+ * org.eclipse.emf.ecore.EObject, java.lang.Object)
+ *
+ * @param domain
+ * @param objectToEdit
+ * @param newValue
+ * @return
+ */
+ public SetRequest[] getSetRequest(TransactionalEditingDomain domain, EObject objectToEdit, Object newValue) {
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return null;
+ }
+
+ // check the type of the feature to set
+ EClassifier type = featureToEdit.getEType();
+ if(type == null) {
+ Activator.log.debug("Impossible to find the type of the feature: " + getFeatureName()); //$NON-NLS-1$
+ return null;
+ } else {
+ if(String.class.isAssignableFrom(type.getInstanceClass())) {
+ return new SetRequest[]{ new SetRequest(domain, objectToEdit, featureToEdit, newValue) };
+ } else if(Integer.TYPE.isAssignableFrom(type.getInstanceClass())) {
+ try {
+ int value = Integer.parseInt(newValue.toString());
+ return new SetRequest[]{ new SetRequest(domain, objectToEdit, featureToEdit, value) };
+ } catch (NumberFormatException e) {
+ Activator.log.debug(newValue + " can not be parsed as an integer"); //$NON-NLS-1$
+ }
+ } else {
+ Activator.log.error("Feature: " + getFeatureName() + ". Impossible to understand the value for the type: " + featureToEdit.getEType().getInstanceClass(), null); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ }
+ return null;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/StringEMFModelHandlerFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/StringEMFModelHandlerFactory.java
new file mode 100644
index 00000000000..4134441cc2e
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/StringEMFModelHandlerFactory.java
@@ -0,0 +1,45 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.modelhandler.IPropertyModelHandlerFactory;
+import org.w3c.dom.Node;
+
+
+/**
+ * Factory that creates {@link StringEMFModelHandler}.
+ */
+public class StringEMFModelHandlerFactory extends EMFModelHandlerFactory implements IPropertyModelHandlerFactory {
+
+ /**
+ * Creates a new StringEMFModelHandlerFactory.
+ */
+ public StringEMFModelHandlerFactory() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public StringEMFModelHandler createModelHandler(Node modelHandlerNode) {
+ // specific code to parse the given element
+ String featureName = retrieveFeatureName(modelHandlerNode);
+
+ if(featureName == null) {
+ Activator.log.warn("Impossible to retrieve feature from node " + modelHandlerNode);
+ return null;
+ }
+
+ return new StringEMFModelHandler(featureName);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/StringStereotypeModelHandler.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/StringStereotypeModelHandler.java
new file mode 100644
index 00000000000..70f4977ca3a
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/StringStereotypeModelHandler.java
@@ -0,0 +1,194 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.operations.IUndoableOperation;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.IAdaptable;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.EStructuralFeature;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.gmf.runtime.common.core.command.CommandResult;
+import org.eclipse.gmf.runtime.emf.commands.core.command.AbstractTransactionalCommand;
+import org.eclipse.gmf.runtime.emf.commands.core.command.CompositeTransactionalCommand;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * Model Handler for String-typed stereotypes properties
+ */
+public class StringStereotypeModelHandler extends EMFStereotypeFeatureModelHandler {
+
+ /** identifier for this model handler */
+ public final static String ID = "StringStereotype";
+
+ /**
+ * Creates a new StringStereotypeModelHandler.
+ *
+ * @param stereotypeName
+ * the name of the stereotype that holds the feature to modify
+ * @param featureName
+ * the name of the feature to modify
+ */
+ public StringStereotypeModelHandler(String stereotypeName, String featureName) {
+ super(stereotypeName, featureName);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getId() {
+ return ID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<IUndoableOperation> getCreateValueOperations(List<? extends EObject> objectsToEdit, Composite parent) {
+ List<IUndoableOperation> operations = new ArrayList<IUndoableOperation>(1);
+ TransactionalEditingDomain editingDomain = EMFUtils.getTransactionalEditingDomain(objectsToEdit);
+ if(editingDomain == null) {
+ Activator.log.error("Impossible during creation operation to find the editing domain for objects: " + objectsToEdit, null);
+ return null;
+ }
+ int indexOfNewValue = NEW_VALUE_NOT_SET_INDEX;
+ CompositeTransactionalCommand command = new CompositeTransactionalCommand(editingDomain, "Create new String Values");
+ for(EObject objectToEdit : objectsToEdit) {
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return null;
+ }
+ CreateStringStererotypeValueOperation operation = new CreateStringStererotypeValueOperation(editingDomain, "Create new String Value", objectToEdit);
+ if(operation != null) {
+ command.add(operation);
+ }
+ if(indexOfNewValue == NEW_VALUE_NOT_SET_INDEX) { // try to update
+ indexOfNewValue = operation.getIndexOfNewValue();
+ }
+ }
+
+ operations.add(command.reduce());
+
+ return operations;
+ }
+
+ /**
+ * Operation to create a String value for the controlled property of a stereotype
+ */
+ protected class CreateStringStererotypeValueOperation extends AbstractTransactionalCommand {
+
+ /** object to edit */
+ protected final EObject objectToEdit;
+
+ /** index of the value to add (-1 in case of single valued property) */
+ private int indexOfNewValue = -2;
+
+ /**
+ * Initializes me with the editing domain, a label, transaction options, and
+ * a list of {@link IFile}s that anticipate modifying when I am executed,
+ * undone or redone.
+ *
+ * @param domain
+ * the editing domain used to modify the model
+ * @param label
+ * my user-readable label, should never be <code>null</code>.
+ * @param objectToEdit
+ * the {@link EObject} to edit
+ */
+ public CreateStringStererotypeValueOperation(TransactionalEditingDomain domain, String label, EObject objectToEdit) {
+ super(domain, (label == null) ? "" : label, null);
+ this.objectToEdit = objectToEdit;
+
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit.getUpperBound() == 1) {
+ indexOfNewValue = -1;
+ } else {
+ @SuppressWarnings("unchecked")
+ List<Object> values = new ArrayList<Object>((List<Object>)getValueToEdit(objectToEdit));
+ indexOfNewValue = values.size();
+ }
+ }
+
+ /**
+ * Returns the index at which the value will be added
+ *
+ * @return the index at which the value will be added
+ */
+ public int getIndexOfNewValue() {
+ return indexOfNewValue;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected CommandResult doExecuteWithResult(IProgressMonitor monitor, IAdaptable info) throws ExecutionException {
+ // create the value and add it to the feature
+ // if feature = simple valued => set
+ // if feature = multi valued => add at the end
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit == null) {
+ return CommandResult.newErrorCommandResult("Impossible to find the feature " + getFeatureName());
+ }
+ Object newValue;
+ if(featureToEdit.getUpperBound() == 1) {
+ newValue = getInitialValue(objectToEdit);
+ } else {
+ @SuppressWarnings("unchecked")
+ List<Object> values = (List<Object>)getValueToEdit(objectToEdit);
+ values.add(indexOfNewValue, getInitialValue(objectToEdit));
+ newValue = values;
+ }
+ setValueInModel(objectToEdit, newValue);
+ return CommandResult.newOKCommandResult();
+ }
+ }
+
+ /**
+ * Returns the initial value for a new value of the feature
+ *
+ * @param objectToEdit
+ * the object to edit
+ *
+ * @return the initial value, not <code>null</code>
+ */
+ public Object getInitialValue(EObject objectToEdit) {
+ String featureName = getFeatureName();
+ EStructuralFeature featureToEdit = getFeatureByName(objectToEdit);
+ if(featureToEdit.getUpperBound() == 1) {
+ return featureName;
+ } else {
+ for(int suffix = 0; suffix < 1000; suffix++) {
+ String tmpName = featureName + suffix;
+ boolean found = false;
+ @SuppressWarnings("unchecked")
+ List<Object> values = new ArrayList<Object>((List<Object>)getValueToEdit(objectToEdit));
+ for(Object value : values) {
+ if(tmpName.equals(value)) {
+ found = true;
+ }
+ }
+ if(!found) {
+ return tmpName;
+ }
+ }
+ return featureName;
+ }
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/StringStereotypeModelHandlerFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/StringStereotypeModelHandlerFactory.java
new file mode 100644
index 00000000000..6cf963f9db7
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/StringStereotypeModelHandlerFactory.java
@@ -0,0 +1,44 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.modelhandler.IPropertyModelHandlerFactory;
+import org.w3c.dom.Node;
+
+
+/**
+ * Factory that creates {@link StringStereotypeModelHandler}.
+ */
+public class StringStereotypeModelHandlerFactory extends StereotypeModelHandlerFactory implements IPropertyModelHandlerFactory {
+
+ /**
+ * Creates a new StringStereotypeModelHandlerFactory.
+ */
+ public StringStereotypeModelHandlerFactory() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public StringStereotypeModelHandler createModelHandler(Node modelHandlerNode) {
+ // specific code to parse the given element
+ String featureName = retrieveFeatureName(modelHandlerNode);
+ String stereotypeName = retrieveStereotypeName(modelHandlerNode);
+ if(featureName == null || stereotypeName == null) {
+ Activator.log.warn("Impossible to retrieve feature name and/or stereotype name from node " + modelHandlerNode);
+ return null;
+ }
+ return new StringStereotypeModelHandler(stereotypeName, featureName);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/TransactionUtil.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/TransactionUtil.java
new file mode 100644
index 00000000000..fd8b0f71007
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/modelhandler/emf/TransactionUtil.java
@@ -0,0 +1,63 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.modelhandler.emf;
+
+import org.eclipse.emf.transaction.Transaction;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.emf.transaction.impl.InternalTransaction;
+import org.eclipse.emf.transaction.impl.InternalTransactionalEditingDomain;
+
+
+/**
+ * Utility class for transactions
+ */
+public class TransactionUtil {
+
+ /**
+ * Checks if the current active transaction is a Write transaction or not
+ * unprotected transaction are not considered write transaction
+ *
+ * @param internalEditingDomain
+ * the current internal editing domain, on which transaction are run
+ * @param includeUnprotected
+ * <code>boolean</code> value that if <code>true</code> will consider unprotected
+ * transactions when determining if a write transaction is in progress.
+ * @param otherThread
+ * <code>boolean</code> value that if <code>true</code>, will verify whether there is
+ * an active transaction only when on a different thread then the caller. This is useful to determine if a
+ * deadlock scenario will occur.
+ * @return <code>true</code> if the current active transaction is a write transaction
+ */
+ public static boolean isReadTransactionInProgress(TransactionalEditingDomain internalEditingDomain, boolean includeUnprotected, boolean otherThread) {
+ if(!(internalEditingDomain instanceof InternalTransactionalEditingDomain)) {
+ return false;
+ }
+
+ InternalTransaction transaction = ((InternalTransactionalEditingDomain)internalEditingDomain).getActiveTransaction();
+ if(transaction != null && transaction.isReadOnly()) {
+ if(includeUnprotected) {
+ Object unprotectedMode = transaction.getOptions().get(Transaction.OPTION_UNPROTECTED);
+ if(Boolean.FALSE.equals(unprotectedMode)) {
+ return false;
+ }
+ }
+
+ if(otherThread && Thread.currentThread() != transaction.getOwner())
+ return true;
+ else if(!otherThread) {
+ return true;
+ }
+ return true;
+ }
+ return false;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/AbstractPropertyEditor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/AbstractPropertyEditor.java
new file mode 100644
index 00000000000..09a3c753c32
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/AbstractPropertyEditor.java
@@ -0,0 +1,281 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.PropertyEditorController;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.graphics.FontMetrics;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.ui.forms.widgets.FormToolkit;
+import org.eclipse.ui.services.IDisposable;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+
+
+/**
+ * Abstract class for all proprty editors
+ */
+public abstract class AbstractPropertyEditor implements IDisposable {
+
+ /** margin added to the computed text */
+ protected static final int TEXT_MARGIN = 5;
+
+ /** margin added to the computed text */
+ protected static final int LABEL_MAX_WIDTH= 100;
+
+ /** controller that manages this editor */
+ private PropertyEditorController controller;
+
+ /** widget factory used to create controls. Not a {@link FormToolkit} because there are missing elements (CCombo, CLabel, etc.) */
+ private TabbedPropertySheetWidgetFactory widgetFactory;
+
+ /** read oonly status for the editor */
+ private boolean isReadOnly = false;
+
+ /** configuration for the property editor */
+ private IPropertyEditorDescriptor descriptor = null;
+
+ /** the tooltip for this controller */
+ private String tooltipText = null;
+
+
+ /**
+ * Creates a new {@link AbstractPropertyEditor}. It uses a created widget factory each time a property editor is created, the other constructor
+ * {@link #AbstractPropertyEditor(TabbedPropertySheetWidgetFactory)} should be used instead.
+ */
+ public AbstractPropertyEditor() {
+ this(new TabbedPropertySheetWidgetFactory());
+ }
+
+ /**
+ * Creates a new {@link AbstractPropertyEditor}.
+ *
+ * @param widgetFactory
+ * widget factory used to create {@link Control}
+ */
+ public AbstractPropertyEditor(TabbedPropertySheetWidgetFactory widgetFactory) {
+ this.widgetFactory = widgetFactory;
+ }
+
+
+ /**
+ * Returns the controller that manages this editor
+ *
+ * @return the controller that manages this editor
+ */
+ protected PropertyEditorController getController() {
+ return controller;
+ }
+
+ /**
+ * Returns the widget factory used to create composites in tabbed property sheet pages
+ *
+ * @return the widget factory
+ */
+ public TabbedPropertySheetWidgetFactory getWidgetFactory() {
+ return widgetFactory;
+ }
+
+
+ /**
+ * Sets the new widget factory used to create composites
+ *
+ * @param widgetFactory
+ * the widgetFactory to set
+ */
+ public void setWidgetFactory(TabbedPropertySheetWidgetFactory widgetFactory) {
+ this.widgetFactory = widgetFactory;
+ }
+
+ /**
+ * Sets the new controller.
+ *
+ * @param controller
+ * the new controller
+ */
+ public void setController(PropertyEditorController controller) {
+ this.controller = controller;
+ }
+
+ /**
+ * Sets the read only status of the editor
+ *
+ * @param isReadOnly
+ * <code>true</code> if the editor should be read-only.
+ */
+ public void setIsReadOnly(boolean isReadOnly) {
+ this.isReadOnly = isReadOnly;
+ }
+
+ /**
+ * Returns the read-only status of the editor
+ *
+ * @return <code>true</code> if the editor is in read-only mode
+ */
+ public boolean getIsReadOnly() {
+ return isReadOnly;
+ }
+
+ /**
+ * Returns the tooltip text of the editor
+ *
+ * @return the tooltip text
+ */
+ public String getTooltipText() {
+ return tooltipText;
+ }
+
+ /**
+ * Sets the tooltip text of the editor
+ *
+ * @param toolTipText
+ * the tooltip for the editor.
+ */
+ public void setTooltipText(String toolTipText) {
+ this.tooltipText = toolTipText;
+ }
+
+
+ /**
+ * Creates the display for this editor
+ *
+ * @param parent
+ * the parent composite for created elements
+ * @return the newly created composite
+ */
+ public abstract Composite createContent(Composite parent);
+
+ /**
+ * Indicates that the content of the editor has changed, and that the model should be updated
+ */
+ public abstract void handleContentChanged();
+
+ /**
+ * Initializes the content of the property editor, for example enumeration literals for enumeration, etc.
+ *
+ * @param descriptor
+ * the descriptor used for initialization
+ * @return the result of the initialization
+ */
+ public abstract IStatus init(IPropertyEditorDescriptor descriptor);
+
+ /**
+ * Returns the configuration for this editor
+ *
+ * @return the configuration for this editor
+ */
+ public IPropertyEditorDescriptor getDescriptor() {
+ return descriptor;
+ }
+
+ /**
+ * Sets the configuration for this editor.
+ *
+ * @param descriptor
+ * the configuration for this editor
+ */
+ public void setDescriptor(IPropertyEditorDescriptor descriptor) {
+ this.descriptor = descriptor;
+ }
+
+ /**
+ * Returns the current value in the editor
+ *
+ * @return the current value in the editor
+ */
+ public abstract Object getValue();
+
+ /**
+ * Sets the value to edit
+ *
+ * @param valueToEdit
+ * the value to edit
+ */
+ public abstract void setValue(Object valueToEdit);
+
+ /**
+ * {@inheritDoc}
+ */
+ public abstract void dispose();
+
+ /**
+ * Checks if the editor is disposed or not.
+ *
+ * @return <code>true</code> if the editor is disposed
+ */
+ public abstract boolean isDisposed();
+
+ /**
+ * Indicates if the control is valid, i.e. not null and not disposed
+ *
+ * @param control
+ * the control to test
+ * @return
+ */
+ protected boolean isValid(Control control) {
+ return (control != null && !control.isDisposed());
+ }
+
+ /**
+ * Creates the label area for the property editor
+ *
+ * @param parent
+ * the composite parent of the label
+ * @return the label
+ */
+ protected Control createLabel(Composite parent) {
+ GridData data = new GridData(SWT.FILL, SWT.CENTER, false, false);
+ String text = getDescriptor().getLabel();
+ int size = computeLabelSize(parent, text);
+ data.minimumWidth = Math.max(LABEL_MAX_WIDTH, size);
+ data.widthHint = data.minimumWidth;
+ return createLabel(parent, data);
+ }
+
+ /**
+ * Computes the size of the given label
+ * @param text the text to compute
+ * @return the approximate size of the text
+ */
+ protected int computeLabelSize(Composite parent, String text) {
+ GC gc = new GC (parent);
+ FontMetrics fm = gc.getFontMetrics ();
+ int width = text.length() * fm.getAverageCharWidth ();
+ gc.dispose ();
+ return width;
+ }
+
+ /**
+ * Creates the label area for the property editor
+ *
+ * @param parent
+ * the composite parent of the label
+ * @param layoutData
+ * layout data to apply to this editor
+ * @return the label
+ */
+ protected Control createLabel(Composite parent, Object layoutData) {
+ CLabel label = getWidgetFactory().createCLabel(parent, getDescriptor().getLabel());
+ if(getDescriptor().getLabelImageDescriptor() != null) {
+ label.setImage(Activator.getImageFromDescriptor(getDescriptor().getLabelImageDescriptor()));
+ }
+ label.setToolTipText(getTooltipText());
+ label.setLayoutData(layoutData);
+ return label;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/AbstractTablePropertyEditor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/AbstractTablePropertyEditor.java
new file mode 100644
index 00000000000..b0c763ccb26
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/AbstractTablePropertyEditor.java
@@ -0,0 +1,497 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.operations.IUndoableOperation;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.layout.TableColumnLayout;
+import org.eclipse.jface.viewers.ColumnWeightData;
+import org.eclipse.jface.viewers.EditingSupport;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.papyrus.commands.CheckedOperationHistory;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.ILabelProviderController;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.MenuItem;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.ui.PlatformUI;
+
+
+/**
+ * Abstract class for all table editors
+ */
+public abstract class AbstractTablePropertyEditor extends AbstractPropertyEditor {
+
+ /** main composite created by this property editor */
+ protected Composite composite;
+
+ /** button to add a reference or modify existing one */
+ protected Button addButton;
+
+ /** button to remove reference */
+ protected Button removeButton;
+
+ /** table area that displays the values */
+ protected Table table;
+
+ /** viewer on the previous table */
+ protected TableViewer viewer;
+
+ /** current Value in the editor */
+ protected List<Object> currentValue;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Composite createContent(Composite parent) {
+ composite = getWidgetFactory().createComposite(parent, SWT.NONE);
+ int columnNu = getColumnNumber();
+ GridLayout layout = new GridLayout(columnNu, false);
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ composite.setLayout(layout);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
+ composite.setLayoutData(data);
+
+ // creates label. No TOP/DOWN/etc. position, always on top
+ createLabel(composite);
+
+ if(!getIsReadOnly()) {
+ // create Button area
+ addButton = getWidgetFactory().createButton(composite, "", SWT.NONE);
+ addButton.setImage(Activator.getImageFromDescriptor(Activator.imageDescriptorFromPlugin(Activator.ID, "icons/Add_12x12.gif")));
+ data = new GridData(SWT.FILL, SWT.CENTER, false, false);
+ addButton.setLayoutData(data);
+ addButton.addMouseListener(new MouseListener() {
+
+ /**
+ * {@inheritDoc}
+ */
+ public void mouseUp(MouseEvent e) {
+ performAddButtonPressed();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void mouseDown(MouseEvent e) {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void mouseDoubleClick(MouseEvent e) {
+ }
+ });
+
+ removeButton = getWidgetFactory().createButton(composite, "", SWT.NONE);
+ removeButton.setImage(Activator.getImageFromDescriptor(Activator.imageDescriptorFromPlugin(Activator.ID, "icons/Delete_12x12.gif")));
+ data = new GridData(SWT.FILL, SWT.CENTER, false, false);
+ removeButton.setLayoutData(data);
+ removeButton.addMouseListener(new MouseListener() {
+
+ /**
+ * {@inheritDoc}
+ */
+ public void mouseUp(MouseEvent e) {
+ performRemoveButtonPressed();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void mouseDown(MouseEvent e) {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void mouseDoubleClick(MouseEvent e) {
+
+ }
+ });
+
+ if(getController().canMoveValues(new ArrayList<Integer>(), 0)) { // only checks if virtual elements can be moved, not real move, so a 0-delta is fine
+ Button upButton = getWidgetFactory().createButton(composite, "", SWT.NONE);
+ upButton.setImage(Activator.getImageFromDescriptor(Activator.imageDescriptorFromPlugin(Activator.ID, "icons/Up_12x12.gif")));
+ data = new GridData(SWT.FILL, SWT.CENTER, false, false);
+ upButton.setLayoutData(data);
+ upButton.addMouseListener(new MouseListener() {
+
+ /**
+ * {@inheritDoc}
+ */
+ public void mouseUp(MouseEvent e) {
+ performUpButtonPressed();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void mouseDown(MouseEvent e) {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void mouseDoubleClick(MouseEvent e) {
+ }
+ });
+
+ Button downButton = getWidgetFactory().createButton(composite, "", SWT.NONE);
+ downButton.setImage(Activator.getImageFromDescriptor(Activator.imageDescriptorFromPlugin(Activator.ID, "icons/Down_12x12.gif")));
+ data = new GridData(SWT.FILL, SWT.CENTER, false, false);
+ downButton.setLayoutData(data);
+ downButton.addMouseListener(new MouseListener() {
+
+ /**
+ * {@inheritDoc}
+ */
+ public void mouseUp(MouseEvent e) {
+ performDownButtonPressed();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void mouseDown(MouseEvent e) {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void mouseDoubleClick(MouseEvent e) {
+ }
+ });
+ }
+ }
+
+ Composite tableComposite = getWidgetFactory().createComposite(composite, SWT.NONE);
+ data = new GridData(SWT.FILL, SWT.FILL, true, true, columnNu, 1);
+ data.heightHint = 80;
+ data.widthHint = 200;
+ tableComposite.setLayoutData(data);
+ // creates table for the display of references
+ table = new Table(tableComposite, SWT.BORDER | SWT.MULTI);
+ viewer = new TableViewer(table);
+ TableColumnLayout tableLayout = new TableColumnLayout();
+ tableComposite.setLayout(tableLayout);
+ final TableViewerColumn tableViewerColumn = new TableViewerColumn(viewer, SWT.NONE);
+ TableColumn tableColumn = tableViewerColumn.getColumn();
+ tableLayout.setColumnData(tableColumn, new ColumnWeightData(100, 0, true));
+ tableColumn.setText("Value");
+ tableViewerColumn.setEditingSupport(createEditingSupport());
+ viewer.setUseHashlookup(true);
+ viewer.setContentProvider(new IStructuredContentProvider() {
+
+ /**
+ * {@inheritDoc}
+ */
+ public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void dispose() {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object[] getElements(Object inputElement) {
+ if(inputElement instanceof List<?>) {
+ return ((List<?>)inputElement).toArray();
+ }
+ return new Object[0];
+ }
+ });
+
+ if(getController() instanceof ILabelProviderController) {
+ viewer.setLabelProvider(((ILabelProviderController)getController()).getEditorLabelProvider());
+ } else {
+ viewer.setLabelProvider(new LabelProvider());
+ }
+ viewer.getControl().setToolTipText(getTooltipText());
+ return composite;
+ }
+
+ /**
+ * Creates the editing support for the table viewer
+ *
+ * @return the editing support for the table viewer
+ */
+ protected abstract EditingSupport createEditingSupport();
+
+ /**
+ * performs the action handled by the "Add" button
+ */
+ protected void performAddButtonPressed() {
+ // pops up a window to ask for a new reference
+ Display display = Display.getCurrent();
+ if(display == null && PlatformUI.isWorkbenchRunning()) {
+ display = PlatformUI.getWorkbench().getDisplay();
+ }
+ display = (display != null) ? display : Display.getDefault();
+
+ List<IUndoableOperation> operations = getController().getCreateValueOperations();
+
+ // either one or more options
+ // in case there are several, open a sub-menu
+ // otherwise, execute the operation
+ if(operations == null || operations.isEmpty()) {
+ return;
+ }
+ if(operations.size() == 1) {
+ try {
+ CheckedOperationHistory.getInstance().execute(operations.get(0), new NullProgressMonitor(), null);
+ } catch (ExecutionException e1) {
+ Activator.log.error(e1);
+ }
+ } else {
+ Menu menu = new Menu(addButton);
+ for(final IUndoableOperation operation : operations) {
+ MenuItem item = new MenuItem(menu, SWT.NONE);
+ item.setText(operation.getLabel());
+ item.addSelectionListener(new SelectionListener() {
+
+ public void widgetSelected(SelectionEvent e) {
+ try {
+ CheckedOperationHistory.getInstance().execute(operation, new NullProgressMonitor(), null);
+ } catch (ExecutionException e1) {
+ Activator.log.error(e1);
+ }
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+
+ }
+ });
+ }
+ menu.setVisible(true);
+ }
+
+ // now select the new value added. Assumes this is the last one
+ int lastIndex = table.getItemCount() - 1;
+ table.select(lastIndex);
+
+ }
+
+ /**
+ * performs the action handled by the "Remove" button
+ */
+ protected void performRemoveButtonPressed() {
+ // use selection to remove element
+ // retrieve selected element(s)
+ IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
+ if(selection == null || selection.isEmpty()) {
+ // nothing selected.
+ return;
+ }
+
+ int[] selectedIndexes = table.getSelectionIndices();
+ Arrays.sort(selectedIndexes);
+ List<Integer> indexes = new ArrayList<Integer>();
+ for(int i = selectedIndexes.length - 1; i >= 0; i--) {
+ indexes.add(selectedIndexes[i]);
+ }
+ IUndoableOperation operation = getController().getDeleteValueOperation(indexes);
+ if(operation != null && operation.canExecute()) {
+ try {
+ CheckedOperationHistory.getInstance().execute(operation, new NullProgressMonitor(), null);
+ } catch (ExecutionException e1) {
+ Activator.log.error(e1);
+ }
+ }
+ }
+
+ /**
+ * performs the action handled by the "Up" button
+ */
+ protected void performUpButtonPressed() {
+ int[] selectionIndices = table.getSelectionIndices();
+ final List<Integer> selectionList = new ArrayList<Integer>();
+ final List<Integer> newSelectionList = new ArrayList<Integer>();
+ for(int i : selectionIndices) {
+ selectionList.add(i);
+ newSelectionList.add(i - 1);
+ }
+ IUndoableOperation moveOperation = getController().getMoveCurrentValuesOperation(selectionList, -1);
+ if(moveOperation != null && moveOperation.canExecute()) {
+ try {
+ CheckedOperationHistory.getInstance().execute(moveOperation, new NullProgressMonitor(), null);
+ // try to restore selection in the view
+ int[] newSelection = new int[newSelectionList.size()];
+ for(int i = 0; i < newSelectionList.size(); i++) {
+ newSelection[i] = newSelectionList.get(i);
+ }
+ table.select(newSelection);
+ } catch (ExecutionException e1) {
+ Activator.log.error(e1);
+ }
+ }
+ }
+
+ /**
+ * performs the action handled by the "Down" button
+ */
+ protected void performDownButtonPressed() {
+ // use selection to remove element
+ // retrieve selected element(s)
+ int[] selectionIndices = table.getSelectionIndices();
+ final List<Integer> selectionList = new ArrayList<Integer>();
+ final List<Integer> newSelectionList = new ArrayList<Integer>();
+ for(int i : selectionIndices) {
+ selectionList.add(i);
+ newSelectionList.add(i + 1);
+ }
+ IUndoableOperation moveOperation = getController().getMoveCurrentValuesOperation(selectionList, +1);
+ if(moveOperation != null && moveOperation.canExecute()) {
+ try {
+ CheckedOperationHistory.getInstance().execute(moveOperation, new NullProgressMonitor(), null);
+ // try to restore selection in the view
+ int[] newSelection = new int[newSelectionList.size()];
+ for(int i = 0; i < newSelectionList.size(); i++) {
+ newSelection[i] = newSelectionList.get(i);
+ }
+ table.select(newSelection);
+ } catch (ExecutionException e1) {
+ Activator.log.error(e1);
+ }
+ }
+ }
+
+
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Control createLabel(Composite parent) {
+ GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
+ return createLabel(parent, data);
+ }
+
+ /**
+ * Returns the number of column for the composite
+ *
+ * @return the number of column for the composite
+ */
+ protected int getColumnNumber() {
+ if(getIsReadOnly()) {
+ return 1;
+ }
+ if(getController().canMoveValues(new ArrayList<Integer>(), 0)) {
+ return 5;
+ }
+ return 3;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleContentChanged() {
+ // this should tells the controller that the input has to be applied to the model
+ getController().updateModel();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IStatus init(IPropertyEditorDescriptor descriptor) {
+ setDescriptor(descriptor);
+ setTooltipText(descriptor.getTooltipText());
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<Object> getValue() {
+ return currentValue;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @SuppressWarnings("unchecked")
+ @Override
+ public void setValue(Object valueToEdit) {
+ if(!isValid(table)) {
+ return;
+ }
+ if(valueToEdit instanceof List<?>) {
+ currentValue = (List<Object>)valueToEdit;
+ } else if(valueToEdit == null) {
+ currentValue = null;
+ } else {
+ Activator.log.error(valueToEdit + " is not a list of Object for current table: " + getDescriptor().getLabel(), null);
+ }
+ viewer.setInput((currentValue != null) ? currentValue : Collections.emptyList());
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void dispose() {
+ if(isValid(composite)) {
+ composite.dispose();
+ composite = null;
+ setController(null);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isDisposed() {
+ if(composite == null) {
+ return true;
+ }
+ return composite.isDisposed();
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/ComboPropertyEditor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/ComboPropertyEditor.java
new file mode 100644
index 00000000000..f67173d6180
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/ComboPropertyEditor.java
@@ -0,0 +1,202 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IBoundedValuesPropertyEditorDescriptor;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CCombo;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * Property editors for enumeration
+ */
+public class ComboPropertyEditor extends AbstractPropertyEditor {
+
+ /** id of this editor */
+ public static final String ID = "org.eclipse.papyrus.properties.runtime.comboPropertyEditor";
+
+ /** main composite created by this property editor */
+ private Composite composite;
+
+ /** list of available elements */
+ protected List<String> values = new ArrayList<String>();
+
+ /** combo that edit values */
+ private CCombo combo;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Composite createContent(Composite parent) {
+ composite = getWidgetFactory().createComposite(parent, SWT.NONE);
+ int columnNu = getColumnNumber();
+ GridLayout layout = new GridLayout(columnNu, false);
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ composite.setLayout(layout);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
+ composite.setLayoutData(data);
+
+ if((getDescriptor().getLabelPosition() & (SWT.LEFT | SWT.TOP)) != 0) {
+ createLabel(composite);
+ }
+
+ combo = getWidgetFactory().createCCombo(composite, SWT.FLAT | SWT.BORDER | SWT.READ_ONLY);
+ combo.setItems(values.toArray(new String[]{}));
+ data = new GridData(SWT.FILL, SWT.FILL, true, false);
+ combo.setLayoutData(data);
+ getWidgetFactory().adapt(combo);
+ combo.addFocusListener(new FocusListener() {
+
+ public void focusLost(FocusEvent e) {
+ handleContentChanged();
+ }
+
+ public void focusGained(FocusEvent e) {
+ }
+ });
+ combo.addSelectionListener(new SelectionListener() {
+
+ public void widgetSelected(SelectionEvent e) {
+ handleContentChanged();
+ }
+
+ public void widgetDefaultSelected(SelectionEvent e) {
+ }
+ });
+ combo.setEnabled(!getIsReadOnly());
+
+ if((getDescriptor().getLabelPosition() & (SWT.RIGHT | SWT.BOTTOM)) != 0) {
+ createLabel(composite);
+ }
+
+ combo.setToolTipText(getTooltipText());
+
+ return composite;
+ }
+
+ /**
+ * Returns the number of column for the composite
+ *
+ * @return the number of column for the composite
+ */
+ protected int getColumnNumber() {
+ if((getDescriptor().getLabelPosition() & (SWT.TOP | SWT.BOTTOM)) != 0) {
+ return 1;
+ }
+ return 2;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void dispose() {
+ if(isValid(composite)) {
+ composite.dispose();
+ composite = null;
+ setController(null);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isDisposed() {
+ if(composite == null) {
+ return true;
+ }
+ return composite.isDisposed();
+ }
+
+ /**
+ * Returns the current String value or <code>null</code> if no elements were selected
+ */
+ @Override
+ public Object getValue() {
+ if(isValid(combo)) {
+ int index = combo.getSelectionIndex();
+ if(index >= 0 && index < values.size()) {
+ return values.get(index);
+ }
+ } else {
+ Activator.log.error("trying to read the value of the combo whereas the combo is disposed", null);
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleContentChanged() {
+ // this should tells the controller that the input has to be applied to the model
+ getController().updateModel();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IStatus init(IPropertyEditorDescriptor descriptor) {
+ setDescriptor(descriptor);
+ setTooltipText(descriptor.getTooltipText());
+ if(descriptor instanceof IBoundedValuesPropertyEditorDescriptor) {
+ List<?> values = ((IBoundedValuesPropertyEditorDescriptor)descriptor).getAvailableValues();
+ if(values != null) {
+ for(Object object : values) {
+ this.values.add(object.toString());
+ }
+ }
+ return Status.OK_STATUS;
+ }
+ return new Status(IStatus.ERROR, Activator.ID, "Impossible to initialize the editor using descriptor :" + descriptor);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setValue(Object valueToEdit) {
+ if(!isValid(combo)) {
+ return;
+ }
+ if(valueToEdit instanceof String) {
+ String newValue = (String)valueToEdit;
+ if(values == null) {
+ return;
+ }
+ int index = values.indexOf(newValue);
+ if(index >= 0) {
+ combo.select(values.indexOf(newValue));
+ } else {
+ Activator.log.error("Impossible to get the value " + valueToEdit + " in the list of available values", null);
+ }
+ }
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/CreatePropertyEditorDescriptorOperation.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/CreatePropertyEditorDescriptorOperation.java
new file mode 100644
index 00000000000..90ca9ef3a99
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/CreatePropertyEditorDescriptorOperation.java
@@ -0,0 +1,64 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+import org.eclipse.gmf.runtime.common.core.service.IOperation;
+import org.eclipse.gmf.runtime.common.core.service.IProvider;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.w3c.dom.Node;
+
+
+/**
+ * Operation that creates the descriptor for a given editor
+ */
+public class CreatePropertyEditorDescriptorOperation implements IOperation {
+
+ /** configuration node for this operation */
+ private Node editorNode;
+
+ /** editor unique identifier */
+ private String editorID;
+
+ /**
+ * Creates a new CreatePropertyEditorDescriptorOperation.
+ *
+ * @param editorID
+ * the id of the editor to create
+ * @param editorNode
+ * the configuration node for this editor descriptor
+ */
+ public CreatePropertyEditorDescriptorOperation(String editorID, Node editorNode) {
+ this.editorNode = editorNode;
+ this.editorID = editorID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IPropertyEditorDescriptor execute(IProvider provider) {
+ if(provider instanceof PropertyEditorProvider) {
+ return ((PropertyEditorProvider)provider).createPropertyEditorDescriptor(editorID, editorNode);
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns the editor identifier
+ *
+ * @return the editor identifier
+ */
+ public String getEditorId() {
+ return editorID;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/CreatePropertyEditorOperation.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/CreatePropertyEditorOperation.java
new file mode 100644
index 00000000000..a8acadb9ad7
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/CreatePropertyEditorOperation.java
@@ -0,0 +1,83 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+import org.eclipse.gmf.runtime.common.core.service.IOperation;
+import org.eclipse.gmf.runtime.common.core.service.IProvider;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.PropertyEditorController;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * Operation that creates an {@link AbstractPropertyEditor} from a provider
+ */
+public class CreatePropertyEditorOperation implements IOperation {
+
+ /** parent composite for the created widgets */
+ protected Composite parent;
+
+ /** identifier of the specific editor to find */
+ protected final String editorIdentifier;
+
+ /** indicates if the property to edit is multi-valued */
+ protected final boolean multiValue;
+
+ /** controller which requires the property editor creation */
+ protected PropertyEditorController controller;
+
+ /**
+ * Constructor.
+ *
+ * @param controller
+ * the controller that manages the created editor
+ * @param id
+ * the identifier of the editor to find
+ */
+ public CreatePropertyEditorOperation(PropertyEditorController controller, String id) {
+ this.controller = controller;
+ this.editorIdentifier = id;
+ this.multiValue = false;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public AbstractPropertyEditor execute(IProvider provider) {
+ if(provider instanceof PropertyEditorProvider) {
+ AbstractPropertyEditor editor = ((PropertyEditorProvider)provider).createPropertyEditor(editorIdentifier, controller);
+ return editor;
+ } else {
+ Activator.log.error("CreatePropertyEditorOperation should execute on a PropertyEditorProvider", null);
+ }
+ return null;
+ }
+
+ /**
+ * Returns the identifier of the specific editor to find
+ *
+ * @return the identifier of the specific editor to find. It can be <code>null</code>. In this case, feature should not be <code>null</code>
+ */
+ public String getEditorIdentifier() {
+ return editorIdentifier;
+ }
+
+ /**
+ * Returns <code>true</code> if the property to edit is multi-valued
+ *
+ * @return <code>true</code> if the property to edit is multi-valued
+ */
+ public boolean isMultiValue() {
+ return multiValue;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/GroupedRadioBoxPropertyEditor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/GroupedRadioBoxPropertyEditor.java
new file mode 100644
index 00000000000..6d932dd6a26
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/GroupedRadioBoxPropertyEditor.java
@@ -0,0 +1,81 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+
+
+/**
+ * Property editors for enumeration
+ */
+public class GroupedRadioBoxPropertyEditor extends RadioBoxPropertyEditor {
+
+ /**
+ * Creates a new RadioBoxPropertyEditor
+ */
+ public GroupedRadioBoxPropertyEditor() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Composite createContent(Composite parent) {
+ composite = getWidgetFactory().createComposite(parent, SWT.NONE);
+ GridLayout layout = new GridLayout();
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ composite.setLayout(layout);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, false, false);
+ composite.setLayoutData(data);
+
+ // creates the group (label is the getLabel() value)
+ Group group = getWidgetFactory().createGroup(composite, getDescriptor().getLabel());
+ GridLayout layout2 = new GridLayout(getColumnNumber(), true);
+ group.setLayout(layout2);
+
+ // layout in the group => number of column derived from the number of line ?
+
+ // create the set of radio-boxes. Does not know the size of the grid used for this editor
+ for(String value : values) {
+ Button button = getWidgetFactory().createButton(group, (!value.equals("") ? value : "<Unset>"), SWT.RADIO);
+ button.addSelectionListener(listener);
+ buttons.add(button);
+ button.setToolTipText(getTooltipText());
+ }
+
+ return composite;
+ }
+
+ /**
+ * Returns the number of column for the composite
+ *
+ * @return the number of column for the composite
+ */
+ protected int getColumnNumber() {
+ return (values.size() + ((((getDescriptor().getLabelPosition() & SWT.RIGHT | SWT.LEFT)) != 0) ? 1 : 0)) / getLineNumber();
+ }
+
+ /**
+ * Returns the number of line required in the group
+ *
+ * @return the number of line required in the group
+ */
+ protected int getLineNumber() {
+ return 3;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/IPropertyEditorTypeValidator.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/IPropertyEditorTypeValidator.java
new file mode 100644
index 00000000000..9d026ec7353
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/IPropertyEditorTypeValidator.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+
+/**
+ * Validator for property editors. It checks if the given editor is able to edit a specific type of value
+ */
+public interface IPropertyEditorTypeValidator {
+
+ /**
+ * returns <code>true</code> if the associated editor is able to edit the specified object
+ *
+ * @param valueToEdit
+ * the vlaue to edit
+ * @return <code>true</code> if the associated editor is able to edit the specified object
+ */
+ public boolean isValidForValue(Object valueToEdit);
+
+ /**
+ * Sets the validated editor
+ *
+ * @param editor
+ * the editor to valid
+ */
+ public void setPropertyEditor(AbstractPropertyEditor editor);
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultiplePrimitiveTypedPropertyEditor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultiplePrimitiveTypedPropertyEditor.java
new file mode 100644
index 00000000000..728c51bdb16
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultiplePrimitiveTypedPropertyEditor.java
@@ -0,0 +1,100 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.commands.operations.IUndoableOperation;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.jface.viewers.CellEditor;
+import org.eclipse.jface.viewers.ColumnViewer;
+import org.eclipse.jface.viewers.EditingSupport;
+import org.eclipse.jface.viewers.TextCellEditor;
+import org.eclipse.papyrus.commands.CheckedOperationHistory;
+import org.eclipse.papyrus.properties.runtime.Activator;
+
+
+/**
+ * Property editor for Primitive typed-properties
+ */
+public class MultiplePrimitiveTypedPropertyEditor extends AbstractTablePropertyEditor {
+
+ /** id of this editor */
+ public static final String ID = "org.eclipse.papyrus.properties.runtime.multiplePrimitiveTypedPropertyEditor";
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected EditingSupport createEditingSupport() {
+ return new StringEditingSupport(viewer);
+ }
+
+ /**
+ * Editing support for the viewer
+ */
+ protected class StringEditingSupport extends EditingSupport {
+
+ /**
+ * Creates a new StringEditingSupport.
+ *
+ * @param viewer
+ * the viewer in which this suport is added
+ */
+ public StringEditingSupport(ColumnViewer viewer) {
+ super(viewer);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected CellEditor getCellEditor(Object element) {
+ return new TextCellEditor(table);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected boolean canEdit(Object element) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Object getValue(Object element) {
+ return element;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected void setValue(Object element, Object value) {
+ // retrieve the index of the element in the list of values
+ int index = viewer.getTable().getSelectionIndex();
+ // retrieves the operation to set the value
+ IUndoableOperation operation = getController().getEditValueOperation(index, table, value);
+ if(operation != null && operation.canExecute()) {
+ try {
+ CheckedOperationHistory.getInstance().execute(operation, new NullProgressMonitor(), null);
+ } catch (ExecutionException e) {
+ Activator.log.error(e);
+ }
+ }
+ }
+
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultiplePrimitiveTypedPropertyEditorValidator.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultiplePrimitiveTypedPropertyEditorValidator.java
new file mode 100644
index 00000000000..5a355f9488b
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultiplePrimitiveTypedPropertyEditorValidator.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+/**
+ * Validator for {@link MultiplePrimitiveTypedPropertyEditor}
+ */
+public class MultiplePrimitiveTypedPropertyEditorValidator implements IPropertyEditorTypeValidator {
+
+ /** editor fo which this validator is installed */
+ protected AbstractPropertyEditor editor;
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isValidForValue(Object valueToEdit) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setPropertyEditor(AbstractPropertyEditor editor) {
+ this.editor = editor;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultipleReferencePropertyEditor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultipleReferencePropertyEditor.java
new file mode 100644
index 00000000000..836a9ac2b9a
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultipleReferencePropertyEditor.java
@@ -0,0 +1,367 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+import org.eclipse.jface.viewers.EditingSupport;
+import org.eclipse.papyrus.properties.runtime.controller.IBoundedValuesController;
+import org.eclipse.papyrus.properties.runtime.controller.PropertyEditorController;
+
+
+/**
+ * Property editor for references that have multiplicity [n..*]
+ */
+public class MultipleReferencePropertyEditor extends AbstractTablePropertyEditor {
+
+ /** id of this editor */
+ public static final String ID = "org.eclipse.papyrus.properties.runtime.multipleReferencePropertyEditor";
+
+ // /**
+ // * {@inheritDoc}
+ // */
+ // @Override
+ // public Composite createContent(Composite parent) {
+ // composite = getWidgetFactory().createComposite(parent, SWT.NONE);
+ // int columnNu = getColumnNumber();
+ // GridLayout layout = new GridLayout(columnNu, false);
+ // layout.marginHeight = 0;
+ // layout.marginWidth = 0;
+ // composite.setLayout(layout);
+ // GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
+ // composite.setLayoutData(data);
+ //
+ // // creates label. No TOP/DOWN/etc. position, always on top
+ // createLabel(composite);
+ //
+ // if(!getIsReadOnly()) {
+ // // create Button area
+ // addButton = getWidgetFactory().createButton(composite, "", SWT.NONE);
+ // addButton.setImage(Activator.getImageFromDescriptor(Activator.imageDescriptorFromPlugin(Activator.ID, "icons/Add_12x12.gif")));
+ // data = new GridData(SWT.FILL, SWT.CENTER, false, false);
+ // addButton.setLayoutData(data);
+ // addButton.addMouseListener(new MouseListener() {
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // @SuppressWarnings("unchecked")
+ // public void mouseUp(MouseEvent e) {
+ // PER
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // public void mouseDown(MouseEvent e) {
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // public void mouseDoubleClick(MouseEvent e) {
+ // }
+ // });
+ //
+ // removeButton = getWidgetFactory().createButton(composite, "", SWT.NONE);
+ // removeButton.setImage(Activator.getImageFromDescriptor(Activator.imageDescriptorFromPlugin(Activator.ID, "icons/Delete_12x12.gif")));
+ // data = new GridData(SWT.FILL, SWT.CENTER, false, false);
+ // removeButton.setLayoutData(data);
+ // removeButton.addMouseListener(new MouseListener() {
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // public void mouseUp(MouseEvent e) {
+ // if(!(getController() instanceof IWizardPropertyEditorController)) {
+ // return;
+ // }
+ // // use selection to remove element
+ // // retrieve selected element(s)
+ // IStructuredSelection selection = (IStructuredSelection)referencesViewer.getSelection();
+ // if(selection == null || selection.isEmpty()) {
+ // // nothing selected.
+ // return;
+ // }
+ //
+ // // copy current value
+ // List<EObject> values = new ArrayList<EObject>(currentValue);
+ // // remove selected elements from values
+ // values.removeAll(selection.toList());
+ //
+ // currentValue = values;
+ // getController().updateModel();
+ //
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // public void mouseDown(MouseEvent e) {
+ //
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // public void mouseDoubleClick(MouseEvent e) {
+ //
+ // }
+ // });
+ //
+ // if(getController().canMoveValues(new ArrayList<Integer>(), 0)) { // only checks if elements can be moved, not real move, so a 0-delta is fine
+ // Button upButton = getWidgetFactory().createButton(composite, "", SWT.NONE);
+ // upButton.setImage(Activator.getImageFromDescriptor(Activator.imageDescriptorFromPlugin(Activator.ID, "icons/Up_12x12.gif")));
+ // data = new GridData(SWT.FILL, SWT.CENTER, false, false);
+ // upButton.setLayoutData(data);
+ // upButton.addMouseListener(new MouseListener() {
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // public void mouseUp(MouseEvent e) {
+ // int[] selectionIndices = referencesViewer.getTable().getSelectionIndices();
+ // final List<Integer> selectionList = new ArrayList<Integer>();
+ // final List<Integer> newSelectionList = new ArrayList<Integer>();
+ // for(int i : selectionIndices) {
+ // selectionList.add(i);
+ // newSelectionList.add(i - 1);
+ // }
+ // IUndoableOperation moveOperation = getController().getMoveCurrentValuesOperation(selectionList, -1);
+ // if(moveOperation != null && moveOperation.canExecute()) {
+ // try {
+ // CheckedOperationHistory.getInstance().execute(moveOperation, new NullProgressMonitor(), null);
+ // // try to restore selection in the view
+ // int[] newSelection = new int[newSelectionList.size()];
+ // for(int i = 0; i < newSelectionList.size(); i++) {
+ // newSelection[i] = newSelectionList.get(i);
+ // }
+ // referencesViewer.getTable().select(newSelection);
+ // } catch (ExecutionException e1) {
+ // Activator.log.error(e1);
+ // }
+ // }
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // public void mouseDown(MouseEvent e) {
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // public void mouseDoubleClick(MouseEvent e) {
+ // }
+ // });
+ //
+ // Button downButton = getWidgetFactory().createButton(composite, "", SWT.NONE);
+ // downButton.setImage(Activator.getImageFromDescriptor(Activator.imageDescriptorFromPlugin(Activator.ID, "icons/Down_12x12.gif")));
+ // data = new GridData(SWT.FILL, SWT.CENTER, false, false);
+ // downButton.setLayoutData(data);
+ // downButton.addMouseListener(new MouseListener() {
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // public void mouseUp(MouseEvent e) {
+ // // use selection to remove element
+ // // retrieve selected element(s)
+ // int[] selectionIndices = referencesViewer.getTable().getSelectionIndices();
+ // final List<Integer> selectionList = new ArrayList<Integer>();
+ // final List<Integer> newSelectionList = new ArrayList<Integer>();
+ // for(int i : selectionIndices) {
+ // selectionList.add(i);
+ // newSelectionList.add(i + 1);
+ // }
+ // IUndoableOperation moveOperation = getController().getMoveCurrentValuesOperation(selectionList, +1);
+ // if(moveOperation != null && moveOperation.canExecute()) {
+ // try {
+ // CheckedOperationHistory.getInstance().execute(moveOperation, new NullProgressMonitor(), null);
+ // // try to restore selection in the view
+ // int[] newSelection = new int[newSelectionList.size()];
+ // for(int i = 0; i < newSelectionList.size(); i++) {
+ // newSelection[i] = newSelectionList.get(i);
+ // }
+ // referencesViewer.getTable().select(newSelection);
+ // } catch (ExecutionException e1) {
+ // Activator.log.error(e1);
+ // }
+ // }
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // public void mouseDown(MouseEvent e) {
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // public void mouseDoubleClick(MouseEvent e) {
+ // }
+ // });
+ // }
+ // }
+ //
+ // // creates table for the display of references
+ // referenceArea = new Table(composite, SWT.BORDER | SWT.MULTI);
+ // data = new GridData(SWT.FILL, SWT.FILL, true, true, columnNu, 1);
+ // data.heightHint = 80;
+ // referenceArea.setLayoutData(data);
+ // referencesViewer = new TableViewer(referenceArea);
+ // referencesViewer.setContentProvider(new IStructuredContentProvider() {
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+ //
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // public void dispose() {
+ //
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // public Object[] getElements(Object inputElement) {
+ // if(inputElement instanceof List<?>) {
+ // return ((List<?>)inputElement).toArray();
+ // }
+ // return new Object[0];
+ // }
+ // });
+ // referencesViewer.setLabelProvider(((IBoundedValuesController)getController()).getEditorLabelProvider());
+ //
+ // referencesViewer.getControl().setToolTipText(getTooltipText());
+ //
+ // return composite;
+ // }
+
+ // /**
+ // * {@inheritDoc}
+ // */
+ // @Override
+ // protected Control createLabel(Composite parent) {
+ // GridData data = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
+ // return createLabel(parent, data);
+ // }
+ //
+ // /**
+ // * Returns the number of column for the composite
+ // *
+ // * @return the number of column for the composite
+ // */
+ // protected int getColumnNumber() {
+ // if(getIsReadOnly()) {
+ // return 1;
+ // }
+ // if(getController().canMoveValues(new ArrayList<Integer>(), 0)) {
+ // return 5;
+ // }
+ // return 3;
+ // }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setController(PropertyEditorController controller) {
+ assert (controller instanceof IBoundedValuesController) : "Controller should be a IboundedValuesController";
+ super.setController(controller);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected EditingSupport createEditingSupport() {
+ return null;
+ }
+
+ // /**
+ // * {@inheritDoc}
+ // */
+ // @Override
+ // public void handleContentChanged() {
+ // // this should tells the controller that the input has to be applied to the model
+ // getController().updateModel();
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // @Override
+ // public IStatus init(IPropertyEditorDescriptor descriptor) {
+ // setDescriptor(descriptor);
+ // setTooltipText(descriptor.getTooltipText());
+ // return Status.OK_STATUS;
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // @Override
+ // public List<EObject> getValue() {
+ // if(isValid(referenceArea)) {
+ // return currentValue;
+ // } else {
+ // Activator.log.error("trying to read the value of the reference area whereas the combo is disposed", null);
+ // }
+ // return Collections.emptyList();
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // @SuppressWarnings("unchecked")
+ // @Override
+ // public void setValue(Object valueToEdit) {
+ // if(!isValid(referenceArea)) {
+ // return;
+ // }
+ // if(valueToEdit instanceof EList<?>) {
+ // currentValue = (EList<EObject>)valueToEdit;
+ // } else {
+ // Activator.log.error("Waiting for a list of EObject", null);
+ // }
+ // referencesViewer.setInput((valueToEdit != null) ? valueToEdit : Collections.emptyList());
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // @Override
+ // public void dispose() {
+ // if(isValid(composite)) {
+ // composite.dispose();
+ // composite = null;
+ // setController(null);
+ // }
+ // }
+ //
+ // /**
+ // * {@inheritDoc}
+ // */
+ // @Override
+ // public boolean isDisposed() {
+ // if(composite == null) {
+ // return true;
+ // }
+ // return composite.isDisposed();
+ // }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultipleReferencePropertyEditorValidator.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultipleReferencePropertyEditorValidator.java
new file mode 100644
index 00000000000..5d8bf5b7fc2
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultipleReferencePropertyEditorValidator.java
@@ -0,0 +1,38 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+/**
+ * validator for Simple References Property Editors
+ */
+public class MultipleReferencePropertyEditorValidator implements IPropertyEditorTypeValidator {
+
+ /**
+ * Constructor.
+ */
+ public MultipleReferencePropertyEditorValidator() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isValidForValue(Object valueToEdit) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setPropertyEditor(AbstractPropertyEditor editor) {
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultipleStructuralFeaturesPropertyEditor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultipleStructuralFeaturesPropertyEditor.java
new file mode 100644
index 00000000000..fce45148016
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultipleStructuralFeaturesPropertyEditor.java
@@ -0,0 +1,34 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+import org.eclipse.jface.viewers.EditingSupport;
+
+
+
+/**
+ * Property editor for structural features that have multiplicity [n..*]
+ */
+public class MultipleStructuralFeaturesPropertyEditor extends AbstractTablePropertyEditor {
+
+ /** id of this editor */
+ public static final String ID = "org.eclipse.papyrus.properties.runtime.multipleStructuralFeaturesPropertyEditor";
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected EditingSupport createEditingSupport() {
+ return null;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultipleStructuralFeaturesPropertyEditorValidator.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultipleStructuralFeaturesPropertyEditorValidator.java
new file mode 100644
index 00000000000..faff74af53f
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/MultipleStructuralFeaturesPropertyEditorValidator.java
@@ -0,0 +1,38 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+/**
+ * Validator for Multiple structural features Property Editors
+ */
+public class MultipleStructuralFeaturesPropertyEditorValidator implements IPropertyEditorTypeValidator {
+
+ /**
+ * Constructor.
+ */
+ public MultipleStructuralFeaturesPropertyEditorValidator() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isValidForValue(Object valueToEdit) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setPropertyEditor(AbstractPropertyEditor editor) {
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/NullPropertyEditor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/NullPropertyEditor.java
new file mode 100644
index 00000000000..8a44e4a7c6d
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/NullPropertyEditor.java
@@ -0,0 +1,100 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.PropertyEditorDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * Property editor that displays only a single Composite, no information
+ */
+public class NullPropertyEditor extends AbstractPropertyEditor {
+
+ /** main composite created by this property editor */
+ private Composite composite;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Composite createContent(Composite parent) {
+ composite = getWidgetFactory().createComposite(parent, SWT.NONE);
+ composite.setLayout(new GridLayout());
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
+ composite.setLayoutData(data);
+ return composite;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleContentChanged() {
+ // Nothing to do
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IStatus init(IPropertyEditorDescriptor descriptor) {
+ this.setDescriptor((PropertyEditorDescriptor)descriptor);
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getValue() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setValue(Object valueToEdit) {
+ // Nothing to do
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void dispose() {
+ if(isValid(composite)) {
+ composite.dispose();
+ composite = null;
+ setController(null);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isDisposed() {
+ if(composite == null) {
+ return true;
+ }
+ return composite.isDisposed();
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/NullPropertyEditorTypeValidator.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/NullPropertyEditorTypeValidator.java
new file mode 100644
index 00000000000..2b0de412ec0
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/NullPropertyEditorTypeValidator.java
@@ -0,0 +1,34 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+
+/**
+ * Validator which is always valid
+ */
+public class NullPropertyEditorTypeValidator implements IPropertyEditorTypeValidator {
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isValidForValue(Object valueToEdit) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setPropertyEditor(AbstractPropertyEditor editor) {
+ // nothing here
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/PropertyEditorConfiguration.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/PropertyEditorConfiguration.java
new file mode 100644
index 00000000000..132d9d7777a
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/PropertyEditorConfiguration.java
@@ -0,0 +1,240 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptorFactory;
+
+/**
+ * Class that contains the information about a specific editor
+ */
+public class PropertyEditorConfiguration {
+
+ /** description of the editor */
+ protected String description;
+
+ /** Image descriptor of the editor */
+ protected ImageDescriptor descriptor;
+
+ /** boolean that indicates if the editor accepts multi-valued properties */
+ protected boolean allowMultiValue;
+
+ /** validator for accepted edited types */
+ protected IPropertyEditorTypeValidator validator;
+
+ /** identifier of this extension point */
+ protected String id;
+
+ /** configuration element that manages this editor */
+ protected IConfigurationElement element;
+
+ /** factory used to create property editor descriptors */
+ protected IPropertyEditorDescriptorFactory factory;
+
+ /**
+ * Sets the element that configures the editor
+ *
+ * @param element
+ * the element to set
+ */
+ protected void setElement(IConfigurationElement element) {
+ this.element = element;
+ }
+
+ /**
+ * Returns the element that configures the editor
+ *
+ * @return the element that configures the editor
+ */
+ protected IConfigurationElement getElement() {
+ return element;
+ }
+
+ /**
+ * Returns the description of the editor
+ *
+ * @return the description of the editor
+ */
+ public String getDescription() {
+ return description;
+ }
+
+
+
+ /**
+ * Sets the description of this editor
+ *
+ * @param description
+ * the description to set
+ */
+ public void setDescription(String description) {
+ this.description = description;
+ }
+
+
+
+ /**
+ * Returns the image descriptor of the preview of the editor
+ *
+ * @return the image descriptor of the preview of the editor
+ */
+ public ImageDescriptor getDescriptor() {
+ return descriptor;
+ }
+
+
+
+ /**
+ * Sets the image descriptor of the editor preview
+ *
+ * @param descriptor
+ * the descriptor to set
+ */
+ public void setDescriptor(ImageDescriptor descriptor) {
+ this.descriptor = descriptor;
+ }
+
+
+
+ /**
+ * Returns <code>true</code> if the editor can support multi-valued property edition
+ *
+ * @return <code>true</code> if the editor can support multi-valued property edition
+ */
+ public boolean isAllowMultiValue() {
+ return allowMultiValue;
+ }
+
+
+
+ /**
+ * Tells if the editor accepts multi valued properties or not
+ *
+ * @param allowMultiValue
+ * the allowMultiValue to set
+ */
+ public void setAllowMultiValue(boolean allowMultiValue) {
+ this.allowMultiValue = allowMultiValue;
+ }
+
+ /**
+ * Returns the validator for types supported by this editor
+ *
+ * @return the validator for types supported by this editor
+ */
+ public IPropertyEditorTypeValidator getValidator() {
+ return validator;
+ }
+
+ /**
+ * Sets the validator for types supported by this editor
+ *
+ * @param validator
+ * the validator for types supported by this editor
+ */
+ public void setValidator(IPropertyEditorTypeValidator validator) {
+ this.validator = validator;
+ }
+
+ /**
+ * parses the configuration element and returns an editor configuration
+ *
+ * @param element
+ * the configuration element to parse
+ * @return the created editor configuration
+ * @throws CoreException
+ * the validator was not successfully initialized
+ */
+
+ public static PropertyEditorConfiguration parse(IConfigurationElement element) throws CoreException {
+ PropertyEditorConfiguration configuration = new PropertyEditorConfiguration();
+
+ // init the id
+ configuration.setId(element.getAttribute("id"));
+
+ // description
+ configuration.setDescription(element.getAttribute("description"));
+
+ // multi value
+ configuration.setAllowMultiValue(Boolean.getBoolean(element.getAttribute("allowMultiValue")));
+
+ // type validator
+ configuration.setValidator((IPropertyEditorTypeValidator)element.createExecutableExtension("typeValidator"));
+
+ // sets the configuration that configures this editor
+ configuration.setElement(element);
+
+ // sets the descriptor factory
+ configuration.setDescriptorFactory((IPropertyEditorDescriptorFactory)element.createExecutableExtension("factory"));
+
+
+ // check everything is valid
+ assert configuration.getId() != null : "impossible to get the identifier for the provider " + element.getName();
+ assert configuration.getValidator() != null : "impossible to get the validor for the provider " + element.getName();
+
+ return configuration;
+ }
+
+ /**
+ * Sets the descriptor factory for this configuration
+ *
+ * @param factory
+ * the descriptor factory to set
+ */
+ protected void setDescriptorFactory(IPropertyEditorDescriptorFactory factory) {
+ this.factory = factory;
+ }
+
+
+ /**
+ * Returns the descriptor factory for this property editor configuration
+ *
+ * @return the descriptor factory for this property editor configuration
+ */
+ public IPropertyEditorDescriptorFactory getDescriptorFactory() {
+ return factory;
+ }
+
+ /**
+ * Sets the identifier for this configuration
+ *
+ * @param id
+ * the id to set
+ */
+ public void setId(String id) {
+ this.id = id;
+ }
+
+
+
+ /**
+ * Returns the id of this configuration
+ *
+ * @return the id of this configuration
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Instanciates the editor. It is not configured at this time, it should not be used as is.
+ *
+ * @return the editor instanciated
+ * @throws CoreException
+ * exception thrown when the executable extension could not be created
+ */
+ public AbstractPropertyEditor instanciateEditor() throws CoreException {
+ return (AbstractPropertyEditor)getElement().createExecutableExtension("class");
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/PropertyEditorProvider.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/PropertyEditorProvider.java
new file mode 100644
index 00000000000..90a9d2f8047
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/PropertyEditorProvider.java
@@ -0,0 +1,126 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.gmf.runtime.common.core.service.AbstractProvider;
+import org.eclipse.gmf.runtime.common.core.service.IOperation;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.PropertyEditorController;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.w3c.dom.Node;
+
+/**
+ * Provider for property editors
+ */
+public class PropertyEditorProvider extends AbstractProvider {
+
+ /** map that stores the mapping id -> editor class */
+ private Map<String, PropertyEditorConfiguration> editors = new HashMap<String, PropertyEditorConfiguration>();
+
+ /**
+ * Creates the property editor managed by this provider
+ *
+ * @param editorIdentifier
+ * the identifier of the editor to create
+ * @param controller
+ * the controller that manages the created property editor
+ *
+ * @return the property editor managed by this provider
+ */
+ public AbstractPropertyEditor createPropertyEditor(String editorIdentifier, PropertyEditorController controller) {
+ // retrieve property class managed by this provider
+ try {
+ PropertyEditorConfiguration configuration = editors.get(editorIdentifier);
+ if(configuration == null) {
+ Activator.log.error("impossible to find the configuration for editor " + editorIdentifier, null);
+ return null;
+ }
+ Object editor = configuration.instanciateEditor();
+ if(editor instanceof AbstractPropertyEditor) {
+ ((AbstractPropertyEditor)editor).setController(controller);
+ return (AbstractPropertyEditor)editor;
+ }
+ } catch (CoreException e) {
+ e.printStackTrace();
+ Activator.log.error(e);
+ }
+ return null;
+ }
+
+ /**
+ * Configures the provider given the extension point that declares it.
+ *
+ * @param providerConfiguration
+ * the configuration element that declares the provider
+ */
+ public void configure(IConfigurationElement providerConfiguration) {
+ try {
+ // for each property editors defined in the provider, retrieves important information
+ for(IConfigurationElement element : providerConfiguration.getChildren()) {
+ // check this child is really configuring editors (not a Priority child...)
+ if("PropertyEditor".equals(element.getName())) {
+ // parse this editor configuration
+ PropertyEditorConfiguration configuration = PropertyEditorConfiguration.parse(element);
+ editors.put(configuration.getId(), configuration);
+ }
+ }
+ } catch (CoreException e) {
+ Activator.log.error(e);
+ }
+ }
+
+ /**
+ * Creates the descriptor for the editor with the given id
+ *
+ * @param editorID
+ * the identifier of the editor
+ * @param editorNode
+ * the configuration node
+ * @return the descriptor for the editor with the given id
+ */
+ public IPropertyEditorDescriptor createPropertyEditorDescriptor(String editorID, Node editorNode) {
+ PropertyEditorConfiguration configuration = editors.get(editorID);
+ if(configuration != null) {
+ return configuration.getDescriptorFactory().createEditorDescriptor(editorNode);
+ }
+ return null;
+ }
+
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean provides(IOperation operation) {
+ if(operation instanceof CreatePropertyEditorOperation) {
+ CreatePropertyEditorOperation createPropertyEditorOperation = (CreatePropertyEditorOperation)operation;
+
+ // test if the configuration corresponds to the feature or the id of the operation
+ // first test the id (specific editor)
+ // then test the feature
+
+ String operationIdentifier = createPropertyEditorOperation.getEditorIdentifier();
+ return editors.containsKey(operationIdentifier);
+ }
+
+ if(operation instanceof CreatePropertyEditorDescriptorOperation) {
+ CreatePropertyEditorDescriptorOperation editorDescriptorOperation = (CreatePropertyEditorDescriptorOperation)operation;
+ return editors.containsKey(editorDescriptorOperation.getEditorId());
+ }
+ return false;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/PropertyEditorService.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/PropertyEditorService.java
new file mode 100644
index 00000000000..ffef2d3eff1
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/PropertyEditorService.java
@@ -0,0 +1,161 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+import java.util.List;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.gmf.runtime.common.core.service.ExecutionStrategy;
+import org.eclipse.gmf.runtime.common.core.service.IOperation;
+import org.eclipse.gmf.runtime.common.core.service.IProvider;
+import org.eclipse.gmf.runtime.common.core.service.Service;
+import org.eclipse.gmf.runtime.common.ui.services.util.ActivityFilterProviderDescriptor;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.PropertyEditorController;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+import org.w3c.dom.Node;
+
+
+/**
+ * Service to provide property editors.
+ */
+public class PropertyEditorService extends Service {
+
+ /** instance of this service */
+ protected static PropertyEditorService instance;
+
+ /**
+ * Creates a new PropertyEditorService. This constructor is not visible, using singleton pattern.
+ */
+ protected PropertyEditorService() {
+ super();
+ }
+
+ /**
+ * Returns the singleton instance of this service.
+ *
+ * @return the singleton instance of this service
+ */
+ /**
+ * Returns the singleton instance of this service
+ *
+ * @return the singleton instance of this service
+ */
+ public synchronized static PropertyEditorService getInstance() {
+ if(instance == null) {
+ instance = new PropertyEditorService();
+ instance.configureProviders(Activator.ID, "propertyEditorProvider"); //$NON-NLS-1$
+ }
+ return instance;
+ }
+
+ /**
+ * Creates the property editor
+ *
+ * @param controller
+ * the controller that manages this editors
+ * @param id
+ * the identifier of the editor to create
+ * @param widgetFactory
+ * widget factory used to create the content of the editor
+ * @return the created property editor
+ */
+ public AbstractPropertyEditor createPropertyEditor(PropertyEditorController controller, String id, TabbedPropertySheetWidgetFactory widgetFactory) {
+ List<Object> results = (List<Object>)execute(ExecutionStrategy.FORWARD, new CreatePropertyEditorOperation(controller, id));
+ if(results == null || results.size()==0) {
+ Activator.log.error("impossible to create the editor using id " + id, null);
+ return null;
+ }
+ Object result = results.get(0);
+ if(result instanceof AbstractPropertyEditor) {
+ ((AbstractPropertyEditor)result).setWidgetFactory(widgetFactory);
+ return (AbstractPropertyEditor)result;
+ }
+ Activator.log.error("impossible to create the editor using id " + id, null);
+ return null;
+ }
+
+ /**
+ * Creates the property editor descriptor
+ *
+ * @param editorID
+ * id of the editor described by this element
+ * @param editorNode
+ * the configuration node of the editor
+ * @return the configuration descriptor for the property editor
+ */
+ public IPropertyEditorDescriptor createPropertyEditorDescriptor(String editorID, Node editorNode) {
+ List<IPropertyEditorDescriptor> results = (List<IPropertyEditorDescriptor>)execute(ExecutionStrategy.FORWARD, new CreatePropertyEditorDescriptorOperation(editorID, editorNode));
+ if(results == null || results.size()==0) {
+ throw new RuntimeException("Impossible to create this property editor: "+editorID);
+ } else {
+ IPropertyEditorDescriptor descriptor = results.get(0);
+ return results.get(0);
+ }
+ }
+
+ /**
+ * @see org.eclipse.gmf.runtime.common.core.service.Service#newProviderDescriptor(org.eclipse.core.runtime.IConfigurationElement)
+ */
+ @Override
+ protected Service.ProviderDescriptor newProviderDescriptor(IConfigurationElement element) {
+ return new ProviderDescriptor(element);
+ }
+
+ /**
+ * A descriptor for property editor providers defined by a configuration element.
+ */
+ protected static class ProviderDescriptor extends ActivityFilterProviderDescriptor {
+
+ /**
+ * Constructs a <code>ISemanticProvider</code> descriptor for
+ * the specified configuration element.
+ *
+ * @param element
+ * The configuration element describing the provider.
+ */
+ public ProviderDescriptor(IConfigurationElement element) {
+ super(element);
+ }
+
+ /**
+ * @see org.eclipse.gmf.runtime.common.core.service.IProvider#provides(org.eclipse.gmf.runtime.common.core.service.IOperation)
+ */
+ public boolean provides(IOperation operation) {
+ if(!super.provides(operation)) {
+ return false;
+ }
+ if(operation instanceof CreatePropertyEditorOperation || operation instanceof CreatePropertyEditorDescriptorOperation) {
+ // test if the configuration corresponds to the feature or the id of the operation
+ return getProvider().provides(operation);
+ }
+ return false;
+ }
+
+ /**
+ * @see org.eclipse.gmf.runtime.common.core.service.Service.ProviderDescriptor#getProvider()
+ */
+ public IProvider getProvider() {
+ if(provider == null) {
+ IProvider newProvider = super.getProvider();
+ if(provider instanceof PropertyEditorProvider) {
+ PropertyEditorProvider defaultProvider = (PropertyEditorProvider)newProvider;
+ defaultProvider.configure(getElement());
+ }
+ return newProvider;
+ }
+ return super.getProvider();
+ }
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/PropertyEditorTypeValidator.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/PropertyEditorTypeValidator.java
new file mode 100644
index 00000000000..aad1b1db7bd
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/PropertyEditorTypeValidator.java
@@ -0,0 +1,41 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+import java.util.List;
+
+/**
+ * Simple validator for property editor
+ */
+public class PropertyEditorTypeValidator implements IPropertyEditorTypeValidator {
+
+ /**
+ * Constructor.
+ */
+ public PropertyEditorTypeValidator() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isValidForValue(Object valueToEdit) {
+ return (valueToEdit instanceof String[] || valueToEdit instanceof List<?>);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setPropertyEditor(AbstractPropertyEditor editor) {
+
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/RadioBoxPropertyEditor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/RadioBoxPropertyEditor.java
new file mode 100644
index 00000000000..df663a61b6e
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/RadioBoxPropertyEditor.java
@@ -0,0 +1,236 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IBoundedValuesPropertyEditorDescriptor;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+
+
+/**
+ * Property editors for enumeration
+ */
+public class RadioBoxPropertyEditor extends AbstractPropertyEditor {
+
+ /** id of this editor */
+ public static final String ID = "org.eclipse.papyrus.properties.runtime.radioBoxPropertyEditor";
+
+ /** main composite created by this property editor */
+ protected Composite composite;
+
+ /** list of available elements */
+ protected List<String> values = new ArrayList<String>();
+
+ /** list of radio buttons */
+ protected List<Button> buttons = new ArrayList<Button>();
+
+ /** listener for the radio buttons */
+ protected SelectionListener listener = new RadioButtonListener();
+
+ /**
+ * Creates a new RadioBoxPropertyEditor
+ */
+ public RadioBoxPropertyEditor() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Composite createContent(Composite parent) {
+ composite = getWidgetFactory().createComposite(parent, SWT.NONE);
+ int columnNu = getColumnNumber();
+ GridLayout layout = new GridLayout(columnNu, false);
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ composite.setLayout(layout);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
+ composite.setLayoutData(data);
+
+ if((getDescriptor().getLabelPosition() & (SWT.LEFT | SWT.TOP)) != 0) {
+ createLabel(composite);
+ }
+
+ // create the set of radio-boxes. Does not know the size of the grid used for this editor
+ for(String value : values) {
+ Button button = getWidgetFactory().createButton(composite, (!value.equals("") ? value : "<Unset>"), SWT.RADIO);
+ if(!getIsReadOnly()) {
+ button.setEnabled(true);
+ button.addSelectionListener(listener);
+ } else {
+ button.setEnabled(false);
+ }
+ buttons.add(button);
+ button.setToolTipText(getTooltipText());
+ }
+
+ if((getDescriptor().getLabelPosition() & (SWT.RIGHT | SWT.BOTTOM)) != 0) {
+ createLabel(composite);
+ }
+
+ return composite;
+ }
+
+ /**
+ * Returns the number of column for the composite
+ *
+ * @return the number of column for the composite
+ */
+ protected int getColumnNumber() {
+ return values.size() + ((((getDescriptor().getLabelPosition() & SWT.RIGHT | SWT.LEFT)) != 0) ? 1 : 0);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void dispose() {
+ if(isValid(composite)) {
+ composite.dispose();
+ composite = null;
+ buttons.clear();
+ listener = null;
+ setController(null);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isDisposed() {
+ if(composite == null) {
+ return true;
+ }
+ return composite.isDisposed();
+ }
+
+ /**
+ * Returns the current String value or <code>null</code> if no elements were selected
+ */
+ @Override
+ public Object getValue() {
+ if(isValid(buttons)) {
+ for(Button button : buttons) {
+ // check if the button is selected
+ if(button.getSelection()) {
+ // returns the value in the list at the same index of the index of the button in the list of buttons
+ return values.get(buttons.indexOf(button));
+ }
+ }
+ } else {
+ Activator.log.error("trying to read the value of the combo whereas the combo is disposed", null);
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleContentChanged() {
+ // this should tells the controller that the input has to be applied to the model
+ getController().updateModel();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IStatus init(IPropertyEditorDescriptor descriptor) {
+ setDescriptor(descriptor);
+ setTooltipText(descriptor.getTooltipText());
+ if(descriptor instanceof IBoundedValuesPropertyEditorDescriptor) {
+ if(((IBoundedValuesPropertyEditorDescriptor)descriptor).getAvailableValues() != null) {
+ for(Object object : ((IBoundedValuesPropertyEditorDescriptor)descriptor).getAvailableValues()) {
+ this.values.add(object.toString());
+ }
+ }
+ return Status.OK_STATUS;
+ }
+ return new Status(IStatus.ERROR, Activator.ID, "Impossible to initialize the editor using descriptor :" + descriptor);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setValue(Object valueToEdit) {
+ if(!isValid(buttons)) {
+ return;
+ }
+ if(valueToEdit instanceof String) {
+ String newValue = (String)valueToEdit;
+ int index = values.indexOf(newValue);
+ if(index >= 0) {
+ // force all to not selected. Prefer to set all to false, then the right one to true.
+ // this should be faster than testing for each button
+ for(Button button : buttons) {
+ button.setSelection(false);
+ }
+
+ // select only the right one
+ buttons.get(index).setSelection(true);
+ } else {
+ Activator.log.error("Impossible to get the value " + valueToEdit + " in the list of available values", null);
+ }
+ }
+ }
+
+ /**
+ * Returns <code>true</code> if the list is not <code>null</code> neither empty and buttons inside list are not <code>null</code>.
+ *
+ * @param buttons
+ * the list of buttons to test
+ * @return <code>true</code> if the list is not <code>null</code> neither empty and buttons inside list are not <code>null</code>.
+ */
+ protected boolean isValid(List<Button> buttons) {
+ return buttons != null && !buttons.isEmpty() && !(buttons.get(0).isDisposed());
+ }
+
+ /**
+ * Selection Listener for a list of radio buttons
+ */
+ protected class RadioButtonListener implements SelectionListener {
+
+ /**
+ * {@inheritDoc}
+ */
+ public void widgetSelected(SelectionEvent e) {
+ for(Button button : buttons) {
+ button.setSelection(false);
+ }
+ ((Button)e.widget).setSelection(true);
+ handleContentChanged();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void widgetDefaultSelected(SelectionEvent e) {
+
+ }
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/SimpleReferencePropertyEditor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/SimpleReferencePropertyEditor.java
new file mode 100644
index 00000000000..8b7980b521c
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/SimpleReferencePropertyEditor.java
@@ -0,0 +1,334 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.jface.dialogs.Dialog;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.IBoundedValuesController;
+import org.eclipse.papyrus.properties.runtime.controller.PropertyEditorController;
+import org.eclipse.papyrus.properties.runtime.dialogs.PropertyDialog;
+import org.eclipse.papyrus.properties.runtime.dialogs.ReferenceExplorerDialog;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.DialogDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.PropertyViewService;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+
+
+/**
+ * Property editor for references that have multiplicity [0..1] or [1..1]
+ */
+public class SimpleReferencePropertyEditor extends AbstractPropertyEditor {
+
+ /** id of this editor */
+ public static final String ID = "org.eclipse.papyrus.properties.runtime.simpleReferencePropertyEditor";
+
+ /** main composite created by this property editor */
+ protected Composite composite;
+
+ /** button to add a reference or modify existing one */
+ protected Button addButton;
+
+ /** button to remove reference */
+ protected Button removeButton;
+
+ /** label area that displays the reference */
+ protected CLabel referenceArea;
+
+ /** current Value */
+ protected Object currentValue;
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Composite createContent(Composite parent) {
+ composite = getWidgetFactory().createComposite(parent, SWT.NONE);
+ int columnNu = getColumnNumber();
+ GridLayout layout = new GridLayout(columnNu, false);
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ composite.setLayout(layout);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
+ composite.setLayoutData(data);
+
+ if((getDescriptor().getLabelPosition() & (SWT.LEFT | SWT.TOP)) != 0) {
+ createLabel(composite);
+ }
+
+ // referenceArea = getWidgetFactory().createText(composite, "", SWT.READ_ONLY | SWT.BORDER);
+ referenceArea = getWidgetFactory().createCLabel(composite, "", SWT.BORDER);
+ data = new GridData(SWT.FILL, SWT.FILL, true, true);
+ referenceArea.setLayoutData(data);
+ referenceArea.addMouseListener(new MouseListener() {
+
+ public void mouseUp(MouseEvent e) {
+ // nothing to do here
+ }
+
+ public void mouseDown(MouseEvent e) {
+ // nothing to do here
+ }
+
+ public void mouseDoubleClick(MouseEvent e) {
+ openPropertyDialog();
+ }
+ });
+ referenceArea.setToolTipText(getTooltipText());
+
+ addButton = getWidgetFactory().createButton(composite, "", SWT.NONE);
+ addButton.setImage(Activator.getImageFromDescriptor(Activator.imageDescriptorFromPlugin(Activator.ID, "icons/Add_12x12.gif")));
+ data = new GridData(SWT.FILL, SWT.CENTER, false, false);
+ addButton.setLayoutData(data);
+ addButton.addMouseListener(new MouseListener() {
+
+ /**
+ * {@inheritDoc}
+ */
+ public void mouseUp(MouseEvent e) {
+ openReferenceDialog();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void mouseDown(MouseEvent e) {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void mouseDoubleClick(MouseEvent e) {
+ }
+ });
+ addButton.setEnabled(!getIsReadOnly());
+
+ removeButton = getWidgetFactory().createButton(composite, "", SWT.NONE);
+ removeButton.setImage(Activator.getImageFromDescriptor(Activator.imageDescriptorFromPlugin(Activator.ID, "icons/Delete_12x12.gif")));
+ data = new GridData(SWT.FILL, SWT.CENTER, false, false);
+ removeButton.setLayoutData(data);
+ removeButton.addMouseListener(new MouseListener() {
+
+ /**
+ * {@inheritDoc}
+ */
+ public void mouseUp(MouseEvent e) {
+ removeValueAction();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void mouseDown(MouseEvent e) {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void mouseDoubleClick(MouseEvent e) {
+
+ }
+ });
+ removeButton.setEnabled(!getIsReadOnly());
+
+ if((getDescriptor().getLabelPosition() & (SWT.RIGHT | SWT.BOTTOM)) != 0) {
+ createLabel(composite);
+ }
+
+ return composite;
+ }
+
+ /**
+ * Removes the current value.
+ */
+ protected void removeValueAction() {
+ // remove the reference of the element
+ currentValue = null;
+ getController().updateModel();
+ }
+
+ /**
+ * Opens the property dialog of current value and apply changes
+ */
+ protected void openPropertyDialog() {
+
+ /*
+ * deactivated part
+ * // open property dialog on the current object
+ * List<Object> objectsToEdit = Arrays.asList(getValue());
+ *
+ * // find editor descriptor...
+ * DialogDescriptor descriptor = PropertyViewService.getInstance().getDialogDescriptor(objectsToEdit);
+ *
+ * if(descriptor != null) {
+ * Shell parentShell = getShell();
+ * PropertyDialog dialog = new PropertyDialog(parentShell, descriptor, objectsToEdit, getWidgetFactory());
+ * dialog.open();
+ * }
+ *
+ * // end of deactivated
+ */
+ }
+
+ /**
+ * Opens the reference dialog and apply changes
+ */
+ protected void openReferenceDialog() {
+ // pops up a window to ask for a new reference
+ Shell currentShell = getShell();
+ ReferenceExplorerDialog dialog = new ReferenceExplorerDialog(currentShell, (IBoundedValuesController)getController(), false);
+ // should select the current value by default
+ if(Dialog.OK == dialog.open()) {
+ currentValue = dialog.getFirstResult();
+ getController().updateModel();
+ }
+ }
+
+ /**
+ * Returns a shell where dialogs can be displayed
+ *
+ * @return a shell where dialogs can be displayed
+ */
+ protected Shell getShell() {
+ Display display = Display.getCurrent();
+ if(display == null && PlatformUI.isWorkbenchRunning()) {
+ display = PlatformUI.getWorkbench().getDisplay();
+ }
+ display = (display != null) ? display : Display.getDefault();
+ return display.getActiveShell();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ protected Control createLabel(Composite parent) {
+ GridData data = new GridData(SWT.LEFT, SWT.CENTER, false, false, (getColumnNumber() == 3) ? 3 : 1, 1);
+ String text = getDescriptor().getLabel();
+ int size = computeLabelSize(parent, text);
+ data.minimumWidth = Math.max(LABEL_MAX_WIDTH, size);
+ data.widthHint = data.minimumWidth;
+ return createLabel(parent, data);
+ }
+
+ /**
+ * Returns the number of column for the composite
+ *
+ * @return the number of column for the composite
+ */
+ protected int getColumnNumber() {
+ if((getDescriptor().getLabelPosition() & (SWT.TOP | SWT.BOTTOM)) != 0) {
+ return 3;
+ }
+ return 4;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleContentChanged() {
+ // this should tells the controller that the input has to be applied to the model
+ getController().updateModel();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IStatus init(IPropertyEditorDescriptor descriptor) {
+ setDescriptor(descriptor);
+ setTooltipText(descriptor.getTooltipText());
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getValue() {
+ if(isValid(referenceArea)) {
+ return currentValue;
+ } else {
+ Activator.log.error("trying to read the value of the reference area whereas the combo is disposed", null);
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setValue(Object valueToEdit) {
+ if(!isValid(referenceArea)) {
+ return;
+ }
+ currentValue = valueToEdit;
+
+ // check if the model handler is able to give an improved text provider (for example, binding messages)
+ if(valueToEdit != null) {
+ referenceArea.setText(((IBoundedValuesController)getController()).getEditorLabelProvider().getText(valueToEdit));
+ referenceArea.setImage(((IBoundedValuesController)getController()).getEditorLabelProvider().getImage(valueToEdit));
+ } else {
+ referenceArea.setText("<Undefined>");
+ referenceArea.setImage(null);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setController(PropertyEditorController controller) {
+ assert (controller instanceof IBoundedValuesController) : "Controller should be a IboundedValuesController";
+ super.setController(controller);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void dispose() {
+ if(isValid(composite)) {
+ composite.dispose();
+ composite = null;
+ setController(null);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isDisposed() {
+ if(composite == null) {
+ return false;
+ }
+ return composite.isDisposed();
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/SimpleReferencePropertyEditorValidator.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/SimpleReferencePropertyEditorValidator.java
new file mode 100644
index 00000000000..8ebd6688118
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/SimpleReferencePropertyEditorValidator.java
@@ -0,0 +1,38 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+/**
+ * validator for Simple References Property Editors
+ */
+public class SimpleReferencePropertyEditorValidator implements IPropertyEditorTypeValidator {
+
+ /**
+ * Constructor.
+ */
+ public SimpleReferencePropertyEditorValidator() {
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isValidForValue(Object valueToEdit) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setPropertyEditor(AbstractPropertyEditor editor) {
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/TextPropertyEditor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/TextPropertyEditor.java
new file mode 100644
index 00000000000..e568afa9bc3
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/TextPropertyEditor.java
@@ -0,0 +1,188 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.IPropertyEditorDescriptor;
+import org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor.PropertyEditorDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Text;
+
+
+/**
+ * Property editors for properties represented by string (ex. Name for a named element)
+ */
+public class TextPropertyEditor extends AbstractPropertyEditor {
+
+ /** id of this editor */
+ public static final String ID = "org.eclipse.papyrus.properties.runtime.textPropertyEditor";
+
+ /** text area */
+ private Text text;
+
+ /** main composite created by this property editor */
+ private Composite composite;
+
+ /**
+ * Creates a new {@link TextPropertyEditor}
+ */
+ public TextPropertyEditor() {
+ super();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void handleContentChanged() {
+ // this should tells the controller that the input has to be applied to the model
+ getController().updateModel();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IStatus init(IPropertyEditorDescriptor descriptor) {
+ this.setDescriptor((PropertyEditorDescriptor)descriptor);
+ setTooltipText(descriptor.getTooltipText());
+ return Status.OK_STATUS;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Composite createContent(Composite parent) {
+ composite = getWidgetFactory().createComposite(parent, SWT.NONE);
+ int columnNu = getColumnNumber();
+ GridLayout layout = new GridLayout(columnNu, false);
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ composite.setLayout(layout);
+ GridData data = new GridData(SWT.FILL, SWT.FILL, true, false);
+ composite.setLayoutData(data);
+
+ if((getDescriptor().getLabelPosition() & (SWT.LEFT | SWT.TOP)) != 0) {
+ createLabel(composite);
+ }
+ text = getWidgetFactory().createText(composite, "", SWT.BORDER);
+ data = new GridData(SWT.FILL, SWT.FILL, true, false);
+ text.setLayoutData(data);
+ text.addFocusListener(new FocusListener() {
+
+ public void focusLost(FocusEvent e) {
+ handleContentChanged();
+ }
+
+ public void focusGained(FocusEvent e) {
+ }
+ });
+ text.addKeyListener(new KeyListener() {
+
+ public void keyReleased(KeyEvent e) {
+ // valid changement on Carriage return typed
+ if(SWT.CR == e.keyCode && e.stateMask == SWT.NONE) {
+ handleContentChanged();
+ }
+ }
+
+ public void keyPressed(KeyEvent e) {
+
+ }
+ });
+ text.setEnabled(!getIsReadOnly());
+ if((getDescriptor().getLabelPosition() & (SWT.RIGHT | SWT.BOTTOM)) != 0) {
+ createLabel(composite);
+ }
+
+ text.setToolTipText(getTooltipText());
+
+ return composite;
+ }
+
+ /**
+ * Returns the number of column for the composite
+ *
+ * @return the number of column for the composite
+ */
+ protected int getColumnNumber() {
+ if((getDescriptor().getLabelPosition() & (SWT.TOP | SWT.BOTTOM)) != 0) {
+ return 1;
+ }
+ return 2;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Object getValue() {
+ if(isValid(text)) {
+ return text.getText();
+ } else {
+ Activator.log.error("trying to read the value of the text area whereas the control is disposed", null);
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public void setValue(Object valueToEdit) {
+ if(isValid(text)) {
+ String textToEdit = (valueToEdit != null) ? valueToEdit.toString() : "";
+ text.setText(textToEdit);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void dispose() {
+ if(isValid(composite)) {
+ composite.dispose();
+ composite = null;
+ setController(null);
+ }
+ }
+
+ /**
+ * Returns the configuration for this editor
+ *
+ * @return the configuration for this editor
+ */
+ public PropertyEditorDescriptor getDescriptor() {
+ return (PropertyEditorDescriptor)super.getDescriptor();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public boolean isDisposed() {
+ if(composite == null) {
+ return true;
+ }
+ return composite.isDisposed();
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/TextPropertyEditorValidator.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/TextPropertyEditorValidator.java
new file mode 100644
index 00000000000..77188e1eb4d
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/TextPropertyEditorValidator.java
@@ -0,0 +1,39 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor;
+
+/**
+ * Validator for the simple reference property editors
+ */
+public class TextPropertyEditorValidator implements IPropertyEditorTypeValidator {
+
+ /**
+ * Creates a new SimpleReferencePropertyEditorValidator.
+ */
+ public TextPropertyEditorValidator() {
+
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isValidForValue(Object valueToEdit) {
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setPropertyEditor(AbstractPropertyEditor editor) {
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/ComboPropertyEditorDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/ComboPropertyEditorDescriptor.java
new file mode 100644
index 00000000000..b7fb541b527
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/ComboPropertyEditorDescriptor.java
@@ -0,0 +1,72 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor;
+
+import java.util.List;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+
+
+/**
+ * Descriptor specific to the combo property editor
+ */
+public class ComboPropertyEditorDescriptor extends PropertyEditorDescriptor implements IBoundedValuesPropertyEditorDescriptor {
+
+ /** list of available values */
+ private List<?> values;
+
+ /**
+ * Creates a new ComboPropertyEditorDescriptor.
+ *
+ * @param editorId
+ * the unique identifier for this editor factory
+ * @param label
+ * the label for this property editor
+ * @param tooltipText
+ * the tooltip text for this property editor
+ */
+ public ComboPropertyEditorDescriptor(String editorId, String label, String tooltipText) {
+ super(editorId, label, tooltipText);
+ }
+
+ /**
+ * Creates a new ComboPropertyEditorDescriptor.
+ *
+ * @param editorId
+ * the unique identifier for this editor factory
+ * @param label
+ * the label for this property editor
+ * @param labelPosition
+ * the label position for this property editor
+ * @param tooltipText
+ * the tooltip text for this property editor
+ * @param imageDescriptor
+ * the icon for this property editor
+ */
+ public ComboPropertyEditorDescriptor(String editorId, String label, int labelPosition, String tooltipText, ImageDescriptor imageDescriptor) {
+ super(editorId, label, labelPosition, tooltipText, imageDescriptor);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setAvailableValues(List<?> values) {
+ this.values = values;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<?> getAvailableValues() {
+ return values;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/ComboPropertyEditorDescriptorFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/ComboPropertyEditorDescriptorFactory.java
new file mode 100644
index 00000000000..266b663ef44
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/ComboPropertyEditorDescriptorFactory.java
@@ -0,0 +1,75 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.swt.SWT;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * factory for property editor descriptors
+ */
+public class ComboPropertyEditorDescriptorFactory implements IPropertyEditorDescriptorFactory {
+
+ /**
+ * {@inheritDoc}
+ */
+ public PropertyEditorDescriptor createEditorDescriptor(Node editorNode) {
+ String identifier = "";
+ String label = "";
+ String tooltipText = "";
+ int labelPosition = SWT.LEFT;
+ ImageDescriptor imageDescriptor = null;
+
+ // retrieve id, label, label position and tooltipText
+ NamedNodeMap attributes = editorNode.getAttributes();
+ if(attributes != null) {
+ for(int i = 0; i < attributes.getLength(); i++) {
+ Node attribute = attributes.item(i);
+ String nodeName = attribute.getNodeName();
+ if("label".equals(nodeName)) {
+ label = attribute.getNodeValue();
+ } else if("labelPosition".equals(nodeName)) {
+ labelPosition = Integer.parseInt(attribute.getNodeValue());
+ } else if("id".equals(nodeName)) {
+ identifier = attribute.getNodeValue();
+ } else if("tooltip".equals(nodeName)) {
+ tooltipText = attribute.getNodeValue();
+ }
+ }
+ }
+
+ // retrieve icon
+ NodeList children = editorNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if("icon".equals(child.getNodeName())) {
+ NamedNodeMap iconAttributes = child.getAttributes();
+ if(iconAttributes != null) {
+ // retrieve plugin id and path
+ for(int j = 0; j < iconAttributes.getLength(); j++) {
+ Node pluginIDNode = iconAttributes.getNamedItem("pluginID");
+ Node pathNode = iconAttributes.getNamedItem("path");
+ if(pluginIDNode != null && pathNode != null) {
+ imageDescriptor = Activator.imageDescriptorFromPlugin(pluginIDNode.getNodeValue(), pathNode.getNodeValue());
+ }
+ }
+ }
+ }
+ }
+
+ return new ComboPropertyEditorDescriptor(identifier, label, labelPosition, tooltipText, imageDescriptor);
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/IBoundedValuesPropertyEditorDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/IBoundedValuesPropertyEditorDescriptor.java
new file mode 100644
index 00000000000..7ab38f82b80
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/IBoundedValuesPropertyEditorDescriptor.java
@@ -0,0 +1,36 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor;
+
+import java.util.List;
+
+
+/**
+ * Interface for property editors that accept a bounded list of values (enumeration, boolean, etc)
+ */
+public interface IBoundedValuesPropertyEditorDescriptor {
+
+ /**
+ * Sets the list of available values
+ *
+ * @param values
+ * the list of available values
+ */
+ public void setAvailableValues(List<?> values);
+
+ /**
+ * Returns the list of available values
+ *
+ * @return the list of available values
+ */
+ public List<?> getAvailableValues();
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/IPropertyEditorDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/IPropertyEditorDescriptor.java
new file mode 100644
index 00000000000..95f8bd4e89a
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/IPropertyEditorDescriptor.java
@@ -0,0 +1,59 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.IConfigurableDescriptor;
+
+
+
+/**
+ * Interface implemented by all editor descriptors. These descriptors are used to configure the property editors. (label, label position, icon, etc.)
+ */
+public interface IPropertyEditorDescriptor extends IConfigurableDescriptor {
+
+ /**
+ * Returns the tooltip text that should be associated to the property editor
+ *
+ * @return the tooltip text that should be associated to the property editor
+ */
+ public String getTooltipText();
+
+ /**
+ * Returns the icon that should be associated to the label of the property editor
+ *
+ * @return the icon that should be associated to the label of the property editor
+ */
+ public ImageDescriptor getLabelImageDescriptor();
+
+ /**
+ * Returns the label position of the property editor
+ *
+ * @return the label position of the property editor
+ */
+ public int getLabelPosition();
+
+ /**
+ * Returns the label of the property editor
+ *
+ * @return the label of the property editor
+ */
+ public String getLabel();
+
+ /**
+ * Returns the unique identifier of the editor
+ *
+ * @return the unique identifier of the editor
+ */
+ public String getEditorId();
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/IPropertyEditorDescriptorFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/IPropertyEditorDescriptorFactory.java
new file mode 100644
index 00000000000..892dcd3cd52
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/IPropertyEditorDescriptorFactory.java
@@ -0,0 +1,29 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor;
+
+import org.w3c.dom.Node;
+
+/**
+ * factory for property editor descriptors
+ */
+public interface IPropertyEditorDescriptorFactory {
+
+ /**
+ * Creates the descriptor for an editor, given its configuration node
+ *
+ * @param editorNode
+ * the configuration node
+ * @return the descriptor for the editor
+ */
+ public IPropertyEditorDescriptor createEditorDescriptor(Node editorNode);
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultiplePrimitiveTypedPropertyEditorDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultiplePrimitiveTypedPropertyEditorDescriptor.java
new file mode 100644
index 00000000000..a38f7d86ad8
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultiplePrimitiveTypedPropertyEditorDescriptor.java
@@ -0,0 +1,53 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+
+/**
+ * Descriptor specific to the multi-valued primitive typed property editor
+ */
+public class MultiplePrimitiveTypedPropertyEditorDescriptor extends PropertyEditorDescriptor {
+
+ /**
+ * Creates a new MultiplePrimitiveTypedPropertyEditorDescriptor.
+ *
+ * @param editorId
+ * the unique identifier for this editor factory
+ * @param label
+ * the label for this property editor
+ * @param tooltipText
+ * the tooltip text for this property editor
+ */
+ public MultiplePrimitiveTypedPropertyEditorDescriptor(String editorId, String label, String tooltipText) {
+ super(editorId, label, tooltipText);
+ }
+
+ /**
+ * Creates a new MultiplePrimitiveTypedPropertyEditorDescriptor.
+ *
+ * @param editorId
+ * the unique identifier for this editor factory
+ * @param label
+ * the label for this property editor
+ * @param labelPosition
+ * the label position for this property editor
+ * @param tooltipText
+ * the tooltip text for this property editor
+ * @param imageDescriptor
+ * the icon for this property editor
+ */
+ public MultiplePrimitiveTypedPropertyEditorDescriptor(String editorId, String label, int labelPosition, String tooltipText, ImageDescriptor imageDescriptor) {
+ super(editorId, label, labelPosition, tooltipText, imageDescriptor);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultiplePrimitiveTypedPropertyEditorDescriptorFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultiplePrimitiveTypedPropertyEditorDescriptorFactory.java
new file mode 100644
index 00000000000..24359f46add
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultiplePrimitiveTypedPropertyEditorDescriptorFactory.java
@@ -0,0 +1,74 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.swt.SWT;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Factory for multiple primitive typed property editor descriptors
+ */
+public class MultiplePrimitiveTypedPropertyEditorDescriptorFactory implements IPropertyEditorDescriptorFactory {
+
+ /**
+ * {@inheritDoc}
+ */
+ public IPropertyEditorDescriptor createEditorDescriptor(Node editorNode) {
+ String identifier = "";
+ String label = "";
+ String tooltipText = "";
+ int labelPosition = SWT.LEFT;
+ ImageDescriptor imageDescriptor = null;
+
+ // retrieve id, label, label position and tooltipText
+ NamedNodeMap attributes = editorNode.getAttributes();
+ if(attributes != null) {
+ for(int i = 0; i < attributes.getLength(); i++) {
+ Node attribute = attributes.item(i);
+ String nodeName = attribute.getNodeName();
+ if("label".equals(nodeName)) {
+ label = attribute.getNodeValue();
+ } else if("labelPosition".equals(nodeName)) {
+ labelPosition = Integer.parseInt(attribute.getNodeValue());
+ } else if("id".equals(nodeName)) {
+ identifier = attribute.getNodeValue();
+ } else if("tooltip".equals(nodeName)) {
+ tooltipText = attribute.getNodeValue();
+ }
+ }
+ }
+
+ // retrieve icon
+ NodeList children = editorNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if("icon".equals(child.getNodeName())) {
+ NamedNodeMap iconAttributes = child.getAttributes();
+ if(iconAttributes != null) {
+ // retrieve plugin id and path
+ Node pluginIDNode = iconAttributes.getNamedItem("pluginID");
+ Node pathNode = iconAttributes.getNamedItem("path");
+ if(pluginIDNode != null && pathNode != null) {
+ imageDescriptor = Activator.imageDescriptorFromPlugin(pluginIDNode.getNodeValue(), pathNode.getNodeValue());
+ }
+ }
+ }
+ }
+
+ return new MultiplePrimitiveTypedPropertyEditorDescriptor(identifier, label, labelPosition, tooltipText, imageDescriptor);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultipleReferencePropertyEditorDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultipleReferencePropertyEditorDescriptor.java
new file mode 100644
index 00000000000..0da31390217
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultipleReferencePropertyEditorDescriptor.java
@@ -0,0 +1,53 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+
+/**
+ * Descriptor specific to the Simple reference property editor
+ */
+public class MultipleReferencePropertyEditorDescriptor extends PropertyEditorDescriptor {
+
+ /**
+ * Creates a new MultipleReferencePropertyEditorDescriptor.
+ *
+ * @param editorId
+ * the unique identifier for this editor factory
+ * @param label
+ * the label for this property editor
+ * @param tooltipText
+ * the tooltip text for this property editor
+ */
+ public MultipleReferencePropertyEditorDescriptor(String editorId, String label, String tooltipText) {
+ super(editorId, label, tooltipText);
+ }
+
+ /**
+ * Creates a new MultipleReferencePropertyEditorDescriptor.
+ *
+ * @param editorId
+ * the unique identifier for this editor factory
+ * @param label
+ * the label for this property editor
+ * @param labelPosition
+ * the label position for this property editor
+ * @param tooltipText
+ * the tooltip text for this property editor
+ * @param imageDescriptor
+ * the icon for this property editor
+ */
+ public MultipleReferencePropertyEditorDescriptor(String editorId, String label, int labelPosition, String tooltipText, ImageDescriptor imageDescriptor) {
+ super(editorId, label, labelPosition, tooltipText, imageDescriptor);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultipleReferencePropertyEditorDescriptorFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultipleReferencePropertyEditorDescriptorFactory.java
new file mode 100644
index 00000000000..df2c2e22d01
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultipleReferencePropertyEditorDescriptorFactory.java
@@ -0,0 +1,74 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.swt.SWT;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * Factory for multiple reference property editor descriptors
+ */
+public class MultipleReferencePropertyEditorDescriptorFactory implements IPropertyEditorDescriptorFactory {
+
+ /**
+ * {@inheritDoc}
+ */
+ public IPropertyEditorDescriptor createEditorDescriptor(Node editorNode) {
+ String identifier = "";
+ String label = "";
+ String tooltipText = "";
+ int labelPosition = SWT.LEFT;
+ ImageDescriptor imageDescriptor = null;
+
+ // retrieve id, label, label position and tooltipText
+ NamedNodeMap attributes = editorNode.getAttributes();
+ if(attributes != null) {
+ for(int i = 0; i < attributes.getLength(); i++) {
+ Node attribute = attributes.item(i);
+ String nodeName = attribute.getNodeName();
+ if("label".equals(nodeName)) {
+ label = attribute.getNodeValue();
+ } else if("labelPosition".equals(nodeName)) {
+ labelPosition = Integer.parseInt(attribute.getNodeValue());
+ } else if("id".equals(nodeName)) {
+ identifier = attribute.getNodeValue();
+ } else if("tooltip".equals(nodeName)) {
+ tooltipText = attribute.getNodeValue();
+ }
+ }
+ }
+
+ // retrieve icon
+ NodeList children = editorNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if("icon".equals(child.getNodeName())) {
+ NamedNodeMap iconAttributes = child.getAttributes();
+ if(iconAttributes != null) {
+ // retrieve plugin id and path
+ Node pluginIDNode = iconAttributes.getNamedItem("pluginID");
+ Node pathNode = iconAttributes.getNamedItem("path");
+ if(pluginIDNode != null && pathNode != null) {
+ imageDescriptor = Activator.imageDescriptorFromPlugin(pluginIDNode.getNodeValue(), pathNode.getNodeValue());
+ }
+ }
+ }
+ }
+
+ return new MultipleReferencePropertyEditorDescriptor(identifier, label, labelPosition, tooltipText, imageDescriptor);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultipleStructuralFeaturesPropertyEditorDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultipleStructuralFeaturesPropertyEditorDescriptor.java
new file mode 100644
index 00000000000..905264dba06
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultipleStructuralFeaturesPropertyEditorDescriptor.java
@@ -0,0 +1,54 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+
+
+/**
+ * Descriptor specific to the Simple reference property editor
+ */
+public class MultipleStructuralFeaturesPropertyEditorDescriptor extends PropertyEditorDescriptor {
+
+ /**
+ * Creates a new MultipleReferencePropertyEditorDescriptor.
+ *
+ * @param editorId
+ * the unique identifier for this editor factory
+ * @param label
+ * the label for this property editor
+ * @param tooltipText
+ * the tooltip text for this property editor
+ */
+ public MultipleStructuralFeaturesPropertyEditorDescriptor(String editorId, String label, String tooltipText) {
+ super(editorId, label, tooltipText);
+ }
+
+ /**
+ * Creates a new MultipleReferencePropertyEditorDescriptor.
+ *
+ * @param editorId
+ * the unique identifier for this editor factory
+ * @param label
+ * the label for this property editor
+ * @param labelPosition
+ * the label position for this property editor
+ * @param tooltipText
+ * the tooltip text for this property editor
+ * @param imageDescriptor
+ * the icon for this property editor
+ */
+ public MultipleStructuralFeaturesPropertyEditorDescriptor(String editorId, String label, int labelPosition, String tooltipText, ImageDescriptor imageDescriptor) {
+ super(editorId, label, labelPosition, tooltipText, imageDescriptor);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultipleStructuralFeaturesPropertyEditorDescriptorFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultipleStructuralFeaturesPropertyEditorDescriptorFactory.java
new file mode 100644
index 00000000000..d636bdec776
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/MultipleStructuralFeaturesPropertyEditorDescriptorFactory.java
@@ -0,0 +1,75 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.swt.SWT;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+
+/**
+ * Factory for multiple reference property editor descriptors
+ */
+public class MultipleStructuralFeaturesPropertyEditorDescriptorFactory implements IPropertyEditorDescriptorFactory {
+
+ /**
+ * {@inheritDoc}
+ */
+ public IPropertyEditorDescriptor createEditorDescriptor(Node editorNode) {
+ String identifier = "";
+ String label = "";
+ String tooltipText = "";
+ int labelPosition = SWT.LEFT;
+ ImageDescriptor imageDescriptor = null;
+
+ // retrieve id, label, label position and tooltipText
+ NamedNodeMap attributes = editorNode.getAttributes();
+ if(attributes != null) {
+ for(int i = 0; i < attributes.getLength(); i++) {
+ Node attribute = attributes.item(i);
+ String nodeName = attribute.getNodeName();
+ if("label".equals(nodeName)) {
+ label = attribute.getNodeValue();
+ } else if("labelPosition".equals(nodeName)) {
+ labelPosition = Integer.parseInt(attribute.getNodeValue());
+ } else if("id".equals(nodeName)) {
+ identifier = attribute.getNodeValue();
+ } else if("tooltip".equals(nodeName)) {
+ tooltipText = attribute.getNodeValue();
+ }
+ }
+ }
+
+ // retrieve icon
+ NodeList children = editorNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if("icon".equals(child.getNodeName())) {
+ NamedNodeMap iconAttributes = child.getAttributes();
+ if(iconAttributes != null) {
+ // retrieve plugin id and path
+ Node pluginIDNode = iconAttributes.getNamedItem("pluginID");
+ Node pathNode = iconAttributes.getNamedItem("path");
+ if(pluginIDNode != null && pathNode != null) {
+ imageDescriptor = Activator.imageDescriptorFromPlugin(pluginIDNode.getNodeValue(), pathNode.getNodeValue());
+ }
+ }
+ }
+ }
+
+ return new MultipleStructuralFeaturesPropertyEditorDescriptor(identifier, label, labelPosition, tooltipText, imageDescriptor);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/PropertyEditorDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/PropertyEditorDescriptor.java
new file mode 100644
index 00000000000..b4787290d81
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/PropertyEditorDescriptor.java
@@ -0,0 +1,133 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.papyrus.properties.runtime.state.IState;
+import org.eclipse.papyrus.properties.runtime.view.IConfigurableDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+
+
+/**
+ * Basic configuration for property editors
+ */
+public class PropertyEditorDescriptor implements IPropertyEditorDescriptor, IConfigurableDescriptor {
+
+ /** the label position of the property editor */
+ private int labelPosition = 0;
+
+ /** the icon descriptor for the label */
+ private ImageDescriptor imageDescriptor = null;
+
+ /** the label of the property editor */
+ private String label = null;
+
+ /** id of the editor configured by this descriptor */
+ private String editorID;
+
+ /** id of the editor configured by this descriptor */
+ private String tooltipText;
+
+ /**
+ * Creates a new PropertyEditorDescriptor.
+ *
+ * @param editorID
+ * the id of the editor described
+ * @param label
+ * the label of the described editor
+ * @param tooltipText
+ * the tooltip text for this property editor
+ */
+ public PropertyEditorDescriptor(String editorID, String label, String tooltipText) {
+ this(editorID, label, SWT.LEFT, tooltipText, null);
+ }
+
+ /**
+ * Creates a new PropertyEditorDescriptor.
+ *
+ * @param editorID
+ * the id of the described editor
+ * @param label
+ * the label of the described editor
+ * @param labelPosition
+ * the label position relative to the edition area (see {@link SWT#LEFT})
+ * @param tooltipText
+ * the tooltip text for this property editor
+ * @param imageDescriptor
+ * the image descriptor for the icon of the property editor
+ */
+ public PropertyEditorDescriptor(String editorID, String label, int labelPosition, String tooltipText, ImageDescriptor imageDescriptor) {
+ this.label = label;
+ this.labelPosition = labelPosition;
+ this.imageDescriptor = imageDescriptor;
+ this.editorID = editorID;
+ this.tooltipText = tooltipText;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ImageDescriptor getLabelImageDescriptor() {
+ return imageDescriptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public int getLabelPosition() {
+ return labelPosition;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEditorId() {
+ return editorID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "editor";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IState createState(boolean readOnly) {
+ return new PropertyEditorDescriptorState(this, readOnly);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getTooltipText() {
+ return tooltipText;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/PropertyEditorDescriptorFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/PropertyEditorDescriptorFactory.java
new file mode 100644
index 00000000000..a1542729093
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/PropertyEditorDescriptorFactory.java
@@ -0,0 +1,74 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.swt.SWT;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+
+/**
+ * factory for property editor descriptors
+ */
+public class PropertyEditorDescriptorFactory implements IPropertyEditorDescriptorFactory {
+
+ /**
+ * {@inheritDoc}
+ */
+ public PropertyEditorDescriptor createEditorDescriptor(Node editorNode) {
+ String identifier = "";
+ String label = "";
+ String tooltipText = "";
+ int labelPosition = SWT.LEFT;
+ ImageDescriptor imageDescriptor = null;
+
+ // retrieve id, label, label position and tooltipText
+ NamedNodeMap attributes = editorNode.getAttributes();
+ if(attributes != null) {
+ for(int i = 0; i < attributes.getLength(); i++) {
+ Node attribute = attributes.item(i);
+ String nodeName = attribute.getNodeName();
+ if("label".equals(nodeName)) {
+ label = attribute.getNodeValue();
+ } else if("labelPosition".equals(nodeName)) {
+ labelPosition = Integer.parseInt(attribute.getNodeValue());
+ } else if("id".equals(nodeName)) {
+ identifier = attribute.getNodeValue();
+ } else if("tooltip".equals(nodeName)) {
+ tooltipText = attribute.getNodeValue();
+ }
+ }
+ }
+
+ // retrieve icon
+ NodeList children = editorNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if("icon".equals(child.getNodeName())) {
+ NamedNodeMap iconAttributes = child.getAttributes();
+ if(iconAttributes != null) {
+ // retrieve plugin id and path
+ Node pluginIDNode = iconAttributes.getNamedItem("pluginID");
+ Node pathNode = iconAttributes.getNamedItem("path");
+ if(pluginIDNode != null && pathNode != null) {
+ imageDescriptor = Activator.imageDescriptorFromPlugin(pluginIDNode.getNodeValue(), pathNode.getNodeValue());
+ }
+ }
+ }
+ }
+
+ return new PropertyEditorDescriptor(identifier, label, labelPosition, tooltipText, imageDescriptor);
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/PropertyEditorDescriptorState.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/PropertyEditorDescriptorState.java
new file mode 100644
index 00000000000..90267b7ffed
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/PropertyEditorDescriptorState.java
@@ -0,0 +1,172 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.state.AbstractState;
+import org.eclipse.papyrus.properties.runtime.state.ITraversableModelElement;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+
+/**
+ * State for {@link PropertyEditorDescriptor}
+ */
+public class PropertyEditorDescriptorState extends AbstractState {
+
+ /** descriptor managed by this state */
+ private PropertyEditorDescriptor descriptor;
+
+ /** change support listener for this state */
+ private PropertyChangeSupport changeSupport;
+
+ /** id of the editor */
+ private String id;
+
+ /** label of the editor */
+ private String label;
+
+ /** label position of the editor */
+ private int labelPosition;
+
+ /**
+ * Creates a new PropertyEditorDescriptorState.
+ *
+ * @param descriptor
+ * the descriptor managed by this state
+ *
+ * @param readOnly
+ * the read only mode for this state
+ */
+ public PropertyEditorDescriptorState(PropertyEditorDescriptor descriptor, boolean readOnly) {
+ super(readOnly);
+ this.descriptor = descriptor;
+
+ // inits the fields
+ id = descriptor.getEditorId();
+ label = descriptor.getLabel();
+ labelPosition = descriptor.getLabelPosition();
+
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ /**
+ * Returns the id of the descriptor
+ *
+ * @return the id of the descriptor
+ */
+ public String getId() {
+ return id;
+ }
+
+ /**
+ * Sets the id of the descriptor
+ *
+ * @param id
+ * the id to set
+ */
+ public void setId(String id) {
+ changeSupport.firePropertyChange("id", this.id, this.id = id);
+ }
+
+ /**
+ * Returns the label of the descriptor
+ *
+ * @return the label of the descriptor
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * Sets the label of the descriptor
+ *
+ * @param label
+ * the label to set
+ */
+ public void setLabel(String label) {
+ changeSupport.firePropertyChange("label", this.label, this.label = label);
+ }
+
+ /**
+ * Returns the labelPosition of the descriptor
+ *
+ * @return the labelPosition of the descriptor
+ */
+ public int getLabelPosition() {
+ return labelPosition;
+ }
+
+ /**
+ * Sets the labelPosition of the descriptor
+ *
+ * @param labelPosition
+ * the labelPosition to set
+ */
+ public void setLabelPosition(int labelPosition) {
+ changeSupport.firePropertyChange("labelPosition", this.labelPosition, this.labelPosition = labelPosition);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public PropertyEditorDescriptor getDescriptor() {
+ return descriptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEditionDialogId() {
+ return "";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node generateNode(Document document) {
+ Element node = document.createElement("editor");
+ // <editor id="org.eclipse.papyrus.properties.runtime.textPropertyEditor" label="Body:" labelPosition="16384"/>
+ node.setAttribute("id", id);
+ node.setAttribute("label", label);
+ node.setAttribute("labelPosition", "" + labelPosition);
+ return node;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<? extends ITraversableModelElement> getChildren() {
+ return Collections.emptyList();
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/RadioBoxPropertyEditorDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/RadioBoxPropertyEditorDescriptor.java
new file mode 100644
index 00000000000..7ed0dc9faf2
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/RadioBoxPropertyEditorDescriptor.java
@@ -0,0 +1,73 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor;
+
+import java.util.List;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+
+/**
+ * Descriptor specific to the radio box property editor
+ */
+public class RadioBoxPropertyEditorDescriptor extends PropertyEditorDescriptor implements IBoundedValuesPropertyEditorDescriptor {
+
+ /** list of available values */
+ private List<?> values;
+
+ /**
+ * Creates a new RadioBoxPropertyEditor.RadioBoxPropertyEditorDescriptor.
+ *
+ * @param editorId
+ * the unique identifier of the editor described by this
+ * descriptor
+ * @param label
+ * the label for this property editor
+ * @param tooltipText
+ * the tooltip text for this property editor
+ */
+ public RadioBoxPropertyEditorDescriptor(String editorId, String label, String tooltipText) {
+ super(editorId, label, tooltipText);
+ }
+
+ /**
+ * Creates a new RadioBoxPropertyEditorDescriptor.
+ *
+ * @param editorId
+ * the unique identifier of the editor described by this
+ * descriptor
+ * @param label
+ * the label for this property editor
+ * @param labelPosition
+ * the label position for this property editor
+ * @param tooltipText
+ * the tooltip text for this property editor
+ * @param imageDescriptor
+ * the icon for this property editor
+ */
+ public RadioBoxPropertyEditorDescriptor(String editorId, String label, int labelPosition, String tooltipText, ImageDescriptor imageDescriptor) {
+ super(editorId, label, labelPosition, tooltipText, imageDescriptor);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void setAvailableValues(List<?> values) {
+ this.values = values;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<?> getAvailableValues() {
+ return values;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/RadioBoxPropertyEditorDescriptorFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/RadioBoxPropertyEditorDescriptorFactory.java
new file mode 100644
index 00000000000..9f98f491fc0
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/RadioBoxPropertyEditorDescriptorFactory.java
@@ -0,0 +1,75 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.swt.SWT;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * factory for property editor descriptors
+ */
+public class RadioBoxPropertyEditorDescriptorFactory implements IPropertyEditorDescriptorFactory {
+
+ /**
+ * {@inheritDoc}
+ */
+ public PropertyEditorDescriptor createEditorDescriptor(Node editorNode) {
+ String identifier = "";
+ String label = "";
+ String tooltipText = "";
+ int labelPosition = SWT.LEFT;
+ ImageDescriptor imageDescriptor = null;
+
+ // retrieve id, label, label position and tooltipText
+ NamedNodeMap attributes = editorNode.getAttributes();
+ if(attributes != null) {
+ for(int i = 0; i < attributes.getLength(); i++) {
+ Node attribute = attributes.item(i);
+ String nodeName = attribute.getNodeName();
+ if("label".equals(nodeName)) {
+ label = attribute.getNodeValue();
+ } else if("labelPosition".equals(nodeName)) {
+ labelPosition = Integer.parseInt(attribute.getNodeValue());
+ } else if("id".equals(nodeName)) {
+ identifier = attribute.getNodeValue();
+ } else if("tooltip".equals(nodeName)) {
+ tooltipText = attribute.getNodeValue();
+ }
+ }
+ }
+
+ // retrieve icon
+ NodeList children = editorNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if("icon".equals(child.getNodeName())) {
+ NamedNodeMap iconAttributes = child.getAttributes();
+ if(iconAttributes != null) {
+ // retrieve plugin id and path
+ for(int j = 0; j < iconAttributes.getLength(); j++) {
+ Node pluginIDNode = iconAttributes.getNamedItem("pluginID");
+ Node pathNode = iconAttributes.getNamedItem("path");
+ if(pluginIDNode != null && pathNode != null) {
+ imageDescriptor = Activator.imageDescriptorFromPlugin(pluginIDNode.getNodeValue(), pathNode.getNodeValue());
+ }
+ }
+ }
+ }
+ }
+
+ return new RadioBoxPropertyEditorDescriptor(identifier, label, labelPosition, tooltipText, imageDescriptor);
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/SimpleReferencePropertyEditorDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/SimpleReferencePropertyEditorDescriptor.java
new file mode 100644
index 00000000000..9b828c03609
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/SimpleReferencePropertyEditorDescriptor.java
@@ -0,0 +1,53 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+
+/**
+ * Descriptor specific to the Simple reference property editor
+ */
+public class SimpleReferencePropertyEditorDescriptor extends PropertyEditorDescriptor {
+
+ /**
+ * Creates a new ComboPropertyEditorDescriptor.
+ *
+ * @param editorId
+ * the unique identifier for this editor factory
+ * @param label
+ * the label for this property editor
+ * @param tooltipText
+ * the tooltip text for this property editor
+ */
+ public SimpleReferencePropertyEditorDescriptor(String editorId, String label, String tooltipText) {
+ super(editorId, label, tooltipText);
+ }
+
+ /**
+ * Creates a new ComboPropertyEditorDescriptor.
+ *
+ * @param editorId
+ * the unique identifier for this editor factory
+ * @param label
+ * the label for this property editor
+ * @param labelPosition
+ * the label position for this property editor
+ * @param tooltipText
+ * the tooltip text for this property editor
+ * @param imageDescriptor
+ * the icon for this property editor
+ */
+ public SimpleReferencePropertyEditorDescriptor(String editorId, String label, int labelPosition, String tooltipText, ImageDescriptor imageDescriptor) {
+ super(editorId, label, labelPosition, tooltipText, imageDescriptor);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/SimpleReferencePropertyEditorDescriptorFactory.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/SimpleReferencePropertyEditorDescriptorFactory.java
new file mode 100644
index 00000000000..6259be7e89d
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/propertyeditor/descriptor/SimpleReferencePropertyEditorDescriptorFactory.java
@@ -0,0 +1,74 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.propertyeditor.descriptor;
+
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.swt.SWT;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ *
+ */
+public class SimpleReferencePropertyEditorDescriptorFactory implements IPropertyEditorDescriptorFactory {
+
+ /**
+ * {@inheritDoc}
+ */
+ public IPropertyEditorDescriptor createEditorDescriptor(Node editorNode) {
+ String identifier = "";
+ String label = "";
+ String tooltipText = "";
+ int labelPosition = SWT.LEFT;
+ ImageDescriptor imageDescriptor = null;
+
+ // retrieve id, label, label position and tooltipText
+ NamedNodeMap attributes = editorNode.getAttributes();
+ if(attributes != null) {
+ for(int i = 0; i < attributes.getLength(); i++) {
+ Node attribute = attributes.item(i);
+ String nodeName = attribute.getNodeName();
+ if("label".equals(nodeName)) {
+ label = attribute.getNodeValue();
+ } else if("labelPosition".equals(nodeName)) {
+ labelPosition = Integer.parseInt(attribute.getNodeValue());
+ } else if("id".equals(nodeName)) {
+ identifier = attribute.getNodeValue();
+ } else if("tooltip".equals(nodeName)) {
+ tooltipText = attribute.getNodeValue();
+ }
+ }
+ }
+
+ // retrieve icon
+ NodeList children = editorNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if("icon".equals(child.getNodeName())) {
+ NamedNodeMap iconAttributes = child.getAttributes();
+ if(iconAttributes != null) {
+ // retrieve plugin id and path
+ Node pluginIDNode = iconAttributes.getNamedItem("pluginID");
+ Node pathNode = iconAttributes.getNamedItem("path");
+ if(pluginIDNode != null && pathNode != null) {
+ imageDescriptor = Activator.imageDescriptorFromPlugin(pluginIDNode.getNodeValue(), pathNode.getNodeValue());
+ }
+ }
+ }
+ }
+
+ return new SimpleReferencePropertyEditorDescriptor(identifier, label, labelPosition, tooltipText, imageDescriptor);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/state/AbstractState.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/state/AbstractState.java
new file mode 100644
index 00000000000..83280b1f2c4
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/state/AbstractState.java
@@ -0,0 +1,65 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.state;
+
+import org.eclipse.swt.graphics.Image;
+
+
+/**
+ * Abstract class for state used to configure the property view
+ */
+public abstract class AbstractState implements IState, ITraversableModelElement {
+
+ /** key for the event: add an element to the list of children */
+ public static final String PROPERTY_ADD_CHILD = "ADD_CHILD_EVENT";
+
+ /** key for the event: remove an element to the list of children */
+ public static final String PROPERTY_REMOVE_CHILD = "REMOVE_CHILD_EVENT";
+
+ /** Add group identifier for context menu */
+ public static final String ADD_GROUP = "ADD_GROUP";
+
+ /** read only mode for the state */
+ protected boolean readOnly = false;
+
+ /**
+ * Creates a new AbstractState.
+ *
+ * @param readOnly
+ * the read only mode for this state
+ */
+ public AbstractState(boolean readOnly) {
+ this.readOnly = readOnly;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean isReadOnly() {
+ return readOnly;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return getDescriptor().getText();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return getDescriptor().getImage();
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/state/IFragmentDescriptorState.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/state/IFragmentDescriptorState.java
new file mode 100644
index 00000000000..8518f490b5d
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/state/IFragmentDescriptorState.java
@@ -0,0 +1,37 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.state;
+
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.view.IFragmentDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.content.ContainerDescriptorState;
+
+
+/**
+ * state for {@link IFragmentDescriptor}
+ */
+public interface IFragmentDescriptorState extends IState, ITraversableModelElement {
+
+ /**
+ * {@inheritDoc}
+ */
+ public IFragmentDescriptor getDescriptor();
+
+ /**
+ * returns the list of container descriptor states for this fragment
+ *
+ * @return the list of container descriptor states for this fragment
+ */
+ public List<ContainerDescriptorState> getContainerDescriptorStates();
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/state/IState.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/state/IState.java
new file mode 100644
index 00000000000..a841c503d00
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/state/IState.java
@@ -0,0 +1,86 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.state;
+
+import java.beans.PropertyChangeListener;
+
+import org.eclipse.papyrus.properties.runtime.view.IConfigurableDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+
+/**
+ * Common interface to all states
+ */
+public interface IState {
+
+ /**
+ * returns the label displayed by this state
+ *
+ * @return the label displayed by this state
+ */
+ public String getText();
+
+ /**
+ * returns the image displayed by this state
+ *
+ * @return the image displayed by this state
+ */
+ public Image getImage();
+
+ /**
+ * Returns the descriptor managed by this state
+ *
+ * @return the descriptor managed by this state
+ */
+ public IConfigurableDescriptor getDescriptor();
+
+ /**
+ * Returns the identifier of the dialog used to edit this element
+ *
+ * @return the identifier of the dialog used to edit this element
+ */
+ public String getEditionDialogId();
+
+ /**
+ * Adds a property change listener to this class
+ *
+ * @param listener
+ * the listener to add
+ */
+ public void addPropertyChangeListener(PropertyChangeListener listener);
+
+ /**
+ * Removes a property change listener from this class
+ *
+ * @param listener
+ * the listener to remove
+ */
+ public void removePropertyChangeListener(PropertyChangeListener listener);
+
+ /**
+ * Serializes the state under the form of an xml node
+ *
+ * @param document
+ * the document used to create elements
+ * @return the generate node
+ */
+ public Node generateNode(Document document);
+
+ /**
+ * Indicates if the state is in read only mode
+ *
+ * @return <code>true</code> if the state should be unmodifiable
+ */
+ public boolean isReadOnly();
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/state/ITraversableModelElement.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/state/ITraversableModelElement.java
new file mode 100644
index 00000000000..d06cca6fff0
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/state/ITraversableModelElement.java
@@ -0,0 +1,45 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.state;
+
+import java.beans.PropertyChangeListener;
+import java.util.List;
+
+
+/**
+ * Interface for element which can be visited to add or remove property listeners
+ */
+public interface ITraversableModelElement {
+
+ /**
+ * Returns the list of children for this element
+ *
+ * @return the list of children for this element
+ */
+ public List<? extends ITraversableModelElement> getChildren();
+
+ /**
+ * Adds the given listener to the list of listeners listening for property change on the element
+ *
+ * @param listener
+ * the listener to add
+ */
+ public void addPropertyChangeListener(PropertyChangeListener listener);
+
+ /**
+ * Removes the given listener from the list of listeners listening for property change on the element
+ *
+ * @param listener
+ * the listener to remove
+ */
+ public void removePropertyChangeListener(PropertyChangeListener listener);
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/AbstractConstrainedDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/AbstractConstrainedDescriptor.java
new file mode 100644
index 00000000000..b3637226e3c
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/AbstractConstrainedDescriptor.java
@@ -0,0 +1,117 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view;
+
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.view.constraints.IConstraintDescriptor;
+import org.w3c.dom.Node;
+
+
+
+/**
+ * Abstract Descriptors that contains a list of constraints, has a unique identifier and holds a list of created containers
+ */
+public abstract class AbstractConstrainedDescriptor implements IConfigurableDescriptor {
+
+ /** id of the dialog */
+ protected final String id;
+
+ /** list of constraints that applies to the dialog (kind of manipulated element, etc) */
+ protected final List<IConstraintDescriptor> constraints;
+
+ /** unparsed content node */
+ protected Node contentNode;
+
+ /** boolean that indicates that the content node has not been parsed yet */
+ protected boolean unparsed = false;
+
+ /** indicates if the parsing of the content node failed. not used currently, here to handle errors in a better way */
+ protected boolean parseFailed = false;
+
+ /** parser of the content node */
+ protected final PropertyViewProviderParser parser;
+
+ /** size of the selection */
+ private int selectionSize;
+
+ /**
+ * Creates a new AbstractConstrainedDescriptor.
+ *
+ * @param id
+ * id of the descriptor
+ * @param constraints
+ * constraints applying to this descriptor
+ * @param selectionSize
+ * size of the selection for which this descriptor is valid
+ *
+ */
+ public AbstractConstrainedDescriptor(String id, List<IConstraintDescriptor> constraints, int selectionSize) {
+ this.id = id;
+ this.constraints = constraints;
+ this.parser = null;
+ this.selectionSize = selectionSize;
+ }
+
+ /**
+ * Creates a new AbstractConstrainedDescriptor.
+ *
+ * @param id
+ * id of the descriptor
+ * @param constraints
+ * constraints applying to this descriptor
+ * @param contentNode
+ * the configuration node for this descriptor
+ * @param selectionSize
+ * size of the selection for which this descriptor is valid
+ * @param parser
+ * the parser used to parse the configuration node
+ *
+ */
+ public AbstractConstrainedDescriptor(String id, List<IConstraintDescriptor> constraints, Node contentNode, int selectionSize, PropertyViewProviderParser parser) {
+ this.id = id;
+ this.constraints = constraints;
+ this.contentNode = contentNode;
+ this.parser = parser;
+ this.selectionSize = selectionSize;
+ unparsed = true;
+ }
+
+ /**
+ * Returns the list of containers descriptors
+ *
+ * @return the list of containers descriptors
+ */
+ public List<IConstraintDescriptor> getConstraintDescriptors() {
+ return constraints;
+ }
+
+ /**
+ * Returns the id of this descriptor
+ *
+ * @return the id of this descriptor
+ */
+ public String getId() {
+ return id;
+ }
+
+
+ /**
+ * Returns the size of the selection
+ *
+ * @return the size of the selection
+ */
+ public int getSelectionSize() {
+ return selectionSize;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/DialogDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/DialogDescriptor.java
new file mode 100644
index 00000000000..13b7a83cc4d
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/DialogDescriptor.java
@@ -0,0 +1,141 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IBindingLabelProviderDescriptor;
+import org.eclipse.papyrus.properties.runtime.state.IState;
+import org.eclipse.papyrus.properties.runtime.view.constraints.IConstraintDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.w3c.dom.Node;
+
+/**
+ * Descriptor for dialogs
+ */
+public class DialogDescriptor extends AbstractConstrainedDescriptor {
+
+ /** list of FragmentDescriptor created by this dialog */
+ protected List<IFragmentDescriptor> fragmentDescriptors;
+
+ /** title for the dialog */
+ protected Object title;
+
+ /** message for the dialog */
+ protected Object message;
+
+ /** list of identifier of replaced dialogs */
+ protected List<String> replacedDialogIds;
+
+ /**
+ * Creates a new DialogDescriptor.
+ *
+ * @param id
+ * identifier of this dialog descriptor
+ * @param constraints
+ * the list of constraints for this dialog
+ * @param contentNode
+ * the unparsed node describing the content of the dialog
+ * @param selectionSize
+ * size of the selection for which this dialog is valid
+ * @param replacedDialogIds
+ * the list of replaced ids for the dialog
+ * @param title
+ * the title of the dialog (either a simple String or a {@link IBindingLabelProviderDescriptor}
+ * @param message
+ * the message of the dialog (either a simple String or a {@link IBindingLabelProviderDescriptor}
+ * @param parser
+ * the parser used to parse the content node
+ */
+ public DialogDescriptor(String id, List<IConstraintDescriptor> constraints, Node contentNode, int selectionSize, List<String> replacedDialogIds, Object title, Object message, PropertyViewProviderParser parser) {
+ super(id, constraints, contentNode, selectionSize, parser);
+ this.replacedDialogIds = replacedDialogIds;
+ this.title = title;
+ this.message = message;
+ }
+
+ /**
+ * Returns the list of identifier of fragment descriptors
+ *
+ * @return the list of identifier of fragment descriptors
+ */
+ public List<IFragmentDescriptor> getFragmentDescriptors() {
+ if(unparsed) {
+ if(parser == null) {
+ fragmentDescriptors = Collections.emptyList();
+ Activator.log.error("No parser was given to the fragment descriptor " + id, null);
+ parseFailed = true;
+ } else {
+ try {
+ fragmentDescriptors = parser.parseDialogContentNode(contentNode);
+ parseFailed = false;
+ } catch (XMLParseException e) {
+ Activator.log.error(e);
+ parseFailed = true;
+ }
+ }
+ }
+ return fragmentDescriptors;
+ }
+
+ /**
+ *
+ * Returns the title object, either a {@link String} or a {@link IBindingLabelProviderDescriptor}
+ *
+ * @return the title object, either a string or a message binding descriptor
+ */
+ public Object getTitle() {
+ return title;
+ }
+
+ /**
+ *
+ * Returns the message object, either a {@link String} or a {@link IBindingLabelProviderDescriptor}
+ *
+ * @return the message object, either a string or a message binding descriptor
+ */
+ public Object getMessage() {
+ return message;
+ }
+
+ /**
+ * Returns the identifier of replaced dialogs
+ *
+ * @return the identifier of replaced dialogs
+ */
+ public List<String> getReplacedDialogIds() {
+ return replacedDialogIds;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "DialogDescriptor";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IState createState(boolean readOnly) {
+ return null;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/FragmentDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/FragmentDescriptor.java
new file mode 100644
index 00000000000..c14b6101d58
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/FragmentDescriptor.java
@@ -0,0 +1,110 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.view.constraints.IConstraintDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.content.ContainerDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.w3c.dom.Node;
+
+
+/**
+ * descriptor for fragments
+ */
+public class FragmentDescriptor extends AbstractConstrainedDescriptor implements IFragmentDescriptor {
+
+ /** list of containers created by this dialog */
+ protected List<ContainerDescriptor> descriptors;
+
+ /**
+ * Creates a new FragmentDescriptor.
+ *
+ * @param id
+ * the identifier of the fragment
+ * @param constraints
+ * the list of constraints to be verified when the fragment is to be displayed
+ * @param descriptors
+ * list of containers in this fragment
+ * @param selectionSize
+ * the size of the selection for which this fragment is valid
+ */
+ public FragmentDescriptor(String id, List<IConstraintDescriptor> constraints, List<ContainerDescriptor> descriptors, int selectionSize) {
+ super(id, constraints, selectionSize);
+ this.descriptors = descriptors;
+ }
+
+ /**
+ * Creates a new FragmentDescriptor.
+ *
+ * @param id
+ * the identifier of the fragment
+ * @param constraints
+ * the list of constraints to be verified when the fragment is to be displayed
+ * @param contentNode
+ * the node configuring this fragment descriptor
+ * @param selectionSize
+ * the size of the selection for which this fragment is valid
+ * @param parser
+ * the parser used to parse the configuration node
+ */
+ public FragmentDescriptor(String id, List<IConstraintDescriptor> constraints, Node contentNode, int selectionSize, PropertyViewProviderParser parser) {
+ super(id, constraints, contentNode, selectionSize, parser);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<ContainerDescriptor> getContainerDescriptors() {
+ if(unparsed && !parseFailed) {
+ if(parser == null) {
+ descriptors = Collections.emptyList();
+ Activator.log.error("No parser was given to the view descriptor " + id, null);
+ parseFailed = true;
+ } else {
+ try {
+ descriptors = parser.parseFragmentContentNode(contentNode);
+ parseFailed = false;
+ } catch (XMLParseException e) {
+ Activator.log.error(e);
+ parseFailed = true;
+ }
+ }
+ }
+ return descriptors;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "Fragment: " + getId();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return Activator.getImage("/icons/Fragment.gif");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public FragmentDescriptorState createState(boolean readOnly) {
+ return new FragmentDescriptorState(this, readOnly);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/FragmentDescriptorState.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/FragmentDescriptorState.java
new file mode 100644
index 00000000000..a9cc934ce41
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/FragmentDescriptorState.java
@@ -0,0 +1,300 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.state.AbstractState;
+import org.eclipse.papyrus.properties.runtime.state.IFragmentDescriptorState;
+import org.eclipse.papyrus.properties.runtime.view.constraints.ConstraintDescriptorState;
+import org.eclipse.papyrus.properties.runtime.view.constraints.IConstraintDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.content.ContainerDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.content.ContainerDescriptorState;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+/**
+ * state for Fragment descriptor
+ */
+public class FragmentDescriptorState extends AbstractState implements IFragmentDescriptorState {
+
+ /** descriptor managed by this state */
+ private FragmentDescriptor descriptor;
+
+ /** list of container descriptors state children of this state */
+ private final List<ContainerDescriptorState> containerDescriptorStates = new ArrayList<ContainerDescriptorState>();
+
+ /** list of constraints descriptors state children of this state */
+ private final List<ConstraintDescriptorState> constraintDescriptorStates = new ArrayList<ConstraintDescriptorState>();
+
+ /** selection size state */
+ private int selectionSize;
+
+ /** change support for this bean */
+ private PropertyChangeSupport changeSupport;
+
+ /** id of the fragment managed by this state */
+ private String id;
+
+ /**
+ * Creates a new FragmentDescriptorState.
+ *
+ * @param descriptor
+ * the fragment descriptor managed by this state
+ * @param readOnly
+ * <code>true</code> if the state should not be modifiable
+ */
+ public FragmentDescriptorState(FragmentDescriptor descriptor, boolean readOnly) {
+ super(readOnly);
+ this.descriptor = descriptor;
+
+ id = descriptor.getId();
+
+ // retrieve and build the states for the container children
+ List<ContainerDescriptor> containerDescriptors = descriptor.getContainerDescriptors();
+ for(ContainerDescriptor containerDescriptor : containerDescriptors) {
+ containerDescriptorStates.add(containerDescriptor.createState(readOnly));
+ }
+
+ for(IConstraintDescriptor constraintDescriptor : descriptor.getConstraintDescriptors()) {
+ getConstraintDescriptorStates().add(constraintDescriptor.createState(readOnly));
+ }
+
+ selectionSize = descriptor.getSelectionSize();
+
+ // register change support
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ public FragmentDescriptor getDescriptor() {
+ return descriptor;
+ }
+
+
+ /**
+ * Returns the state for the selection size
+ *
+ * @return the state for the selection size
+ */
+ public int getSelectionSize() {
+ return selectionSize;
+ }
+
+ /**
+ * Sets the state for the selection size
+ *
+ * @param selectionSize
+ * the selectionSize to set
+ */
+ public void setSelectionSizeState(int selectionSize) {
+ int oldSize = this.selectionSize;
+ this.selectionSize = selectionSize;
+
+ changeSupport.firePropertyChange("selectionSize", oldSize, this.selectionSize);
+ }
+
+ /**
+ * Returns the containerDescriptor States for this fragment
+ *
+ * @return the containerDescriptor States for this fragment
+ */
+ public List<ContainerDescriptorState> getContainerDescriptorStates() {
+ return containerDescriptorStates;
+ }
+
+ /**
+ * Returns the constraintDescriptor States for this fragment
+ *
+ * @return the constraintDescriptor States for this fragment
+ */
+ public List<ConstraintDescriptorState> getConstraintDescriptorStates() {
+ return constraintDescriptorStates;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEditionDialogId() {
+ return "FragmentDescriptorStateDialog";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "Fragment: " + getId() + " (size: " + getSelectionSize() + ")";
+ }
+
+ /**
+ * Adds a property change listener to this class
+ *
+ * @param listener
+ * the listener to add
+ */
+ public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * Removes a property change listener from this class
+ *
+ * @param listener
+ * the listener to remove
+ */
+ public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * Adds the {@link ContainerDescriptorState} to the list of descriptor states belonging to this fragment
+ *
+ * @param containerDescriptorState
+ * the state to add
+ */
+ public void addContainerDescriptorState(ContainerDescriptorState containerDescriptorState) {
+ containerDescriptorStates.add(containerDescriptorState);
+
+ changeSupport.firePropertyChange(PROPERTY_ADD_CHILD, null, containerDescriptorStates);
+ }
+
+ /**
+ * Removes the {@link ContainerDescriptorState} from the list of descriptor states belonging to this fragment
+ *
+ * @param containerDescriptorState
+ * the state to remove
+ */
+ public void removeContainerDescriptorState(ContainerDescriptorState containerDescriptorState) {
+ containerDescriptorStates.remove(containerDescriptorState);
+
+ changeSupport.firePropertyChange(PROPERTY_REMOVE_CHILD, null, containerDescriptorStates);
+ }
+
+ /**
+ * Adds the {@link ContainerDescriptorState} to the list of descriptor states belonging to this fragment
+ *
+ * @param constraintDescriptorState
+ * the state to add
+ */
+ public void addConstraintDescriptorState(ConstraintDescriptorState constraintDescriptorState) {
+ constraintDescriptorStates.add(constraintDescriptorState);
+
+ changeSupport.firePropertyChange(PROPERTY_ADD_CHILD, null, constraintDescriptorState);
+ }
+
+ /**
+ * Removes the {@link ContainerDescriptorState} from the list of descriptor states belonging to this fragment
+ *
+ * @param constraintDescriptorState
+ * the state to remove
+ */
+ public void removeContainerDescriptorState(ConstraintDescriptorState constraintDescriptorState) {
+ constraintDescriptorStates.remove(constraintDescriptorState);
+
+ changeSupport.firePropertyChange(PROPERTY_REMOVE_CHILD, null, constraintDescriptorState);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<ContainerDescriptorState> getChildren() {
+ return getContainerDescriptorStates();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node generateNode(Document document) {
+ Element node = document.createElement("fragment");
+
+ generateAttributes(node, document);
+
+ // generate for children(containers and constraints)
+ generateConstraints(node, document);
+ generateContainers(node, document);
+
+ return node;
+ }
+
+ /**
+ * Generates attributes for this fragment
+ *
+ * @param node
+ * the node to complete
+ * @param document
+ * the document used to create nodes
+ */
+ protected void generateAttributes(Element node, Document document) {
+ node.setAttribute("id", getId());
+
+ }
+
+ /**
+ * Generates the constraints for the fragment descriptor
+ *
+ * @param node
+ * the parent node for generated nodes
+ * @param document
+ * the document used to create elements
+ */
+ protected void generateConstraints(Element node, Document document) {
+ Element contentElement = document.createElement("context");
+ // add the enables for attribute
+ contentElement.setAttribute("enablesFor", "" + getSelectionSize());
+
+ // generate for each constraint
+ for(ConstraintDescriptorState state : getConstraintDescriptorStates()) {
+ contentElement.appendChild(state.generateNode(document));
+ }
+ node.appendChild(contentElement);
+
+ }
+
+ /**
+ * Generate the children nodes for all containers
+ *
+ * @param node
+ * the parent node for generated nodes
+ * @param document
+ * the document used to create elements
+ */
+ protected void generateContainers(Element node, Document document) {
+ Element contentElement = document.createElement("content");
+ for(ContainerDescriptorState state : getContainerDescriptorStates()) {
+ contentElement.appendChild(state.generateNode(document));
+ }
+ node.appendChild(contentElement);
+ }
+
+ /**
+ * Sets the id
+ *
+ * @param id
+ * the id to set
+ */
+ public void setId(String id) {
+ changeSupport.firePropertyChange("id", this.id, this.id = id);
+ }
+
+ /**
+ * Returns the id
+ *
+ * @return the id
+ */
+ public String getId() {
+ return id;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/GetAllFragmentDescriptorsOperation.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/GetAllFragmentDescriptorsOperation.java
new file mode 100644
index 00000000000..4052fa1cdf7
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/GetAllFragmentDescriptorsOperation.java
@@ -0,0 +1,42 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view;
+
+import java.util.Map;
+
+import org.eclipse.gmf.runtime.common.core.service.IProvider;
+
+/**
+ * Operation to retrieve all available fragment descriptors
+ */
+public class GetAllFragmentDescriptorsOperation implements IPropertyViewOperation {
+
+
+ /**
+ * Creates a new GetAllFragmentDescriptorsOperation.
+ */
+ public GetAllFragmentDescriptorsOperation() {
+ // nothing specific here
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Map<String, FragmentDescriptor> execute(IProvider provider) {
+ if(provider instanceof IPropertyViewProvider) {
+ return ((IPropertyViewProvider)provider).getAllFragmentDescriptors();
+ }
+ return null;
+ }
+
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/GetFragmentDescriptorOperation.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/GetFragmentDescriptorOperation.java
new file mode 100644
index 00000000000..623b01ee035
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/GetFragmentDescriptorOperation.java
@@ -0,0 +1,54 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view;
+
+import org.eclipse.gmf.runtime.common.core.service.IProvider;
+
+
+/**
+ * Operation to retrieve a fragment descriptor using its ID
+ */
+public class GetFragmentDescriptorOperation implements IPropertyViewOperation {
+
+ /** id of the view descriptor to retrieve */
+ protected final String descriptorID;
+
+ /**
+ * Creates a new GetFragmentDescriptorOperation.
+ *
+ * @param descriptorID
+ * the identifier of the fragment descriptor to create
+ */
+ public GetFragmentDescriptorOperation(String descriptorID) {
+ this.descriptorID = descriptorID;
+ }
+
+ /**
+ * Returns the descriptor id for this operation
+ *
+ * @return the descriptor id for this operation
+ */
+ public String getDescriptorID() {
+ return descriptorID;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Object execute(IProvider provider) {
+ if(provider instanceof IPropertyViewProvider) {
+ return ((IPropertyViewProvider)provider).getFragmentDescriptor(descriptorID);
+ }
+ return null;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/IConfigurableDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/IConfigurableDescriptor.java
new file mode 100644
index 00000000000..720595b2ba5
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/IConfigurableDescriptor.java
@@ -0,0 +1,46 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view;
+
+import org.eclipse.papyrus.properties.runtime.state.IState;
+import org.eclipse.swt.graphics.Image;
+
+
+/**
+ * interface shared by all descriptors that can be configured by the Papyrus customization support
+ */
+public interface IConfigurableDescriptor {
+
+ /**
+ * Returns the label displayed by the descriptor
+ *
+ * @return the label displayed by the descriptor
+ */
+ public String getText();
+
+ /**
+ * Returns the image displayed by the descriptor
+ *
+ * @return the image displayed by the descriptor
+ */
+ public Image getImage();
+
+ /**
+ * Creates a state on this descriptor, in order to be able to customize it.
+ *
+ * @param readOnly
+ * the read only mode of the state
+ * @return the created state
+ */
+ public IState createState(boolean readOnly);
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/IFragmentDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/IFragmentDescriptor.java
new file mode 100644
index 00000000000..f7194ebfddc
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/IFragmentDescriptor.java
@@ -0,0 +1,43 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view;
+
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.state.IFragmentDescriptorState;
+import org.eclipse.papyrus.properties.runtime.view.content.ContainerDescriptor;
+
+
+/**
+ * Interface for all fragment descriptors
+ */
+public interface IFragmentDescriptor extends IConfigurableDescriptor {
+
+ /**
+ * Returns the list of containers descriptors
+ *
+ * @return the list of containers descriptors
+ */
+ public List<ContainerDescriptor> getContainerDescriptors();
+
+ /**
+ * {@inheritDoc}
+ */
+ public IFragmentDescriptorState createState(boolean readOnly);
+
+ /**
+ * Returns the id of the fragment described by the descriptor
+ *
+ * @return the id of the fragment described by the descriptor
+ */
+ public String getId();
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/IPropertyViewOperation.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/IPropertyViewOperation.java
new file mode 100644
index 00000000000..4bc0fb2cba9
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/IPropertyViewOperation.java
@@ -0,0 +1,24 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view;
+
+import org.eclipse.gmf.runtime.common.core.service.IOperation;
+
+
+/**
+ * Interface implemented by all Property view operations
+ *
+ * @see IOperation
+ */
+public interface IPropertyViewOperation extends IOperation {
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/IPropertyViewProvider.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/IPropertyViewProvider.java
new file mode 100644
index 00000000000..f52bf502a99
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/IPropertyViewProvider.java
@@ -0,0 +1,87 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view;
+
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.gmf.runtime.common.core.service.IProvider;
+
+
+/**
+ * Interface for Property view providers
+ */
+public interface IPropertyViewProvider extends IProvider {
+
+ /**
+ * Configures this provider, retrieving the xml file and parsing it.
+ *
+ * @param element
+ * the configuration element for this provider
+ */
+ public void configure(IConfigurationElement element);
+
+ /**
+ * Returns the fragment descriptor, given its ID
+ *
+ * @param descriptorID
+ * the id of the descriptor to retrieve
+ * @return the found fragment descriptor or <code>null</code>
+ */
+ public FragmentDescriptor getFragmentDescriptor(String descriptorID);
+
+ /**
+ * returns the full map of fragments descriptors proposed by this provider, key is their identifier
+ *
+ * @return the full map of fragments descriptors proposed by this provider, key is their identifier
+ */
+ public Map<String, FragmentDescriptor> getAllFragmentDescriptors();
+
+ /**
+ * returns <code>true</code> if this provider can handle the fragment descriptor specified by its identifier
+ *
+ * @param descriptorId
+ * the id of the descriptor
+ * @return <code>true</code> if the provider can handle this fragment provider
+ */
+ public boolean managesFragmentDescriptor(String descriptorId);
+
+ /**
+ * Returns the dialog descriptor, given its ID
+ *
+ * @param descriptorID
+ * the id of the descriptor to retrieve
+ * @return the found dialog descriptor or <code>null</code>
+ */
+ public DialogDescriptor getDialogDescriptor(String descriptorID);
+
+ /**
+ * Returns the list of dialog descriptors, valid for the list of given objects
+ *
+ * @param objectsToEdit
+ * list of objects to edit
+ * @return the found dialog descriptors or <code>null</code>
+ */
+ public List<DialogDescriptor> getDialogDescriptor(List<Object> objectsToEdit);
+
+ /**
+ * returns <code>true</code> if this provider can handle the dialog descriptor specified by its identifier
+ *
+ * @param descriptorId
+ * the id of the descriptor
+ * @return <code>true</code> if the provider can handle this dialog provider
+ */
+ public boolean managesDialogDescriptor(String descriptorId);
+
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/PredefinedFragmentDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/PredefinedFragmentDescriptor.java
new file mode 100644
index 00000000000..0c5948debdd
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/PredefinedFragmentDescriptor.java
@@ -0,0 +1,93 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.state.IFragmentDescriptorState;
+import org.eclipse.papyrus.properties.runtime.view.content.ContainerDescriptor;
+import org.eclipse.swt.graphics.Image;
+
+
+/**
+ * descriptor for predefined fragments
+ */
+public class PredefinedFragmentDescriptor implements IFragmentDescriptor {
+
+ /** id of the predefined descriptor */
+ private String predefinedId;
+
+ /** parsing failed */
+ private boolean parseFailed = false;
+
+ /** descriptor referenced by this predefined descriptor */
+ private IFragmentDescriptor descriptor = null;
+
+ /**
+ * Creates a new PredefinedFragmentDescriptor.
+ *
+ * @param predefinedId
+ * the id of the predefined descriptor
+ */
+ public PredefinedFragmentDescriptor(String predefinedId) {
+ this.predefinedId = predefinedId;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "PredefinedFragment: " + predefinedId;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return Activator.getImage("/icons/PredefinedFragment.gif");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IFragmentDescriptorState createState(boolean readOnly) {
+ return new PredefinedFragmentDescriptorState(this, readOnly);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<ContainerDescriptor> getContainerDescriptors() {
+ if(descriptor == null && !parseFailed) {
+ // resolve the fragment descriptor if it exists
+ descriptor = PropertyViewService.getInstance().getFragmentDescriptor(predefinedId);
+ if(descriptor == null) {
+ parseFailed = true;
+ }
+ }
+
+ if(descriptor != null) {
+ return descriptor.getContainerDescriptors();
+ }
+ return Collections.emptyList();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getId() {
+ return predefinedId;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/PredefinedFragmentDescriptorState.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/PredefinedFragmentDescriptorState.java
new file mode 100644
index 00000000000..fa6c8b41de0
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/PredefinedFragmentDescriptorState.java
@@ -0,0 +1,107 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view;
+
+import java.beans.PropertyChangeListener;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.state.AbstractState;
+import org.eclipse.papyrus.properties.runtime.state.IFragmentDescriptorState;
+import org.eclipse.papyrus.properties.runtime.state.ITraversableModelElement;
+import org.eclipse.papyrus.properties.runtime.view.content.ContainerDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.content.ContainerDescriptorState;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+/**
+ * State for {@link PredefinedFragmentDescriptor}
+ */
+public class PredefinedFragmentDescriptorState extends AbstractState implements IFragmentDescriptorState {
+
+ /** the descriptor managed by this state */
+ private final PredefinedFragmentDescriptor predefinedFragmentDescriptor;
+
+ /** list of container descriptors state children of this state */
+ private final List<ContainerDescriptorState> containerDescriptorStates = new ArrayList<ContainerDescriptorState>();
+
+ /**
+ * Creates a new PredefinedFragmentDescriptorState.
+ *
+ * @param predefinedFragmentDescriptor
+ * the descriptor managed by this state
+ * @param readOnly
+ */
+ public PredefinedFragmentDescriptorState(PredefinedFragmentDescriptor predefinedFragmentDescriptor, boolean readOnly) {
+ super(readOnly);
+ this.predefinedFragmentDescriptor = predefinedFragmentDescriptor;
+
+ for(ContainerDescriptor containerDescriptor : predefinedFragmentDescriptor.getContainerDescriptors()) {
+ getContainerDescriptorStates().add(containerDescriptor.createState(true));
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<? extends ITraversableModelElement> getChildren() {
+ return getContainerDescriptorStates();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public PredefinedFragmentDescriptor getDescriptor() {
+ return predefinedFragmentDescriptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEditionDialogId() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ // nothing here, read only
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ // nothing here, read only
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<ContainerDescriptorState> getContainerDescriptorStates() {
+ return containerDescriptorStates;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node generateNode(Document document) {
+ Element element = document.createElement("fragment");
+ element.setAttribute("predefinedId", getDescriptor().getId());
+ return element;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/PropertyViewProviderParser.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/PropertyViewProviderParser.java
new file mode 100644
index 00000000000..3da88453d3a
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/PropertyViewProviderParser.java
@@ -0,0 +1,672 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.dialogs.EMFFeatureBindingLabelProviderDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.constraints.AppliedStereotypeConstraintDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.constraints.IConstraintDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.constraints.ObjectTypeConstraintDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.content.ContainerDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.content.ExpandableContainerDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.content.GroupContainerDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.content.LayoutDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.content.LayoutParser;
+import org.osgi.framework.Bundle;
+import org.w3c.dom.Document;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+
+/**
+ * Parser for the xml content of the property view provider
+ */
+public class PropertyViewProviderParser {
+
+ /** node name for dialogs */
+ protected static final String DIALOGS_NODE_NAME = "dialogs";
+
+ /** node name for fragments */
+ protected static final String NODE_NAME_FRAGMENTS = "fragments";
+
+ /** node name for tab */
+ protected static final String NODE_NAME_TAB = "tab";
+
+ /** node name for fragment */
+ protected static final String NODE_NAME_FRAGMENT = "fragment";
+
+ /** node name for id */
+ protected static final String NODE_NAME_ID = "id";
+
+ /** key for the value: path to the xml file */
+ protected static final String XML_PATH = "path";
+
+ /** node name for dialog */
+ protected static final String NODE_NAME_DIALOG = "dialog";
+
+ /** ATTRIBUTE_PREDEFINED_ID */
+ protected static final String ATTRIBUTE_PREDEFINED_ID = "predefinedId";
+
+ /** reference to the map containing predefined fragments */
+ protected Map<String, FragmentDescriptor> predefinedFragments;
+
+ /** stores the reference to the bundle, so the bundle class loader can be used to load classes */
+ protected Bundle bundle;
+
+ /** reference to the map containing predefined dialogs */
+ protected Map<String, DialogDescriptor> predefinedDialogs;
+
+ /**
+ * Parses the fragment node
+ *
+ * @param fragmentNode
+ * the node corresponding to the fragment
+ * @return the fragment result of the parsing
+ * @throws XMLParseException
+ * parsing failed
+ */
+ protected FragmentDescriptor parseFragment(Node fragmentNode) throws XMLParseException {
+ // the fragment node is divided into 2 parts:
+ // the first one describes the context for the fragment to be displayed,
+ // the second one describes the content of the fragment itself
+
+ // retrieve ID of the fragment (to be reused as a predefined fragment)
+ NamedNodeMap attributes = fragmentNode.getAttributes();
+ String id;
+ if(attributes != null) {
+ Node idNode = attributes.getNamedItem("id");
+ if(idNode != null) {
+ id = idNode.getNodeValue();
+ } else {
+ throw new XMLParseException("Impossible to find ID for fragment " + fragmentNode);
+ }
+ } else {
+ throw new XMLParseException("Impossible to find ID for fragment " + fragmentNode);
+ }
+
+ NodeList children = fragmentNode.getChildNodes();
+ Node contextNode = null;
+ Node contentNode = null;
+
+ for(int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ final String childNodeName = child.getNodeName();
+ if("context".equals(childNodeName)) {
+ // this is the context of the fragment
+ // store this node.
+ contextNode = child;
+ } else if("content".equals(childNodeName)) {
+ contentNode = child;
+ }
+ }
+
+ // 2 nodes should have been found
+ if(contextNode == null || contentNode == null) {
+ Activator.log.error("Impossible to parse configuration for " + fragmentNode, null);
+ return null;
+ }
+
+ // parses constraints that will be given to each section
+ List<IConstraintDescriptor> constraints = parseConstraints(contextNode);
+
+ // retrieve selection size
+ int selectionSize = parseSelectionSize(contextNode);
+
+ // do not parse currently the content node, will be done later, as the fragment is used
+ return new FragmentDescriptor(id, constraints, contentNode, selectionSize, this);
+ }
+
+ /**
+ * Parses the specified node and returns the list of replaced dialogs
+ *
+ * @param contextNode
+ * the node to parse
+ * @return the list of replaced ids or an empty list if none
+ */
+ protected List<String> parseReplacedDialogs(Node contextNode) {
+ List<String> replacedDialogIds = new ArrayList<String>();
+ // retrieve "replacedDialogs" node
+
+ NodeList childrenNodes = contextNode.getChildNodes();
+ for(int i = 0; i < childrenNodes.getLength(); i++) {
+ Node childNode = childrenNodes.item(i);
+ String childNodeName = childNode.getNodeName();
+ if("replacedDialogs".equals(childNodeName)) {
+ NodeList replacedDialogNodes = childNode.getChildNodes();
+ for(int j = 0; j < replacedDialogNodes.getLength(); j++) {
+ Node replacedDialogNode = replacedDialogNodes.item(j);
+ if("replacedDialog".equals(replacedDialogNode.getNodeName())) {
+ // this is a replaced dialog node, try to find attribute id
+ NamedNodeMap attributes = replacedDialogNode.getAttributes();
+ if(attributes != null) {
+ Node idNode = attributes.getNamedItem(NODE_NAME_ID);
+ if(idNode != null) {
+ replacedDialogIds.add(idNode.getNodeValue());
+ }
+ }
+ }
+ }
+ }
+ }
+ return replacedDialogIds;
+ }
+
+ /**
+ * Parses the size the selection should be
+ *
+ * @param contextNode
+ * the node to parse
+ * @return the size the selection should be
+ */
+ protected int parseSelectionSize(Node contextNode) {
+ NamedNodeMap contextAttributes = contextNode.getAttributes();
+ Node isMultiNode = contextAttributes.getNamedItem("enablesFor");
+ String isMultiValue = isMultiNode.getNodeValue();
+ return Integer.parseInt(isMultiValue);
+ }
+
+ /**
+ * Parses the list of constraints for this node
+ *
+ * @param contextNode
+ * the context node to parse
+ * @return the list of constraints for this node
+ */
+ protected List<IConstraintDescriptor> parseConstraints(Node contextNode) {
+
+ List<IConstraintDescriptor> constraintDescriptors = new ArrayList<IConstraintDescriptor>();
+ // retrieve meta class for which the fragment is valid
+ // and additional constraints (applied profiles, applied stereotypes, ocl constraints, etc)
+ NodeList children2 = contextNode.getChildNodes();
+ Class<?> elementClass = null;
+ for(int j = 0; j < children2.getLength(); j++) {
+ Node child2 = children2.item(j);
+ // check child 2 is an element class definition
+ if("elementClass".equals(child2.getNodeName())) {
+ if(child2.getAttributes() != null && child2.getAttributes().getNamedItem("name") != null) {
+ String elementClassName = child2.getAttributes().getNamedItem("name").getNodeValue();
+ // should retrieve java class corresponding to this class
+ try {
+ elementClass = bundle.loadClass(elementClassName);
+ constraintDescriptors.add(new ObjectTypeConstraintDescriptor(elementClass));
+ } catch (ClassNotFoundException e) {
+ Activator.log.error(e);
+ }
+ }
+ } else if("appliedStereotypes".equals(child2.getNodeName())) {
+ List<String> appliedStereotypeQNames = new ArrayList<String>();
+ // each child node of this node is the stereotype with qualified names
+ NodeList stereotypeNodes = child2.getChildNodes();
+ for(int i = 0; i < stereotypeNodes.getLength(); i++) {
+ Node stereotypeNode = stereotypeNodes.item(i);
+ String stereotypeNodeName = stereotypeNode.getNodeName();
+ if("appliedStereotype".equals(stereotypeNodeName)) {
+ // retrieve attribute QN
+ NamedNodeMap attributes = stereotypeNode.getAttributes();
+ if(attributes != null) {
+ Node qualifiedName = attributes.getNamedItem("qualifiedName");
+ if(qualifiedName != null) {
+ appliedStereotypeQNames.add(qualifiedName.getNodeValue());
+ }
+ }
+ }
+ }
+ constraintDescriptors.add(new AppliedStereotypeConstraintDescriptor(appliedStereotypeQNames));
+ }
+ }
+ return constraintDescriptors;
+ }
+
+ /**
+ * Parses the content of the xml file
+ *
+ * @param document
+ * the document to parse
+ * @param predefinedFragments
+ * the list of predefined views, which will be completed during this parsing
+ * @param predefinedDialogs
+ * list of predefined dialogs
+ * @throws XMLParseException
+ * parsing failed
+ */
+ public void parseXMLfile(Document document, Map<String, FragmentDescriptor> predefinedFragments, Map<String, DialogDescriptor> predefinedDialogs) throws XMLParseException {
+ this.predefinedFragments = predefinedFragments;
+ this.predefinedDialogs = predefinedDialogs;
+ // this.bundle = bundle;
+ NodeList roots = document.getChildNodes();
+ for(int i = 0; i < roots.getLength(); i++) {
+ Node fragmentsOrDialogsNode = roots.item(i);
+ // check this is a "fragments" or "dialogs" node, not a comment or a text format node.
+ final String topNodeName = fragmentsOrDialogsNode.getNodeName();
+ if(NODE_NAME_FRAGMENTS.equals(topNodeName)) {
+ parseFragmentsNode(fragmentsOrDialogsNode);
+ } else if(DIALOGS_NODE_NAME.equals(topNodeName)) {
+ parseDialogsNode(fragmentsOrDialogsNode);
+ }
+ }
+ }
+
+ /**
+ * Parses the dialogs node and adds a dialog Descriptor to the list of dialog descriptors maintained by this provider
+ *
+ * @param dialogNode
+ * the node to parse
+ * @throws XMLParseException
+ * exception thrown when the file could not be parsed correctly
+ */
+ protected void parseDialogsNode(Node dialogNode) throws XMLParseException {
+ String pluginId = getPluginIdFromTopNode(dialogNode);
+ bundle = Platform.getBundle(pluginId);
+
+ // retrieve each child node which is a dialog
+ NodeList children = dialogNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ // check this is a dialog node (not a comment or a formatting children)
+
+ Node childNode = children.item(i);
+ String childNodeName = childNode.getNodeName();
+ if(NODE_NAME_DIALOG.equals(childNodeName)) {
+ DialogDescriptor dialogDescriptor = parseDialogNode(childNode);
+ if(dialogDescriptor != null) {
+ predefinedDialogs.put(dialogDescriptor.getId(), dialogDescriptor);
+ }
+ }
+ }
+ }
+
+ /**
+ * Parses the dialog node and returns a dialog descriptor from this configuration
+ *
+ * @param dialogNode
+ * the node corresponding to the dialog
+ * @return the new {@link DialogDescriptor}
+ * @throws XMLParseException
+ * parsing failed
+ */
+ protected DialogDescriptor parseDialogNode(Node dialogNode) throws XMLParseException {
+ // retrieve ID of the dialog (to be reused as a predefined dialog)
+ NamedNodeMap attributes = dialogNode.getAttributes();
+ String id;
+ if(attributes != null) {
+ Node idNode = attributes.getNamedItem("id");
+ if(idNode != null) {
+ id = idNode.getNodeValue();
+ } else {
+ throw new XMLParseException("Impossible to find ID for dialog " + dialogNode);
+ }
+ } else {
+ throw new XMLParseException("Impossible to find ID for dialog " + dialogNode);
+ }
+
+ NodeList children = dialogNode.getChildNodes();
+ Node contextNode = null;
+ Node contentNode = null;
+ Node titleNode = null;
+ Node messageNode = null;
+
+ for(int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ final String childNodeName = child.getNodeName();
+ if("context".equals(childNodeName)) {
+ // this is the context of the dialog
+ // store this node.
+ contextNode = child;
+ } else if("content".equals(childNodeName)) {
+ contentNode = child;
+ } else if("title".equals(childNodeName)) {
+ titleNode = child;
+ } else if("message".equals(childNodeName)) {
+ messageNode = child;
+ }
+ }
+
+ // 2 nodes should have been found
+ if(contextNode == null || contentNode == null || titleNode == null || messageNode == null) {
+ Activator.log.error("Impossible to parse configuration for " + dialogNode, null);
+ return null;
+ }
+
+ // parses constraints that will be given to each section
+ List<IConstraintDescriptor> constraints = parseConstraints(contextNode);
+ int selectionSize = parseSelectionSize(contextNode);
+
+ // parses the list of replaced dialogs
+ List<String> replacedDialogIds = parseReplacedDialogs(contextNode);
+
+ Object message = parseStringNode(messageNode);
+
+ Object title = parseStringNode(titleNode);
+
+ // do not parse currently the content node, will be done later, as the dialog is used
+ return new DialogDescriptor(id, constraints, contentNode, selectionSize, replacedDialogIds, title, message, this);
+ }
+
+ /**
+ * Parses the title node
+ *
+ * @param titleNode
+ * the node to parse
+ * @return the result of the parsing
+ */
+ protected Object parseStringNode(Node titleNode) {
+ // two possibilities currently: only a simple string, a second one usgin a message binding
+ NodeList children = titleNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ String childNodeName = child.getNodeName();
+ if("string".equals(childNodeName)) {
+ // there should be a value attribute
+ NamedNodeMap attributes = child.getAttributes();
+ if(attributes != null) {
+ Node valueNode = attributes.getNamedItem("value");
+ return (valueNode != null) ? valueNode.getNodeValue() : "";
+ } else {
+ Activator.log.warn("no attribute for title Node: " + titleNode);
+ }
+ } else if("emfMessageBinding".equals(childNodeName)) {
+ return parseEMFBindingNode(child);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Parses the message binding node
+ *
+ * @param messageBindingNode
+ * the node to parse
+ * @return the result of the parsing
+ */
+ protected Object parseEMFBindingNode(Node messageBindingNode) {
+ String message = null;
+ List<String> featureNames = new ArrayList<String>();
+
+ // retrieve attribute message
+ NamedNodeMap attributes = messageBindingNode.getAttributes();
+ if(attributes != null) {
+ Node valueNode = attributes.getNamedItem("message");
+ if(valueNode != null) {
+ message = valueNode.getNodeValue();
+ } else {
+ Activator.log.warn("ParseBindingNode: No value for message node : " + messageBindingNode);
+ return null;
+ }
+ } else {
+ Activator.log.warn("ParseBindingNode: No attributes for node: " + messageBindingNode);
+ return null;
+ }
+
+ NodeList childNodes = messageBindingNode.getChildNodes();
+ for(int i = 0; i < childNodes.getLength(); i++) {
+ Node child = childNodes.item(i);
+ String childNodeName = child.getNodeName();
+
+ if("feature".equals(childNodeName)) {
+ attributes = child.getAttributes();
+ if(attributes != null) {
+ Node valueNode = attributes.getNamedItem("name");
+ if(valueNode != null) {
+ featureNames.add(valueNode.getNodeValue());
+ }
+ } else {
+ Activator.log.warn("ParseBindingNode: No attributes for feature node: " + child);
+ }
+ }
+ }
+ // FIXME here, we should not know that we work using EMF features...
+ return new EMFFeatureBindingLabelProviderDescriptor(message, featureNames.toArray(new String[]{}));
+
+ }
+
+ /**
+ * Parses the fragment node and adds a fragment Descriptor to the list of fragment descriptor maintained by this provider
+ *
+ * @param fragmentNode
+ * the configuration node of the fragment
+ * @throws XMLParseException
+ * parsing failed
+ */
+ protected void parseFragmentsNode(Node fragmentNode) throws XMLParseException {
+ String pluginId = getPluginIdFromTopNode(fragmentNode);
+ bundle = Platform.getBundle(pluginId);
+
+ // retrieve each child node which is a fragment
+ NodeList children = fragmentNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ // check this is a fragment node (not a comment or a formatting children)
+
+ Node childNode = children.item(i);
+ String childNodeName = childNode.getNodeName();
+ if(NODE_NAME_FRAGMENT.equals(childNodeName)) {
+ FragmentDescriptor fragmentDescriptor = parseFragment(childNode);
+ if(fragmentDescriptor != null) {
+ predefinedFragments.put(fragmentDescriptor.getId(), fragmentDescriptor);
+ }
+ }
+ }
+ }
+
+ /**
+ * Retrieves the value of the attribute pluginId
+ *
+ * @param topNode
+ * the node to parse
+ * @return the id of the plugin from which class loader is used
+ * @throws XMLParseException
+ * exception thrown when the content of the file could not be read correctly
+ */
+ protected String getPluginIdFromTopNode(Node topNode) throws XMLParseException {
+ NamedNodeMap attributes = topNode.getAttributes();
+ if(attributes != null) {
+ Node pluginIdNode = attributes.getNamedItem("pluginId");
+ if(pluginIdNode != null) {
+ return pluginIdNode.getNodeValue();
+ }
+ }
+ throw new XMLParseException("impossible to find plugin id for top node: " + topNode);
+ }
+
+ /**
+ * Parses the xml content node to set the content of the section
+ *
+ * @param unparsedContentNode
+ * the node to parse
+ * @return the new configuration for the section
+ * @throws XMLParseException
+ * exception thrown when the content of the file could not be read correctly
+ */
+ public List<ContainerDescriptor> parseFragmentContentNode(Node unparsedContentNode) throws XMLParseException {
+ ArrayList<ContainerDescriptor> containerDescriptors = new ArrayList<ContainerDescriptor>();
+ NodeList children = unparsedContentNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ Node containerNode = children.item(i);
+ if("container".equals(containerNode.getNodeName())) {
+ containerDescriptors.add(parseContainerNode(containerNode));
+ } else if("expandableContainer".equals(containerNode.getNodeName())) {
+ containerDescriptors.add(parseExpandableContainerNode(containerNode));
+ } else if("groupContainer".equals(containerNode.getNodeName())) {
+ containerDescriptors.add(parseGroupNode(containerNode));
+ }
+ }
+ return containerDescriptors;
+
+ }
+
+ /**
+ * Parses the container XML description and returns the descriptor.
+ *
+ * @param containerNode
+ * the node to parse
+ * @return the result of the parsing
+ * @throws XMLParseException
+ * exception thrown when the content of the file could not be read correctly
+ */
+ protected ContainerDescriptor parseContainerNode(Node containerNode) throws XMLParseException {
+ // retrieve layout node
+ Node layoutNode = getLayoutNode(containerNode);
+ LayoutDescriptor layoutDescriptor = parseLayoutNode(layoutNode);
+ return new ContainerDescriptor(layoutDescriptor, containerNode);
+ }
+
+ /**
+ * Finds and return the layout node for the specified container node
+ *
+ * @param containerNode
+ * the node which contains the layout node
+ * @return the
+ */
+ protected Node getLayoutNode(Node containerNode) {
+ NodeList children = containerNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ // get the name of the children,; which should equals "layout"
+ Node child = children.item(i);
+ if("layout".equals(child.getNodeName())) {
+ return child;
+ }
+ }
+ return null;
+ }
+
+ /**
+ * Parses the group container XML description and returns the descriptor.
+ *
+ * @param containerNode
+ * the node to parse
+ * @return the result of the parsing
+ * @throws XMLParseException
+ * exception thrown when the content of the file could not be read correctly
+ */
+ protected ContainerDescriptor parseGroupNode(Node containerNode) throws XMLParseException {
+ // retrieve layout node
+ Node layoutNode = getLayoutNode(containerNode);
+ LayoutDescriptor layoutDescriptor = parseLayoutNode(layoutNode);
+ String label = parseLabel(containerNode);
+ return new GroupContainerDescriptor(layoutDescriptor, label, containerNode);
+ }
+
+ /**
+ * Parses the expandable container XML description and returns the descriptor.
+ *
+ * @param containerNode
+ * the node to parse
+ * @return the result of the parsing
+ * @throws XMLParseException
+ * exception thrown when the content of the file could not be read correctly
+ */
+ protected ContainerDescriptor parseExpandableContainerNode(Node containerNode) throws XMLParseException {
+ // retrieve layout node
+ Node layoutNode = getLayoutNode(containerNode);
+ LayoutDescriptor layoutDescriptor = parseLayoutNode(layoutNode);
+ String label = parseLabel(containerNode);
+ return new ExpandableContainerDescriptor(layoutDescriptor, label, containerNode);
+ }
+
+ /**
+ * Parses the label for the given container
+ *
+ * @param containerNode
+ * the container node to parse
+ * @return the label of the container
+ * @throws XMLParseException
+ * exception thrown when XML file could not be parsed.
+ */
+ protected String parseLabel(Node containerNode) throws XMLParseException {
+ NamedNodeMap attributes = containerNode.getAttributes();
+ if(attributes == null) {
+ throw new XMLParseException("Impossible to find attributes for container node " + containerNode);
+ }
+ // retrieve the name
+ Node nameNode = attributes.getNamedItem("label");
+ String label = "";
+ if(nameNode == null) {
+ throw new XMLParseException("Impossible to find layout attribute for container node " + containerNode);
+ } else {
+ label = nameNode.getNodeValue();
+ }
+ return label;
+ }
+
+ /**
+ * Parses the layout for the container
+ *
+ * @param layoutNode
+ * the node to parse
+ *
+ * @param containerNode
+ * the container node which contains layout information
+ * @return the layout for the container
+ * @throws XMLParseException
+ * exception thrown when the content of the file could not be read correctly
+ */
+ protected LayoutDescriptor parseLayoutNode(Node layoutNode) throws XMLParseException {
+ return LayoutParser.parseLayoutNode(layoutNode);
+ }
+
+ /**
+ * Parses the node of the content for a dialog configuration
+ *
+ * @param contentNode
+ * the content node to parse
+ * @return the list of identifier of fragment descriptors referenced by this content node
+ * @throws XMLParseException
+ * exception thrown when the content of the file could not be read correctly
+ */
+ public List<IFragmentDescriptor> parseDialogContentNode(Node contentNode) throws XMLParseException {
+ List<IFragmentDescriptor> fragmentDescriptors = new ArrayList<IFragmentDescriptor>();
+ try {
+ NodeList children = contentNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ Node childNode = children.item(i);
+ if(NODE_NAME_FRAGMENT.equals(childNode.getNodeName())) {
+ IFragmentDescriptor descriptor = parseFragmentOrPredefinedFragment(childNode);
+ fragmentDescriptors.add(descriptor);
+ }
+ }
+ } catch (XMLParseException e) {
+ Activator.log.error("Problem during parsing of replaced sections for node " + contentNode, e);
+ }
+ return fragmentDescriptors;
+ }
+
+ /**
+ * Parses a fragment node, either a predefined fragment or a locally defined fragment
+ *
+ * @param fragmentNode
+ * the node to parse
+ * @return the parsed fragment
+ * @throws XMLParseException
+ * exception thrown when the content of the file could not be read correctly
+ */
+ protected IFragmentDescriptor parseFragmentOrPredefinedFragment(Node fragmentNode) throws XMLParseException {
+ NamedNodeMap attributes = fragmentNode.getAttributes();
+ if(attributes != null) {
+ Node attribute = attributes.getNamedItem(ATTRIBUTE_PREDEFINED_ID);
+ if(attribute != null) {
+ return new PredefinedFragmentDescriptor(attribute.getNodeValue());
+ }
+ }
+
+ // this is a locally defined fragment.
+ // parse it as it was a predefinition of fragment
+ FragmentDescriptor fragmentDescriptor;
+
+ fragmentDescriptor = parseFragment(fragmentNode);
+ predefinedFragments.put(fragmentDescriptor.getId(), fragmentDescriptor);
+ return fragmentDescriptor;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/PropertyViewService.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/PropertyViewService.java
new file mode 100644
index 00000000000..fab2ca6d256
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/PropertyViewService.java
@@ -0,0 +1,307 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.IPreferenceChangeListener;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences.PreferenceChangeEvent;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+import org.eclipse.gmf.runtime.common.core.service.ExecutionStrategy;
+import org.eclipse.gmf.runtime.common.core.service.IOperation;
+import org.eclipse.gmf.runtime.common.core.service.IProvider;
+import org.eclipse.gmf.runtime.common.core.service.ProviderChangeEvent;
+import org.eclipse.gmf.runtime.common.core.service.Service;
+import org.eclipse.gmf.runtime.common.ui.services.util.ActivityFilterProviderDescriptor;
+import org.eclipse.papyrus.properties.runtime.controller.PropertyEditorController;
+import org.eclipse.papyrus.properties.runtime.controller.PropertyEditorControllerService;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IPropertyEditorControllerDescriptor;
+import org.eclipse.papyrus.properties.runtime.dialogs.GetDialogDescriptorOperation;
+import org.eclipse.papyrus.properties.runtime.dialogs.GetDialogDescriptorOperationById;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+
+/**
+ * Service to provide property views providers.
+ */
+public class PropertyViewService extends Service implements IPreferenceChangeListener {
+
+ /** instance of this service */
+ protected static PropertyViewService instance;
+
+ /**
+ * Creates a new PropertyViewService. This constructor is not visible, using singleton pattern.
+ */
+ protected PropertyViewService() {
+ super();
+ IEclipsePreferences prefs = new InstanceScope().getNode(org.eclipse.papyrus.properties.runtime.Activator.ID);
+ prefs.addPreferenceChangeListener(this);
+ }
+
+ /**
+ * Returns the singleton instance of this service.
+ *
+ * @return the singleton instance of this service
+ */
+ /**
+ * Returns the singleton instance of this service
+ *
+ * @return the singleton instance of this service
+ */
+ public synchronized static PropertyViewService getInstance() {
+ if(instance == null) {
+ instance = new PropertyViewService();
+ instance.configureProviders(org.eclipse.papyrus.properties.runtime.Activator.ID, "propertyViewProvider"); //$NON-NLS-1$
+ }
+ return instance;
+ }
+
+ /**
+ * Returns the list of property view Providers
+ *
+ * @return the list of property view Providers
+ */
+ @SuppressWarnings("unchecked")
+ public List<PropertyViewService.ProviderDescriptor> getPropertyViewProviders() {
+ return (List<PropertyViewService.ProviderDescriptor>)findAllProviders();
+ }
+
+ /**
+ * Creates a new Property editor controller given its configuration
+ *
+ * @param objectsToEdit
+ * the list of objects to display
+ * @param parent
+ * the composite parent for the property view
+ * @param controllerDescriptor
+ * the descriptor of the property editor controller
+ * @param widgetFactory
+ * @return the created controller for the property editor
+ */
+ public PropertyEditorController createPropertyEditorController(List<Object> objectsToEdit, Composite parent, IPropertyEditorControllerDescriptor controllerDescriptor, TabbedPropertySheetWidgetFactory widgetFactory) {
+ PropertyEditorController controller = PropertyEditorControllerService.getInstance().createPropertyEditorController(objectsToEdit, parent, controllerDescriptor);
+
+ if(controller != null) {
+ controller.createPropertyEditor(controllerDescriptor.getEditorDescriptor(), widgetFactory);
+ }
+ return controller;
+ }
+
+ /**
+ * Returns the dialog descriptor given the id of this dialog
+ *
+ * @param dialogID
+ * id of the dialog described by this element
+ * @return the configuration descriptor for the dialog
+ */
+ public DialogDescriptor getDialogDescriptor(String dialogID) {
+ DialogDescriptor descriptor = (DialogDescriptor)executeUnique(ExecutionStrategy.REVERSE, new GetDialogDescriptorOperationById(dialogID));
+ return descriptor;
+ }
+
+ /**
+ * Returns the dialog descriptor that fits best to the list of given objects
+ *
+ * @param objectsToEdit
+ * the list of objects to edit
+ * @return the best dialog found
+ */
+ @SuppressWarnings("unchecked")
+ public DialogDescriptor getDialogDescriptor(List<Object> objectsToEdit) {
+ List<List<DialogDescriptor>> validDescriptors = (List<List<DialogDescriptor>>)execute(ExecutionStrategy.REVERSE, new GetDialogDescriptorOperation(objectsToEdit));
+ List<DialogDescriptor> filteredDescriptors = new ArrayList<DialogDescriptor>();
+
+ // filter this list using the replaced descriptors
+ List<DialogDescriptor> subList = flattenList(validDescriptors);
+ // check sub list is not empty
+ if(subList.isEmpty()) {
+ return null;
+ }
+
+ // the list of available descriptors is now available, now remove from the list the section descriptors which are erased by others
+ for(DialogDescriptor currentDescriptor : subList) {
+ boolean isRemoved = false;
+ String currentId = currentDescriptor.getId();
+ // is this descriptor removed by another one ?
+ for(DialogDescriptor descriptor : subList) {
+ if(descriptor.getReplacedDialogIds().contains(currentId)) {
+ isRemoved = true;
+ }
+ }
+
+ if(!isRemoved) {
+ filteredDescriptors.add(currentDescriptor);
+ }
+ }
+
+ // check the filtered descriptors is not an empty list.
+ // Otherwise, it should take the first one from the available list as default
+ // if the list has more that one available editors, take the first one also
+ if(filteredDescriptors.isEmpty()) {
+ return subList.get(0); // not empty because it has been checked before
+ } else {
+ return filteredDescriptors.get(0);
+ }
+ }
+
+ /**
+ * Returns a fragment descriptor for its Id
+ *
+ * @param id
+ * the id of the fragment descriptor to retrieve
+ * @return the fragment descriptor found or <code>null</code>
+ */
+ public FragmentDescriptor getFragmentDescriptor(String id) {
+ FragmentDescriptor result = (FragmentDescriptor)executeUnique(ExecutionStrategy.REVERSE, new GetFragmentDescriptorOperation(id));
+ return result;
+ }
+
+ /**
+ * @see org.eclipse.gmf.runtime.common.core.service.Service#newProviderDescriptor(org.eclipse.core.runtime.IConfigurationElement)
+ */
+ protected Service.ProviderDescriptor newProviderDescriptor(IConfigurationElement element) {
+ return new ProviderDescriptor(element);
+ }
+
+ /**
+ * returns all providers for this service. This is made to overpass the visibility of the final protected method {@link Service#getAllProviders()}
+ * <P>
+ * this method should not be used at runtime, it is available only for customization purpose.
+ * </P>
+ *
+ * @return the list of all providers contributing to this service
+ */
+ public List<?> findAllProviders() {
+ return super.getAllProviders();
+ }
+
+ /**
+ * A descriptor for property views providers defined by a configuration element.
+ */
+ public static class ProviderDescriptor extends ActivityFilterProviderDescriptor {
+
+ /**
+ * Constructs a <code>ISemanticProvider</code> descriptor for
+ * the specified configuration element.
+ *
+ * @param element
+ * The configuration element describing the provider.
+ */
+ public ProviderDescriptor(IConfigurationElement element) {
+ super(element);
+ }
+
+ /**
+ * @see org.eclipse.gmf.runtime.common.core.service.IProvider#provides(org.eclipse.gmf.runtime.common.core.service.IOperation)
+ */
+ public boolean provides(IOperation operation) {
+ if(!super.provides(operation)) {
+ return false;
+ }
+ if(operation instanceof IPropertyViewOperation) {
+ // test if the configuration corresponds to the feature or the id of the operation
+ return getProvider().provides(operation);
+ }
+ return false;
+ }
+
+ /**
+ * Resets the provider
+ */
+ public void resetProvider() {
+ provider = null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public IProvider getProvider() {
+ if(provider == null) {
+ IProvider newProvider = super.getProvider();
+ if(provider instanceof IPropertyViewProvider) {
+ ((IPropertyViewProvider)newProvider).configure(getElement());
+ }
+ return newProvider;
+ }
+ return super.getProvider();
+ }
+ }
+
+ /**
+ * Returns the list of all available fragment descriptors
+ *
+ * @return the list of available fragment descriptors
+ */
+ public Map<String, FragmentDescriptor> getAllFragmentDescriptors() {
+ @SuppressWarnings("unchecked")
+ List<Map<String, FragmentDescriptor>> fragmentDescriptors = execute(ExecutionStrategy.FORWARD, new GetAllFragmentDescriptorsOperation());
+ return flattenMap(fragmentDescriptors);
+ }
+
+ /**
+ * Flattens the list, i.e. creates a list from the list of list
+ *
+ * @param <T>
+ * the type of elements in the list
+ *
+ * @param descriptors
+ * the list of list to flatten
+ * @return a flatten list of descriptors
+ */
+ public <T> List<T> flattenList(List<List<T>> descriptors) {
+ List<T> flattenList = new ArrayList<T>();
+ for(List<T> list : descriptors) {
+ flattenList.addAll(list);
+ }
+ return flattenList;
+ }
+
+ /**
+ * Flattens the list, i.e. creates a map from the list of maps
+ *
+ * @param <T>
+ * the type of the key for the map
+ * @param <V>
+ * the type of the value in the map
+ *
+ * @param descriptors
+ * the list of list to flatten
+ * @return a flatten list of descriptors
+ */
+ public <T, V> Map<T, V> flattenMap(List<Map<T, V>> descriptors) {
+ Map<T, V> flattenMap = new HashMap<T, V>();
+ for(Map<T, V> map : descriptors) {
+ flattenMap.putAll(map);
+ }
+ return flattenMap;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void preferenceChange(PreferenceChangeEvent event) {
+ if(XMLPropertyViewProvider.PROPERTY_VIEW_CUSTOMIZATIONS_ID.equals(event.getKey())) {
+ for(Object descriptor : getAllProviders()) {
+ if(descriptor instanceof ProviderDescriptor) {
+ ((ProviderDescriptor)descriptor).resetProvider();
+ }
+ }
+ providerChanged(new ProviderChangeEvent(this));
+ }
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/XMLParseException.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/XMLParseException.java
new file mode 100644
index 00000000000..0e4ea46a1d3
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/XMLParseException.java
@@ -0,0 +1,32 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view;
+
+
+/**
+ * Exception thrown when the XML parsing of the property view definition did not work correctly
+ */
+public class XMLParseException extends Exception {
+
+ /** serialVersionUID */
+ private static final long serialVersionUID = -8807648762667856170L;
+
+ /**
+ * Creates a new XMLParseException.
+ *
+ * @param message
+ * the message of the exception
+ */
+ public XMLParseException(String message) {
+ super(message);
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/XMLPropertyViewProvider.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/XMLPropertyViewProvider.java
new file mode 100644
index 00000000000..5c20c05e1c1
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/XMLPropertyViewProvider.java
@@ -0,0 +1,352 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+import javax.xml.parsers.DocumentBuilder;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.IConfigurationElement;
+import org.eclipse.core.runtime.Platform;
+import org.eclipse.gmf.runtime.common.core.service.AbstractProvider;
+import org.eclipse.gmf.runtime.common.core.service.IOperation;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.dialogs.GetDialogDescriptorOperation;
+import org.eclipse.papyrus.properties.runtime.dialogs.GetDialogDescriptorOperationById;
+import org.eclipse.papyrus.properties.runtime.view.constraints.IConstraintDescriptor;
+import org.osgi.framework.Bundle;
+import org.w3c.dom.Document;
+import org.xml.sax.SAXException;
+
+
+/**
+ * Provider for property views, using an xml view definition
+ */
+public class XMLPropertyViewProvider extends AbstractProvider implements IPropertyViewProvider {
+
+ /** attribute name for tab identifier */
+ protected static final String TAB_ID = "tabId";
+
+ /** attribute name for adapter identifier */
+ protected static final String ADAPTER_ID = "adapterId";
+
+ /** node name for sections */
+ protected static final String SECTION_NODE_NAME = "section";
+
+ /** node name for tab */
+ protected static final String NODE_NAME_TAB = "tab";
+
+ /** node name for fragment */
+ protected static final String NODE_NAME_FRAGMENT = "view";
+
+ /** node name for id */
+ protected static final String NODE_NAME_ID = "id";
+
+ /** key for the value: path to the xml file */
+ protected static final String XML_PATH = "path";
+
+ /** key for the value: property view contribution */
+ protected static final String PROPERTY_VIEW_CONTRIBUTION = "PropertyViewContribution";
+
+ /** key for the value: icon path */
+ protected static final String ICON = "icon";
+
+ /** key for the value: description */
+ protected static final String DESCRIPTION = "description";
+
+ /** key for the value: name */
+ protected static final String NAME = "name";
+
+ /** key for the id attribute */
+ protected static final String ID = "id";
+
+ /** key for the category attribute */
+ protected static final String CATEGORY = "category";
+
+ /** key for the label attribute */
+ protected static final String LABEL = "label";
+
+ /** id for the node that stores the path to the file in the memento */
+ public static final String MEMENTO_PATH = "path";
+
+ /** identifier for preferences */
+ public static final String PROPERTY_VIEW_CUSTOMIZATIONS_ID = "propertyViewCustomizations"; // //$NON-NLS-1$
+
+ /** identifier for local paths */
+ public static final String PROPERTY_VIEW_CUSTOMIZATION = "propertyViewCustomization"; // //$NON-NLS-1$;
+
+
+ /** name of the contribution */
+ protected String name;
+
+ /** id of the contribution */
+ protected String id;
+
+ /** icon of the contribution */
+ protected ImageDescriptor iconDescriptor = null;
+
+ /** description of the contribution */
+ protected String description;
+
+ /** parser for the configuration file */
+ protected PropertyViewProviderParser parser = null;
+
+ /** list of predefined fragments */
+ protected final Map<String, FragmentDescriptor> predefinedFragments = new HashMap<String, FragmentDescriptor>();
+
+ /** list of predefined dialogs */
+ protected final Map<String, DialogDescriptor> predefinedDialogs = new HashMap<String, DialogDescriptor>();
+
+ /**
+ * Returns the parser for the xml configuration file
+ *
+ * @return the parser for the xml configuration file
+ */
+ public PropertyViewProviderParser getParser() {
+ if(parser == null) {
+ parser = createParser();
+ }
+ return parser;
+ }
+
+ /**
+ * Creates the parser for the configuration file
+ *
+ * @return the parser for the configuration file
+ */
+ protected PropertyViewProviderParser createParser() {
+ return new PropertyViewProviderParser();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean provides(IOperation operation) {
+ if(operation instanceof GetFragmentDescriptorOperation) {
+ return managesFragmentDescriptor(((GetFragmentDescriptorOperation)operation).getDescriptorID());
+ } else if(operation instanceof GetDialogDescriptorOperationById) {
+ return managesDialogDescriptor(((GetDialogDescriptorOperationById)operation).getDescriptorID());
+ } else if(operation instanceof GetDialogDescriptorOperation) {
+ return true; // ?
+ } else if(operation instanceof GetAllFragmentDescriptorsOperation) {
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns the name of the contribution
+ *
+ * @return the name of the contribution
+ */
+ public String getContributionName() {
+ return name;
+ }
+
+ /**
+ * Returns the icon descriptor of the contribution
+ *
+ * @return the icon descriptor of the contribution
+ */
+ public ImageDescriptor getIconDescriptor() {
+ return iconDescriptor;
+ }
+
+ /**
+ * Returns the description of the contribution
+ *
+ * @return the description of the contribution
+ */
+ public String getDescription() {
+ return description;
+ }
+
+ /**
+ * Configures this provider, retrieving the xml file and parsing it.
+ *
+ * @param element
+ * the configuration element for this provider
+ */
+ public void configure(IConfigurationElement element) {
+ // 1. retrieve path of the xml file
+ IConfigurationElement[] children = element.getChildren();
+ Bundle bundle = Platform.getBundle(element.getContributor().getName());
+ if(bundle == null) {
+ Activator.log.warn("Ignoring extension " + element + ". Impossible to find bundle " + bundle);
+ return;
+ }
+ for(IConfigurationElement child : children) {
+ if(PROPERTY_VIEW_CONTRIBUTION.equals(child.getName())) {
+ // this is one of the configuration, parses the config itself, i.e. retrieve the xml file
+ name = child.getAttribute(NAME);
+ description = child.getAttribute(DESCRIPTION);
+ String iconPath = child.getAttribute(ICON);
+ if(iconPath != null) {
+ iconDescriptor = Activator.imageDescriptorFromPlugin(element.getContributor().getName(), iconPath);
+ }
+ DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
+ documentBuilderFactory.setNamespaceAware(true);
+ try {
+ DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
+
+ // retrieve xml file from path
+ String path = child.getAttribute(XML_PATH);
+ InputStream stream = getXmlFile(child, path, bundle);
+ // the file should never be null in this implementation, but sub-classes could return null
+ if(stream == null) {
+ throw new IOException("Impossible to load file: " + path);
+ } else {
+ Document document = documentBuilder.parse(stream);
+ getParser().parseXMLfile(document, this.predefinedFragments, this.predefinedDialogs);
+ }
+ } catch (ParserConfigurationException e) {
+ Activator.log.error(e);
+ } catch (IOException e) {
+ Activator.log.error(e);
+ } catch (SAXException e) {
+ Activator.log.error(e);
+ } catch (XMLParseException e) {
+ Activator.log.error(e);
+ }
+ }
+ }
+ }
+
+ /**
+ * Retrieves the xml file configuring the property view
+ *
+ * @param element
+ * the configuration element which gives the path to the file
+ * @param path
+ * the path for the file
+ * @param bundle
+ * the bundle used to load classes or retrieve files
+ * @return the input stream opened on the file
+ * @throws IOException
+ * exception thrown when the file is not found or can not be read
+ */
+ public InputStream getXmlFile(IConfigurationElement element, String path, Bundle bundle) throws IOException {
+ // try to read it in a plugin...
+ URL urlFile = bundle.getEntry(path);
+ urlFile = FileLocator.resolve(urlFile);
+ urlFile = FileLocator.toFileURL(urlFile);
+ if("file".equals(urlFile.getProtocol())) { //$NON-NLS-1$
+ return new FileInputStream(new File(urlFile.getFile()));
+ } else if("jar".equals(urlFile.getProtocol())) { //$NON-NLS-1$
+ String filePath = urlFile.getPath();
+ if(filePath.startsWith("file:")) {
+ // strip off the file: and the !/
+ int jarPathEndIndex = filePath.indexOf("!/");
+ if(jarPathEndIndex < 0) {
+ Activator.log.error("Impossible to find the jar path end", null);
+ return null;
+ }
+ String jarPath = filePath.substring("file:".length(), jarPathEndIndex);
+ ZipFile zipFile = new ZipFile(jarPath);
+ filePath = filePath.substring(jarPathEndIndex + 2, filePath.length());
+ ZipEntry entry = zipFile.getEntry(filePath);
+ return zipFile.getInputStream(entry);
+ // return new File(filePath);
+ }
+ }
+ return null;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public FragmentDescriptor getFragmentDescriptor(String descriptorID) {
+ return predefinedFragments.get(descriptorID);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Map<String, FragmentDescriptor> getAllFragmentDescriptors() {
+ return predefinedFragments;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean managesFragmentDescriptor(String descriptorId) {
+ return predefinedFragments.containsKey(descriptorId);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public DialogDescriptor getDialogDescriptor(String descriptorID) {
+ return predefinedDialogs.get(descriptorID);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<DialogDescriptor> getDialogDescriptor(List<Object> objectsToEdit) {
+ // iterate for each dialog on the predefined dialogs
+ List<DialogDescriptor> validDescriptors = new ArrayList<DialogDescriptor>();
+ for(DialogDescriptor descriptor : predefinedDialogs.values()) {
+ // check this dialog validity
+ // for each constraint, test if it is valid for the list of object
+ if(isValid(descriptor, objectsToEdit)) {
+ validDescriptors.add(descriptor);
+ }
+ }
+ return validDescriptors;
+ }
+
+ /**
+ * Tests if the descriptor is valid for the given list of objects
+ *
+ * @param descriptor
+ * the descriptor to test
+ * @param objectsToEdit
+ * the list of objects to display in the dialog
+ * @return <code>true</code> if the descriptors can display the list of objects to edit
+ */
+ protected boolean isValid(DialogDescriptor descriptor, List<Object> objectsToEdit) {
+ // for each object, test each constraint
+ for(IConstraintDescriptor constraintDescriptor : descriptor.getConstraintDescriptors()) {
+ for(Object objectToEdit : objectsToEdit) {
+ boolean isValid = constraintDescriptor.select(objectToEdit);
+ if(!isValid) {
+ // constraint is not valid for this object: return false
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean managesDialogDescriptor(String descriptorId) {
+ return predefinedDialogs.containsKey(descriptorId);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/constraints/AppliedStereotypeConstraintDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/constraints/AppliedStereotypeConstraintDescriptor.java
new file mode 100644
index 00000000000..76c3d972d0a
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/constraints/AppliedStereotypeConstraintDescriptor.java
@@ -0,0 +1,198 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view.constraints;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.view.IConfigurableDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.uml2.uml.Element;
+import org.eclipse.uml2.uml.Stereotype;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+/**
+ * Descriptor for constraints based on stereotype application
+ */
+public class AppliedStereotypeConstraintDescriptor implements IConstraintDescriptor, IConfigurableDescriptor {
+
+ /** list of stereotype qualified names to be applied */
+ private final List<String> stereotypeQualifiedNames;
+
+ /**
+ * Creates a new AppliedStereotypeConstraintDescriptor.
+ *
+ * @param stereotypeQualifiedNames
+ * list of stereotype qualified names to be applied
+ */
+ public AppliedStereotypeConstraintDescriptor(List<String> stereotypeQualifiedNames) {
+ this.stereotypeQualifiedNames = stereotypeQualifiedNames;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean select(Object objectToTest) {
+ // object should be a UML element
+ if(objectToTest instanceof Element) {
+ Element elementToTest = (Element)objectToTest;
+
+ // each stereotype in the list should be present
+ for(String stQualifiedName : getStereotypeQualifiedNames()) {
+ Stereotype st = elementToTest.getAppliedStereotype(stQualifiedName);
+ if(st == null) {
+ return false;
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns the list of stereotype Qualified Names
+ *
+ * @return the list of stereotype Qualified Names
+ */
+ public List<String> getStereotypeQualifiedNames() {
+ return stereotypeQualifiedNames;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "Stereotypes Constraint: " + getStereotypeQualifiedNames();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return Activator.getImage("/icons/StereotypeConstraint.gif");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public AppliedStereotypeConstraintDescriptorState createState(boolean readOnly) {
+ return new AppliedStereotypeConstraintDescriptorState(this, readOnly);
+ }
+
+ /**
+ * State for the {@link AppliedStereotypeConstraintDescriptor}, used for customization
+ */
+ public class AppliedStereotypeConstraintDescriptorState extends ConstraintDescriptorState {
+
+ /** change support for this bean */
+ private PropertyChangeSupport changeSupport;
+
+ /** list of stereotypes to be applied */
+ private List<String> stereotypesToApply = new ArrayList<String>();
+
+ /**
+ * Creates a new AppliedStereotypeConstraintDescriptorState.
+ *
+ * @param descriptor
+ * the descriptor to manage by this state
+ * @param readOnly
+ * the read only mode of this state
+ *
+ */
+ public AppliedStereotypeConstraintDescriptorState(AppliedStereotypeConstraintDescriptor descriptor, boolean readOnly) {
+ super(descriptor, readOnly);
+
+ // initialize the list of stereotypes
+ stereotypesToApply.addAll(descriptor.getStereotypeQualifiedNames());
+
+ // register change support
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ /**
+ * Returns the stereotypesToApply
+ *
+ * @return the stereotypesToApply
+ */
+ public List<String> getStereotypesToApply() {
+ return stereotypesToApply;
+ }
+
+ /**
+ * Adds a stereotype to the list of required stereotypes
+ *
+ * @param qualifiedName
+ * the qualified name of the stereotype to apply
+ */
+ public void addStereotypeToApply(String qualifiedName) {
+ stereotypesToApply.add(qualifiedName);
+
+ // fire changes event
+ changeSupport.firePropertyChange(PROPERTY_ADD_CHILD, null, stereotypesToApply);
+ }
+
+ /**
+ * Removes a stereotype from the list of required stereotypes
+ *
+ * @param qualifiedName
+ * the qualified name of the stereotype to remove
+ */
+ public void removeStereotypeToApply(String qualifiedName) {
+ stereotypesToApply.remove(qualifiedName);
+
+ // fire changes event
+ changeSupport.firePropertyChange(PROPERTY_REMOVE_CHILD, null, stereotypesToApply);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEditionDialogId() {
+ // FIXME add a configuration dialog identifier
+ return "";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node generateNode(Document document) {
+ Node node = document.createElement("appliedStereotypes");
+
+ // generate for each stereotype required
+ for(String qualifiedName : stereotypesToApply) {
+ org.w3c.dom.Element subNode = document.createElement("appliedStereotype");
+ subNode.setAttribute("qualifiedName", qualifiedName);
+ node.appendChild(subNode);
+ }
+
+ return node;
+ }
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/constraints/ConstraintDescriptorState.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/constraints/ConstraintDescriptorState.java
new file mode 100644
index 00000000000..f6a2d94c06b
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/constraints/ConstraintDescriptorState.java
@@ -0,0 +1,74 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view.constraints;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.state.AbstractState;
+import org.eclipse.papyrus.properties.runtime.state.ITraversableModelElement;
+import org.w3c.dom.Document;
+import org.w3c.dom.Node;
+
+
+/**
+ * State for Constraint Descriptors
+ */
+public abstract class ConstraintDescriptorState extends AbstractState {
+
+ /** constraint managed by this state */
+ protected IConstraintDescriptor constraintDescriptor;
+
+ /**
+ * Creates a new ConstraintDescriptorState.
+ *
+ * @param constraintDescriptor
+ * the constraint descriptor managed by this state
+ * @param readOnly
+ * the read only mode of this state
+ */
+ public ConstraintDescriptorState(IConstraintDescriptor constraintDescriptor, boolean readOnly) {
+ super(readOnly);
+ this.constraintDescriptor = constraintDescriptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public IConstraintDescriptor getDescriptor() {
+ return constraintDescriptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEditionDialogId() {
+ return "ConstraintDescriptorStateDialog";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<ITraversableModelElement> getChildren() {
+ return Collections.emptyList();
+ }
+
+ /**
+ * Serialize the configuration given by this state
+ *
+ * @param document
+ * the document used to create XML elements
+ * @return the created xml node
+ */
+ public abstract Node generateNode(Document document);
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/constraints/ConstraintParser.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/constraints/ConstraintParser.java
new file mode 100644
index 00000000000..2d3021a356f
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/constraints/ConstraintParser.java
@@ -0,0 +1,82 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view.constraints;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.osgi.framework.Bundle;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+
+/**
+ * Utility class to parse the constraint xml nodes. This has been created to provide an entry point to extension points. This class should evolve in
+ * next versions. Each constraint should provide its own parser.
+ */
+public class ConstraintParser {
+
+ /**
+ * Parses the constraint node, which gives some constraints on the descriptor that will be used.
+ *
+ * @param contextNode
+ * the xml node to parse
+ * @param bundle
+ * the bundle used to find the class loader, in case of required class loader
+ * @return the list of parsed constraints
+ */
+ public static List<IConstraintDescriptor> parseConstraints(Node contextNode, Bundle bundle) {
+ List<IConstraintDescriptor> constraintDescriptors = new ArrayList<IConstraintDescriptor>();
+ // retrieve meta class for which the fragment is valid
+ // and additional constraints (applied profiles, applied stereotypes, ocl constraints, etc)
+ NodeList children2 = contextNode.getChildNodes();
+ Class<?> elementClass = null;
+ for(int j = 0; j < children2.getLength(); j++) {
+ Node child2 = children2.item(j);
+ // check child 2 is an element class definition
+ if("elementClass".equals(child2.getNodeName())) {
+ if(child2.getAttributes() != null && child2.getAttributes().getNamedItem("name") != null) {
+ String elementClassName = child2.getAttributes().getNamedItem("name").getNodeValue();
+ // should retrieve java class corresponding to this class
+ try {
+ elementClass = bundle.loadClass(elementClassName);
+ constraintDescriptors.add(new ObjectTypeConstraintDescriptor(elementClass));
+ } catch (ClassNotFoundException e) {
+ Activator.log.error(e);
+ }
+ }
+ } else if("appliedStereotypes".equals(child2.getNodeName())) {
+ List<String> appliedStereotypeQNames = new ArrayList<String>();
+ // each child node of this node is the stereotype with qualified names
+ NodeList stereotypeNodes = child2.getChildNodes();
+ for(int i = 0; i < stereotypeNodes.getLength(); i++) {
+ Node stereotypeNode = stereotypeNodes.item(i);
+ String stereotypeNodeName = stereotypeNode.getNodeName();
+ if("appliedStereotype".equals(stereotypeNodeName)) {
+ // retrieve attribute QN
+ NamedNodeMap attributes = stereotypeNode.getAttributes();
+ if(attributes != null) {
+ Node qualifiedName = attributes.getNamedItem("qualifiedName");
+ if(qualifiedName != null) {
+ appliedStereotypeQNames.add(qualifiedName.getNodeValue());
+ }
+ }
+ }
+ }
+ constraintDescriptors.add(new AppliedStereotypeConstraintDescriptor(appliedStereotypeQNames));
+ }
+ }
+ return constraintDescriptors;
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/constraints/IConstraintDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/constraints/IConstraintDescriptor.java
new file mode 100644
index 00000000000..fc0a4b25116
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/constraints/IConstraintDescriptor.java
@@ -0,0 +1,35 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view.constraints;
+
+import org.eclipse.papyrus.properties.runtime.view.IConfigurableDescriptor;
+
+/**
+ * Descriptor for constraints on the sections
+ */
+public interface IConstraintDescriptor extends IConfigurableDescriptor {
+
+ /**
+ * Returns <code>true</code> if the constraint is valid for the given object
+ *
+ * @param objectToTest
+ * the object to test
+ * @return <code>true</code> if the constraint is valid
+ */
+ public boolean select(Object objectToTest);
+
+ /**
+ * {@inheritDoc}
+ */
+ public ConstraintDescriptorState createState(boolean readOnly);
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/constraints/ObjectTypeConstraintDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/constraints/ObjectTypeConstraintDescriptor.java
new file mode 100644
index 00000000000..1da8fa3c8de
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/constraints/ObjectTypeConstraintDescriptor.java
@@ -0,0 +1,161 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view.constraints;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.view.IConfigurableDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+/**
+ * Descriptor for a constraint based on the type of object
+ */
+public class ObjectTypeConstraintDescriptor implements IConstraintDescriptor, IConfigurableDescriptor {
+
+ /** class of the edited element */
+ protected final Class<?> elementClass;
+
+ /**
+ * Creates a new ObjectTypeConstraintDescriptor.
+ *
+ * @param elementClass
+ * class of the element to edit
+ */
+ public ObjectTypeConstraintDescriptor(Class<?> elementClass) {
+ this.elementClass = elementClass;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public boolean select(Object objectToTest) {
+ if(objectToTest == null) {
+ return false;
+ } else if((elementClass.isAssignableFrom(objectToTest.getClass()))) {
+ return true;
+ }
+ return false;
+ }
+
+
+ /**
+ * Returns the element class for this constraint descriptor, i.e the class that each object in the selection must be compliant (the same or
+ * inherited one)
+ *
+ * @return the element class for this constraint descriptor
+ */
+ public Class<?> getElementClass() {
+ return elementClass;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "Object Type Constraint: " + getElementClass().getCanonicalName();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return Activator.getImage("/icons/ObjectTypeConstraint.gif");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ConstraintDescriptorState createState(boolean readOnly) {
+ return new ObjectTypeConstraintDescriptorState(this, readOnly);
+ }
+
+ /**
+ * State for the {@link ObjectTypeConstraintDescriptor}, used for customization
+ */
+ public class ObjectTypeConstraintDescriptorState extends ConstraintDescriptorState {
+
+ /** change support for this bean */
+ private PropertyChangeSupport changeSupport;
+
+ /** class constraint */
+ private Class<?> elementClassState;
+
+ /**
+ * Creates a new ObjectTypeConstraintDescriptorState.
+ *
+ * @param objectTypeConstraintDescriptor
+ * the descriptor to manage
+ * @param readOnly
+ * the read only mode of this state
+ */
+ public ObjectTypeConstraintDescriptorState(ObjectTypeConstraintDescriptor objectTypeConstraintDescriptor, boolean readOnly) {
+ super(objectTypeConstraintDescriptor, readOnly);
+
+ elementClassState = objectTypeConstraintDescriptor.getElementClass();
+
+ // register change support
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ /**
+ * Sets the element class for the descriptor
+ *
+ * @param elementClass
+ * the element class for the descriptor
+ */
+ public void setElementClass(Class<?> elementClass) {
+ Class<?> oldClass = this.elementClassState;
+ this.elementClassState = elementClass;
+
+ changeSupport.firePropertyChange("elementClass", oldClass, this.elementClassState);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void addPropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void removePropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node generateNode(Document document) {
+ Element node = document.createElement("elementClass");
+ node.setAttribute("name", elementClassState.getName());
+ return node;
+ }
+
+ /**
+ * Returns the elementClassState
+ *
+ * @return the elementClassState
+ */
+ public Class<?> getElementClassState() {
+ return elementClassState;
+ }
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/AbstractContainerDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/AbstractContainerDescriptor.java
new file mode 100644
index 00000000000..457e6446ab5
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/AbstractContainerDescriptor.java
@@ -0,0 +1,79 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view.content;
+
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.controller.PropertyEditorController;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IPropertyEditorControllerDescriptor;
+import org.eclipse.papyrus.properties.runtime.view.IConfigurableDescriptor;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.services.IDisposable;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+import org.w3c.dom.Node;
+
+
+/**
+ * Descriptor for the containers in the section.
+ */
+public abstract class AbstractContainerDescriptor implements IDisposable, IConfigurableDescriptor {
+
+ /** layout used by this container */
+ private final LayoutDescriptor layoutDescriptor;
+
+ /** uncached content of the container */
+ protected final Node containerNode;
+
+ /**
+ * Creates a new AbstractContainerDescriptor.
+ *
+ * @param layoutDescriptor
+ * the layout of the composite described by this element
+ * @param containerNode
+ * the configuration node for this descriptor
+ */
+ public AbstractContainerDescriptor(LayoutDescriptor layoutDescriptor, Node containerNode) {
+ this.layoutDescriptor = layoutDescriptor;
+ this.containerNode = containerNode;
+ }
+
+ /**
+ * Creates the composite described by this container
+ *
+ * @param parent
+ * the composite parent of the created Composite
+ * @param tabbedPropertySheetWidgetFactory
+ * the tabbed property sheet page in which element are created
+ * @param objectsToEdit
+ * list of objects to edit
+ * @return the list of created controllers for the content of this composite
+ */
+ public abstract List<PropertyEditorController> createContent(Composite parent, TabbedPropertySheetWidgetFactory tabbedPropertySheetWidgetFactory, List<Object> objectsToEdit);
+
+
+ /**
+ * returns the list of property editor controllers contained by this container
+ *
+ * @return the list of property editor controllers contained by this container
+ */
+ public abstract List<IPropertyEditorControllerDescriptor> getControllerDescriptors();
+
+ /**
+ * Returns the layout descriptor for this container
+ *
+ * @return the layout descriptor for this container
+ */
+ public LayoutDescriptor getLayoutDescriptor() {
+ return layoutDescriptor;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/ContainerDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/ContainerDescriptor.java
new file mode 100644
index 00000000000..0bb89a54c27
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/ContainerDescriptor.java
@@ -0,0 +1,256 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view.content;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.PropertyEditorController;
+import org.eclipse.papyrus.properties.runtime.controller.PropertyEditorControllerService;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IPropertyEditorControllerDescriptor;
+import org.eclipse.papyrus.properties.runtime.controller.predefined.PredefinedPropertyControllerProvider;
+import org.eclipse.papyrus.properties.runtime.view.PropertyViewService;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+/**
+ * simple container descriptor
+ */
+public class ContainerDescriptor extends AbstractContainerDescriptor {
+
+ /** composite managed by this descriptor */
+ protected Composite describedComposite;
+
+ /** List of controllers managed in this composite */
+ protected List<PropertyEditorController> controllers = new ArrayList<PropertyEditorController>();
+
+ /** list of objects to edit */
+ protected List<Object> objectsToEdit;
+
+ /** boolean set to <code>true</code> when the content of the node has been parsed */
+ protected boolean unparsedContent = true;
+
+ /** boolean that indicates if the parsing of the content has already failed */
+ protected boolean parseFailed;
+
+ /** list of uncached Property editor controller descriptors */
+ protected List<IPropertyEditorControllerDescriptor> uncachedDescriptors;
+
+ /**
+ * Creates a new ContainerDescriptor.
+ *
+ * @param layoutDescriptor
+ * the layout of the composite described by this element
+ * @param containerNode
+ * the xml configuration node for this container
+ *
+ */
+ public ContainerDescriptor(LayoutDescriptor layoutDescriptor, Node containerNode) {
+ super(layoutDescriptor, containerNode);
+ }
+
+ /**
+ * Creates a new ContainerDescriptor.
+ *
+ * @param layoutDescriptor
+ * the layoutDescriptor of the composite described by this element
+ * @param descriptors
+ * list of controller descriptors owned by this container
+ */
+ public ContainerDescriptor(LayoutDescriptor layoutDescriptor, List<IPropertyEditorControllerDescriptor> descriptors) {
+ super(layoutDescriptor, null);
+ // force the list of descriptors, not using cache
+ uncachedDescriptors = descriptors;
+ unparsedContent = false;
+ }
+
+ /**
+ * Returns the describedComposite
+ *
+ * @return the describedComposite
+ */
+ public Composite getDescribedComposite() {
+ return describedComposite;
+ }
+
+ /**
+ * Sets the describedComposite
+ *
+ * @param describedComposite
+ * the describedComposite to set
+ */
+ public void setDescribedComposite(Composite describedComposite) {
+ this.describedComposite = describedComposite;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<PropertyEditorController> createContent(Composite parent, TabbedPropertySheetWidgetFactory widgetFactory, List<Object> objectsToEdit) {
+ this.objectsToEdit = objectsToEdit;
+ if(getDescribedComposite() == null || getDescribedComposite().isDisposed()) {
+ setDescribedComposite(widgetFactory.createComposite(parent));
+ // creates the layout
+ getDescribedComposite().setLayout(getLayoutDescriptor().createLayout());
+ getDescribedComposite().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ }
+
+ controllers = updateControllers(widgetFactory);
+ return controllers;
+ }
+
+ /**
+ * Returns the Composite containing the property editors.
+ *
+ * @return the Composite containing the property editors.
+ */
+ protected Composite getPropertyEditorContainer() {
+ return getDescribedComposite();
+ }
+
+ /**
+ * Update controllers managed by this descriptor
+ *
+ * @param widgetFactory
+ * widget factory used to create content of the editors
+ *
+ * @return the list of update controllers
+ */
+ protected List<PropertyEditorController> updateControllers(TabbedPropertySheetWidgetFactory widgetFactory) {
+ // clear and re-create the list of controllers
+ for(PropertyEditorController controller : controllers) {
+ controller.dispose();
+ }
+ controllers.clear();
+
+ // parses the property editor controller descriptors from the configuration node if required
+ if(unparsedContent) {
+ uncachedDescriptors = new ArrayList<IPropertyEditorControllerDescriptor>();
+ parseContent();
+ }
+
+ if(!parseFailed) {
+ // creates the content for the controllers
+ for(IPropertyEditorControllerDescriptor descriptor : getControllerDescriptors()) {
+ controllers.add(PropertyViewService.getInstance().createPropertyEditorController(objectsToEdit, getPropertyEditorContainer(), descriptor, widgetFactory));
+ }
+ }
+
+ return controllers;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public void dispose() {
+ for(PropertyEditorController controller : controllers) {
+ if(controller != null) {
+ controller.dispose();
+ }
+ }
+ controllers.clear();
+ if(getDescribedComposite() != null && !getDescribedComposite().isDisposed()) {
+ getDescribedComposite().dispose();
+ }
+ }
+
+ /**
+ * parses the content of the container.
+ */
+ protected void parseContent() {
+ NodeList children = containerNode.getChildNodes();
+ for(int i = 0; i < children.getLength(); i++) {
+ Node child = children.item(i);
+ if("controller".equals(child.getNodeName())) {
+ parseControllerNode(child);
+ }
+ }
+ }
+
+ /**
+ * parses the controller node
+ *
+ * @param controllerNode
+ * the node to parse
+ *
+ * @param child
+ * the controller node
+ */
+ protected void parseControllerNode(Node controllerNode) {
+ if(!controllerNode.hasAttributes()) {
+ Activator.log.error("impossible to find attributes for node " + controllerNode, null);
+ return;
+ }
+ IPropertyEditorControllerDescriptor controllerDescriptor = null;
+ // should check here if this is a predefined controller node or a locally defined one
+ Node predefinedIDNode = controllerNode.getAttributes().getNamedItem(PredefinedPropertyControllerProvider.PREDEFINED_ID);
+ if(predefinedIDNode != null) {
+ controllerDescriptor = PropertyEditorControllerService.getInstance().createPredefinedControllerDescriptor(predefinedIDNode.getNodeValue());
+ } else {
+ String controllerId = controllerNode.getAttributes().getNamedItem("id").getNodeValue();
+ controllerDescriptor = PropertyEditorControllerService.getInstance().createPropertyEditorControllerDescriptor(controllerId, controllerNode, null);
+ }
+
+ if(controllerDescriptor != null) {
+ uncachedDescriptors.add(controllerDescriptor);
+ }
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<IPropertyEditorControllerDescriptor> getControllerDescriptors() {
+ return uncachedDescriptors;
+ }
+
+ /**
+ * non optimized method to have access to all controller descriptors. It forces the parse of the content of the controller descriptors
+ *
+ * @return the parsed list of the content descriptors
+ */
+ public List<IPropertyEditorControllerDescriptor> getUnparsedControllerDescriptors() {
+ if(unparsedContent) {
+ uncachedDescriptors = new ArrayList<IPropertyEditorControllerDescriptor>();
+ parseContent();
+ }
+ return getControllerDescriptors();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "SimpleContainerDescriptor";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return Activator.getImage("/icons/Container.gif");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public ContainerDescriptorState createState(boolean readOnly) {
+ return new ContainerDescriptorState(this, readOnly);
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/ContainerDescriptorState.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/ContainerDescriptorState.java
new file mode 100644
index 00000000000..592bf2a04d6
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/ContainerDescriptorState.java
@@ -0,0 +1,219 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view.content;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.ControllerDescriptorState;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IPropertyEditorControllerDescriptor;
+import org.eclipse.papyrus.properties.runtime.state.AbstractState;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+/**
+ * State for the container descriptors. this is used to do some customization on elements
+ */
+public class ContainerDescriptorState extends AbstractState {
+
+ /** descriptor managed by this state */
+ protected AbstractContainerDescriptor descriptor;
+
+ /** list of controllers managed by this state */
+ protected final List<ControllerDescriptorState> controllerDescriptorStates = new ArrayList<ControllerDescriptorState>();
+
+ /** change support for this bean */
+ private PropertyChangeSupport changeSupport;
+
+ /** Layout descriptor state */
+ protected final LayoutDescriptorState layoutDescriptorState;
+
+ /**
+ * Creates a new ContainerDescriptorState.
+ *
+ * @param descriptor
+ * the descriptor managed by this state
+ * @param readOnly
+ * <code>true</code> if the state should be not modifiable
+ */
+ public ContainerDescriptorState(ContainerDescriptor descriptor, boolean readOnly) {
+ super(readOnly);
+ this.descriptor = descriptor;
+
+ layoutDescriptorState = descriptor.getLayoutDescriptor().createState(readOnly);
+
+ // read the current list of controller descriptor managed by this state
+ List<IPropertyEditorControllerDescriptor> controllerDescriptors = descriptor.getUnparsedControllerDescriptors();
+ for(IPropertyEditorControllerDescriptor controllerDescriptor : controllerDescriptors) {
+ controllerDescriptorStates.add(controllerDescriptor.createState(readOnly));
+ }
+
+ // register change support
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ /**
+ * Returns the descriptor described by this state
+ *
+ * @return the descriptor described by this state
+ */
+ public AbstractContainerDescriptor getDescriptor() {
+ return descriptor;
+ }
+
+ /**
+ * Returns the controllerDescriptor States for this descriptor
+ *
+ * @return the controllerDescriptor States for this descriptor
+ */
+ public List<ControllerDescriptorState> getControllerDescriptorStates() {
+ return controllerDescriptorStates;
+ }
+
+ /**
+ * Returns the layoutDescriptor state for this element
+ *
+ * @return the layoutDescriptor state for this element
+ */
+ public LayoutDescriptorState getLayoutDescriptorState() {
+ return layoutDescriptorState;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEditionDialogId() {
+ return "ContainerDescriptorStateDialog";
+ }
+
+ /**
+ * Adds a property change listener to this class
+ *
+ * @param listener
+ * the listener to add
+ */
+ public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * Removes a property change listener from this class
+ *
+ * @param listener
+ * the listener to remove
+ */
+ public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * Adds a Property editor controller state to the list of controller states owned by this Container descriptor state
+ *
+ * @param state
+ * the state to add
+ */
+ public void addPropertyEditorControllerState(ControllerDescriptorState state) {
+ controllerDescriptorStates.add(state);
+
+ changeSupport.firePropertyChange(PROPERTY_ADD_CHILD, null, controllerDescriptorStates);
+ }
+
+ /**
+ * Removes a Property editor controller state to the list of controller states owned by this Container descriptor state
+ *
+ * @param state
+ * the state to remove
+ */
+ public void removePropertyEditorControllerState(ControllerDescriptorState state) {
+ controllerDescriptorStates.remove(state);
+
+ changeSupport.firePropertyChange(PROPERTY_REMOVE_CHILD, null, controllerDescriptorStates);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<AbstractState> getChildren() {
+ ArrayList<AbstractState> states = new ArrayList<AbstractState>();
+ states.add(layoutDescriptorState);
+ states.addAll(getControllerDescriptorStates());
+ return states;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node generateNode(Document document) {
+ Element node = document.createElement("container");
+ // generate the layout descriptor node
+ generateLayoutDescriptor(node, document);
+
+ // generate for owned controllers
+ generateControllers(node, document);
+
+ return node;
+ }
+
+ /**
+ * Generates the layout descriptor node
+ *
+ * @param node
+ * the node to generate
+ * @param document
+ * the document used to create elements
+ */
+ protected void generateLayoutDescriptor(Element node, Document document) {
+ node.appendChild(getLayoutDescriptorState().generateNode(document));
+ }
+
+ /**
+ * Generate the controllers node
+ *
+ * @param node
+ * the node owner of the generated nodes
+ * @param document
+ * the document used to create elements
+ */
+ protected void generateControllers(Element node, Document document) {
+ for(ControllerDescriptorState state : getControllerDescriptorStates()) {
+ node.appendChild(state.generateNode(document));
+ }
+ }
+
+ /**
+ * Creates the preview for this state
+ *
+ * @param parent
+ * the parent for the created preview
+ * @return the created composite
+ */
+ public Composite createPreview(Composite parent) {
+ Composite composite = new TabbedPropertySheetWidgetFactory().createComposite(parent, SWT.NONE);
+ // add layout
+ composite.setLayout(layoutDescriptorState.createLayout());
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ // create the content for the controllers
+ for(ControllerDescriptorState controllerDescriptorState : controllerDescriptorStates) {
+ controllerDescriptorState.createPreview(composite);
+ }
+ return composite;
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/ExpandableContainerDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/ExpandableContainerDescriptor.java
new file mode 100644
index 00000000000..8d05553e402
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/ExpandableContainerDescriptor.java
@@ -0,0 +1,258 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view.content;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.PropertyEditorController;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.ControllerDescriptorState;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IPropertyEditorControllerDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.ui.forms.widgets.ExpandableComposite;
+import org.eclipse.ui.forms.widgets.Section;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Descriptor for the folder containers
+ */
+public class ExpandableContainerDescriptor extends ContainerDescriptor {
+
+ /** label for the folder */
+ private final String label;
+
+ /** composite content of the expandable container */
+ protected Composite expandableContainer;
+
+ /**
+ * Creates a new ExpandableContainerDescriptor
+ *
+ * @param layoutDescriptor
+ * the layoutDescriptor applied to the container
+ * @param label
+ * the label of the created composite
+ * @param containerNode
+ * the unparsed xml configuration node for this container
+ */
+ public ExpandableContainerDescriptor(LayoutDescriptor layoutDescriptor, String label, Node containerNode) {
+ super(layoutDescriptor, containerNode);
+ this.label = label;
+ }
+
+ /**
+ * Creates a new ExpandableContainerDescriptor
+ *
+ * @param layoutDescriptor
+ * the layoutDescriptor applied to the container
+ * @param label
+ * the label of the created composite
+ * @param descriptors
+ * the list of {@link IPropertyEditorControllerDescriptor} contained by this container
+ */
+ public ExpandableContainerDescriptor(LayoutDescriptor layoutDescriptor, String label, List<IPropertyEditorControllerDescriptor> descriptors) {
+ super(layoutDescriptor, descriptors);
+ this.label = label;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ExpandableComposite getDescribedComposite() {
+ return (ExpandableComposite)super.getDescribedComposite();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<PropertyEditorController> createContent(Composite parent, TabbedPropertySheetWidgetFactory widgetFactory, List<Object> objectsToEdit) {
+ this.objectsToEdit = objectsToEdit;
+ if(getDescribedComposite() == null || getDescribedComposite().isDisposed()) {
+ setDescribedComposite(widgetFactory.createSection(parent, Section.TITLE_BAR | Section.TWISTIE | Section.EXPANDED));
+ getDescribedComposite().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ expandableContainer = widgetFactory.createComposite(getDescribedComposite());
+ expandableContainer.setLayout(getLayoutDescriptor().createLayout());
+ getDescribedComposite().setText(getLabel());
+
+ widgetFactory.paintBordersFor(expandableContainer);
+ getDescribedComposite().setClient(expandableContainer);
+ }
+
+ controllers = updateControllers(widgetFactory);
+
+ return controllers;
+ }
+
+ /**
+ * Returns the Composite containing the property editors.
+ *
+ * @return the Composite containing the property editors.
+ */
+ protected Composite getPropertyEditorContainer() {
+ return expandableContainer;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "ExpandableContainerDescriptor";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return Activator.getImage("/icons/ExpandableContainer.gif");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ContainerDescriptorState createState(boolean readOnly) {
+ return new ExpandableContainerDescriptorState(this, readOnly);
+ }
+
+ /**
+ * Returns the label of the expandable composite
+ *
+ * @return the label of the expandable composite
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * State for {@link ExpandableContainerDescriptor}
+ */
+ public class ExpandableContainerDescriptorState extends ContainerDescriptorState {
+
+ /** name of the container */
+ private String name;
+
+ /** change support for this bean */
+ private PropertyChangeSupport changeSupport;
+
+ /**
+ * Creates a new ExpandableContainerDescriptorState.
+ *
+ * @param descriptor
+ * the descriptor managed by the state
+ * @param readOnly
+ * the read only mode for this state
+ */
+ public ExpandableContainerDescriptorState(ExpandableContainerDescriptor descriptor, boolean readOnly) {
+ super(descriptor, readOnly);
+
+ this.name = descriptor.getLabel();
+ // register change support
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ /**
+ * Sets the name of the expandable composite
+ *
+ * @param name
+ * the name to set
+ */
+ public void setName(String name) {
+ String oldName = this.name;
+ this.name = name;
+
+ // fire change event
+ changeSupport.firePropertyChange("name", oldName, this.name);
+ }
+
+ /**
+ * Returns the name of the expandable composite
+ *
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node generateNode(Document document) {
+ Element node = document.createElement("expandableContainer");
+ node.setAttribute("label", getName());
+
+ generateLayoutDescriptor(node, document);
+ // generate for owned controllers
+ generateControllers(node, document);
+
+ return node;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
+ super.addPropertyChangeListener(listener);
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
+ super.removePropertyChangeListener(listener);
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEditionDialogId() {
+ return "ExpandableContainerDescriptorStateDialog";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Composite createPreview(Composite parent) {
+ Group composite = new TabbedPropertySheetWidgetFactory().createGroup(parent, "Expandable > " + name);
+ // add layout
+ composite.setLayout(layoutDescriptorState.createLayout());
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ // create the content for the controllers
+ for(ControllerDescriptorState controllerDescriptorState : controllerDescriptorStates) {
+ controllerDescriptorState.createPreview(composite);
+ }
+ return composite;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "Expandable \"" + getName() + "\"";
+ }
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/GridLayoutDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/GridLayoutDescriptor.java
new file mode 100644
index 00000000000..cf36290afb0
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/GridLayoutDescriptor.java
@@ -0,0 +1,101 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view.content;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridLayout;
+
+
+/**
+ * Descriptor for GridLayout
+ */
+public class GridLayoutDescriptor extends LayoutDescriptor {
+
+ /** number of columns for the layout */
+ private final int numColumns;
+
+ /** equal columns width */
+ private final boolean sameWidth;
+
+ /**
+ * Creates a new GridLayoutDescriptor.
+ *
+ * @param numColumns
+ * the number of columns for the grid layout
+ * @param sameWidth
+ * boolean <code>true</code> when columns in the layout should have the same width
+ */
+ public GridLayoutDescriptor(int numColumns, boolean sameWidth) {
+ this.numColumns = numColumns;
+ this.sameWidth = sameWidth;
+ }
+
+ /**
+ * Creates a new GridLayoutDescriptor with default values
+ */
+ public GridLayoutDescriptor() {
+ this.numColumns = 2;
+ this.sameWidth = true;
+ }
+
+
+ /**
+ * Returns the number of columns
+ *
+ * @return the number of columns
+ */
+ public int getNumColumns() {
+ return numColumns;
+ }
+
+
+ /**
+ * Returns <code>true</code> if the columns in the layout should have the same size
+ *
+ * @return <code>true</code> if the columns in the layout should have the same size
+ */
+ public boolean isSameWidth() {
+ return sameWidth;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "GridLayout (" + numColumns + ", " + sameWidth + ")";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return Activator.getImage("/icons/GridLayout.gif");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GridLayout createLayout() {
+ return new GridLayout(numColumns, sameWidth);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public GridLayoutDescriptorState createState(boolean readOnly) {
+ return new GridLayoutDescriptorState(this, readOnly);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/GridLayoutDescriptorState.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/GridLayoutDescriptorState.java
new file mode 100644
index 00000000000..29fb79a3639
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/GridLayoutDescriptorState.java
@@ -0,0 +1,160 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view.content;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+
+import org.eclipse.swt.layout.GridLayout;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+
+/**
+ * State for {@link LayoutDescriptor}
+ */
+public class GridLayoutDescriptorState extends LayoutDescriptorState {
+
+ /** change support for this bean */
+ private PropertyChangeSupport changeSupport;
+
+ /** number of columns in the layout */
+ private int numColumns;
+
+ /** indicates if the columns should have the same width */
+ private boolean sameWidth;
+
+ /**
+ * Creates a new LayoutDescriptorState.
+ *
+ * @param layoutDescriptor
+ * managed descriptor
+ * @param readOnly
+ * the read only mode of the state
+ */
+ public GridLayoutDescriptorState(GridLayoutDescriptor layoutDescriptor, boolean readOnly) {
+ super(layoutDescriptor, readOnly);
+
+ sameWidth = layoutDescriptor.isSameWidth();
+ numColumns = layoutDescriptor.getNumColumns();
+
+ // register change support
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public GridLayoutDescriptor getDescriptor() {
+ return (GridLayoutDescriptor)super.getDescriptor();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEditionDialogId() {
+ return "GridLayoutDescriptorStateDialog";
+ }
+
+
+ /**
+ * Adds a property change listener to this class
+ *
+ * @param listener
+ * the listener to add
+ */
+ public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * Removes a property change listener from this class
+ *
+ * @param listener
+ * the listener to remove
+ */
+ public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * Sets the number of columns
+ *
+ * @param numColumns
+ * the number of columns to set
+ */
+ public void setNumColumns(int numColumns) {
+ changeSupport.firePropertyChange("numColumns", this.numColumns, this.numColumns = numColumns);
+ }
+
+ /**
+ * Returns the number of columns
+ *
+ * @return the number of columns
+ */
+ public int getNumColumns() {
+ return numColumns;
+ }
+
+ /**
+ * Sets if the columns should have the same width
+ *
+ * @param sameWidth
+ * <code>true</code> if columns should have the same width
+ */
+ public void setSameWidth(boolean sameWidth) {
+ changeSupport.firePropertyChange("sameWidth", this.sameWidth, this.sameWidth = sameWidth);
+ }
+
+ /**
+ * Returns if the columns should have the same width
+ *
+ * @return <code>true</code> if columns should have the same width
+ */
+ public boolean getSameWidth() {
+ return sameWidth;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node generateNode(Document document) {
+ Element node = document.createElement("layout");
+ node.setAttribute("kind", LayoutParser.GRID_KIND);
+ node.setAttribute("numColumns", "" + getNumColumns());
+ node.setAttribute("sameWidth", "" + getSameWidth());
+ return node;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public String getText() {
+ StringBuffer buffer = new StringBuffer();
+ buffer.append("GridLayout (");
+ buffer.append(getNumColumns());
+ buffer.append(", ");
+ buffer.append(getSameWidth());
+ buffer.append(")");
+ return buffer.toString();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public GridLayout createLayout() {
+ return new GridLayout(numColumns, sameWidth);
+ }
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/GroupContainerDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/GroupContainerDescriptor.java
new file mode 100644
index 00000000000..8ed50ae3793
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/GroupContainerDescriptor.java
@@ -0,0 +1,240 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view.content;
+
+import java.beans.PropertyChangeListener;
+import java.beans.PropertyChangeSupport;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.eclipse.papyrus.properties.runtime.controller.PropertyEditorController;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.ControllerDescriptorState;
+import org.eclipse.papyrus.properties.runtime.controller.descriptor.IPropertyEditorControllerDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Group;
+import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetWidgetFactory;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+
+/**
+ * Container descriptor for the groups
+ */
+public class GroupContainerDescriptor extends ContainerDescriptor {
+
+ /** label for the folder */
+ protected final String label;
+
+ /**
+ * Creates a new ViewConfiguration.FolderContainerDescriptor.
+ *
+ * @param layoutDescriptor
+ * the layoutDescriptor applied to the container
+ * @param label
+ * the label of the created composite
+ * @param containerNode
+ * the unparsed xml configuration node for this container
+ */
+ public GroupContainerDescriptor(LayoutDescriptor layoutDescriptor, String label, Node containerNode) {
+ super(layoutDescriptor, containerNode);
+ this.label = label;
+ }
+
+ /**
+ * Creates a new GroupContainerDescriptor
+ *
+ * @param layoutDescriptor
+ * the layoutDescriptor applied to the container
+ * @param label
+ * the label of the created composite
+ * @param descriptors
+ * the list of {@link IPropertyEditorControllerDescriptor} contained by this container
+ */
+ public GroupContainerDescriptor(LayoutDescriptor layoutDescriptor, String label, List<IPropertyEditorControllerDescriptor> descriptors) {
+ super(layoutDescriptor, descriptors);
+ this.label = label;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public Group getDescribedComposite() {
+ return (Group)super.getDescribedComposite();
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public List<PropertyEditorController> createContent(Composite parent, TabbedPropertySheetWidgetFactory widgetFactory, List<Object> objectsToEdit) {
+ this.objectsToEdit = objectsToEdit;
+ if(getDescribedComposite() == null || getDescribedComposite().isDisposed()) {
+ setDescribedComposite(widgetFactory.createGroup(parent, label));
+ getDescribedComposite().setText(label);
+ // creates the layout
+ getDescribedComposite().setLayout(getLayoutDescriptor().createLayout());
+ getDescribedComposite().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+ }
+
+ controllers = updateControllers(widgetFactory);
+
+ return controllers;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "GroupContainerDescriptor";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Image getImage() {
+ return Activator.getImage("/icons/GroupContainer.gif");
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public ContainerDescriptorState createState(boolean readOnly) {
+ return new GroupContainerDescriptorState(this, readOnly);
+ }
+
+ /**
+ * Returns the label of the expandable composite
+ *
+ * @return the label of the expandable composite
+ */
+ public String getLabel() {
+ return label;
+ }
+
+ /**
+ * State for {@link GroupContainerDescriptor}
+ */
+ public class GroupContainerDescriptorState extends ContainerDescriptorState {
+
+ /** name of the container */
+ private String name;
+
+ /** change support for this bean */
+ private PropertyChangeSupport changeSupport;
+
+ /**
+ * Creates a new ExpandableContainerDescriptorState.
+ *
+ * @param descriptor
+ * the descriptor managed by the state
+ * @param readOnly
+ * read only mode of this state
+ */
+ public GroupContainerDescriptorState(GroupContainerDescriptor descriptor, boolean readOnly) {
+ super(descriptor, readOnly);
+
+ this.name = descriptor.getLabel();
+ // register change support
+ changeSupport = new PropertyChangeSupport(this);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
+ super.addPropertyChangeListener(listener);
+ changeSupport.addPropertyChangeListener(listener);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ @Override
+ public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
+ super.removePropertyChangeListener(listener);
+ changeSupport.removePropertyChangeListener(listener);
+ }
+
+ /**
+ * Sets the name of the expandable composite
+ *
+ * @param name
+ * the name to set
+ */
+ public void setName(String name) {
+ String oldName = this.name;
+ this.name = name;
+
+ // fire change event
+ changeSupport.firePropertyChange("label", oldName, this.name);
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getText() {
+ return "Group \"" + getName() + "\"";
+ }
+
+ /**
+ * Returns the name of the expandable composite
+ *
+ * @return the name
+ */
+ public String getName() {
+ return name;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Node generateNode(Document document) {
+ Element node = document.createElement("groupContainer");
+ node.setAttribute("label", getName());
+
+ generateLayoutDescriptor(node, document);
+ // generate for owned controllers
+ generateControllers(node, document);
+
+ return node;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public String getEditionDialogId() {
+ return "GroupContainerDescriptorStateDialog";
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public Composite createPreview(Composite parent) {
+ Group composite = new TabbedPropertySheetWidgetFactory().createGroup(parent, name);
+ // add layout
+ composite.setLayout(layoutDescriptorState.createLayout());
+ composite.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+ // create the content for the controllers
+ for(ControllerDescriptorState controllerDescriptorState : controllerDescriptorStates) {
+ controllerDescriptorState.createPreview(composite);
+ }
+ return composite;
+ }
+ }
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/LayoutDescriptor.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/LayoutDescriptor.java
new file mode 100644
index 00000000000..7df94ff2daa
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/LayoutDescriptor.java
@@ -0,0 +1,34 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view.content;
+
+import org.eclipse.papyrus.properties.runtime.view.IConfigurableDescriptor;
+import org.eclipse.swt.widgets.Layout;
+
+
+/**
+ * Descriptor for layouts for containers
+ */
+public abstract class LayoutDescriptor implements IConfigurableDescriptor {
+
+ /**
+ * {@inheritDoc}
+ */
+ public abstract LayoutDescriptorState createState(boolean readOnly);
+
+ /**
+ * Creates the layout relative to this descriptor
+ *
+ * @return the layout relative to this descriptor
+ */
+ public abstract Layout createLayout();
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/LayoutDescriptorState.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/LayoutDescriptorState.java
new file mode 100644
index 00000000000..327fe71e6ef
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/LayoutDescriptorState.java
@@ -0,0 +1,64 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view.content;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.papyrus.properties.runtime.state.AbstractState;
+import org.eclipse.papyrus.properties.runtime.state.ITraversableModelElement;
+import org.eclipse.swt.widgets.Layout;
+
+
+/**
+ * State for {@link LayoutDescriptor}
+ */
+public abstract class LayoutDescriptorState extends AbstractState {
+
+ /** descriptor managed by this state */
+ private final LayoutDescriptor layoutDescriptor;
+
+ /**
+ * Creates a new LayoutDescriptorState.
+ *
+ * @param layoutDescriptor
+ * managed descriptor
+ * @param readOnly
+ * read only mode of this state
+ */
+ public LayoutDescriptorState(LayoutDescriptor layoutDescriptor, boolean readOnly) {
+ super(readOnly);
+ this.layoutDescriptor = layoutDescriptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public LayoutDescriptor getDescriptor() {
+ return layoutDescriptor;
+ }
+
+ /**
+ * {@inheritDoc}
+ */
+ public List<? extends ITraversableModelElement> getChildren() {
+ return Collections.emptyList();
+ }
+
+ /**
+ * Creates the layout for the preview
+ *
+ * @return the layout for the preview
+ */
+ public abstract Layout createLayout();
+
+}
diff --git a/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/LayoutParser.java b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/LayoutParser.java
new file mode 100644
index 00000000000..38507143b63
--- /dev/null
+++ b/plugins/views/properties/org.eclipse.papyrus.views.properties.runtime/src/org/eclipse/papyrus/properties/runtime/view/content/LayoutParser.java
@@ -0,0 +1,90 @@
+/*****************************************************************************
+ * Copyright (c) 2010 CEA LIST.
+ *
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Remi Schnekenburger (CEA LIST) remi.schnekenburger@cea.fr - Initial API and implementation
+ *****************************************************************************/
+package org.eclipse.papyrus.properties.runtime.view.content;
+
+import org.eclipse.papyrus.properties.runtime.Activator;
+import org.w3c.dom.NamedNodeMap;
+import org.w3c.dom.Node;
+
+/**
+ * Utility class to parse layouts. <BR>
+ * Nota: Entry point for future possible extension point</BR>
+ */
+public class LayoutParser {
+
+ /** kind for grid layout (default value) */
+ public static final String GRID_KIND = "Grid";
+
+ /**
+ * Parses the content of the layout node and returns the descriptor
+ *
+ * @param layoutNode
+ * the node to parse
+ * @return the created layout descriptor
+ */
+ public static LayoutDescriptor parseLayoutNode(Node layoutNode) {
+ // default layout
+ if(layoutNode == null) {
+ return new GridLayoutDescriptor();
+ }
+ String type = getType(layoutNode);
+ if(GRID_KIND.equals(type)) {
+ NamedNodeMap attributes = layoutNode.getAttributes();
+ if(attributes == null) {
+ Activator.log.warn("Impossible to parse the attribute set for grid layout: " + layoutNode);
+ return new GridLayoutDescriptor();
+ }
+
+ int numColumns = 2;
+ Node numColumnsNode = attributes.getNamedItem("numColumns");
+ if(numColumnsNode != null) {
+ try {
+ numColumns = Integer.parseInt(numColumnsNode.getNodeValue());
+ } catch (NumberFormatException e) {
+ Activator.log.error(e);
+ }
+ }
+
+ boolean sameWidth = true;
+ Node sameWidthNode = attributes.getNamedItem("sameWidth");
+ if(sameWidthNode != null) {
+ sameWidth = Boolean.parseBoolean(sameWidthNode.getNodeValue());
+ }
+
+ return new GridLayoutDescriptor(numColumns, sameWidth);
+ }
+
+ return new GridLayoutDescriptor();
+ }
+
+ /**
+ * Returns the kind of layout
+ *
+ * @param layoutNode
+ * the node to parse
+ * @return the kind of layout
+ */
+ private static String getType(Node layoutNode) {
+ NamedNodeMap attributes = layoutNode.getAttributes();
+ if(attributes == null) {
+ Activator.log.warn("Impossible to parse the attribute set for layout node: " + layoutNode);
+ return GRID_KIND;
+ }
+ Node kindNode = attributes.getNamedItem("kind");
+ if(kindNode == null) {
+ Activator.log.warn("Impossible to find the kind attribute for the layout node: " + layoutNode);
+ return GRID_KIND;
+ }
+
+ return kindNode.getNodeValue();
+ }
+}

Back to the top