Customizing Properties View

The Properties View is used to edit the attributes of the DevOps Modeling Platform elements selected in the Project Explorer or in diagrams. It is made of a single properties sheet that is broken down into 3 components.

  1. categories - categories are used to group tabs and are defined against a contributor Id
  2. tabs - tabs are added to categories
  3. sections - sections are added to tabs

The properties sheet, as well as each of the above components, have their own extension-point. It is possible to add tabs and sections to the properties sheet used by RMP UML Modeler. Alternatively, the user may also wish to create brand new property sheets for their own custom domains.

Contributing to the UML Modeler Properties Sheet

UML modeler defines serveral categories, tabs and sections for the com.ibm.xtools.modeler.ui.properties contributor ID.

The following example will describe how to contribute a new tab and section to modify a Stereotype attribute. The tab will only become visible upon selecting an element with the expected applied Stereotype.

This example assumes that a profile named MyProfile with a stereotype, MyStereotype, and attribute, myAttribute, exists. The attribute is of type String.

The first step is to specify the property tab within the new property category by extending the propertyTabs extension-point and set the contributorId to com.ibm.xtools.modeler.ui.properties.

Set the category to be one of the pre-defined categories from modeler:

   <extension point="org.eclipse.ui.views.properties.tabbed.propertyTabs">
      <propertyTabs contributorId="com.ibm.xtools.modeler.ui.properties">
         <propertyTab
            label="My Tab 1"
            category="Core"
            id="com.ibm.examples.properties.tab1"/> 
      </propertyTabs>
   </extension>

Next, extend the org.eclipse.ui.views.properties.tabbed.propertySections extension-point to create a section.

   <extension point="org.eclipse.ui.views.properties.tabbed.propertySections">
      <propertySections contributorId="com.ibm.xtools.modeler.ui.properties">
         <propertySection
               class="com.ibm.examples.properties.sections.MyPropertySection"
               tab="com.ibm.examples.properties.tab1"
               filter="com.ibm.examples.properties.filters.MyPropertyFilter"
               id="com.ibm.examples.properties.section1">
         </propertySection>
      </propertySections>
   </extension>

The filter implementation is as follows. It will check if the selected object is adaptable to an instance of Element, and then return true if the expected Stereotype is applied.

public class MyPropertySectionFilter implements IFilter {

    public boolean select(Object toTest) {
        EObject eObject = null;
        if (toTest instanceof IAdaptable) {
            eObject = (EObject)((IAdaptable)toTest).getAdapter(EObject.class);
        } else if (toTest instanceof EObject) {
            eObject = (EObject)toTest;
        }
        if (eObject != null) {
            return eObject instanceof Element &&
                ((Element)eObject).getAppliedStereotype("MyProfile::MyStereotype") != null;
        }
        return false;
    }
}

The final step is to create the property sections which implements ISection.

GMF provides some abstract implementations of ISection:

Since "myAttribute" is of type String, create a class which extends org.eclipse.gmf.runtime.diagram.ui.properties.sections.AbstractBasicTextPropertySection. When extending the AbstractBasicTextPropertySection class, only 4 methods need to be implemented.

public class MyPropertySection extends AbstractBasicTextPropertySection {

    /**
     * Return the name of the command which will be executed to set the property.
     */
    protected String getPropertyChangeCommandName() {
        return "Set My Attribute";
    }

    /**
     * Return the name of the property to place in the label widget.
     */
    protected String getPropertyNameLabel() {
        return "My Attribute";
    }

    /**
     * Return the string representation of the property value.
     */
    protected String getPropertyValueString() {
        Element element = (Element)getEObject();
        Stereotype stereotype = element.getAppliedStereotype("MyProfile::MyStereotype");
        EObject account = element.getStereotypeApplication(stereotype);
        EStructuralFeature idFeature = account.eClass().getEStructuralFeature("myAttribute");
        String id = (String)account.eGet(idFeature);
        return id == null ? StringStatics.BLANK : id;
    }

    /**
     * Set property value for the given object.
     */
    protected void setPropertyValue(EObject object, Object value) {
        Element element = (Element)getEObject();
        Stereotype stereotype = element.getAppliedStereotype("MyProfile::MyStereotype");
        EObject account = element.getStereotypeApplication(stereotype);
        EStructuralFeature idFeature = account.eClass().getEStructuralFeature("myAttribute");
        account.eSet(idFeature, value);
    }
}

The resulting properties sheet:

Creating a Custom Property Sheet

The previous section showed how to add property tabs and sections to UML Modeler. However, if you have defined your own domain elements, editors or views, a few additionals steps are required in order to provide tabbed properties for them.

For example, let's say you have defined your domain model using EMF, and have generated diagramming support for it using GMF. Before defining properties for individual elements on the diagram, implement the interface ITabbedPropertySheetPageContributor to your diagram editor.

The ITabbedPropertySheetPageContributor has one method called getContributorId() that needs to be implemented. This method allows a workbench element to select what kind of properties are applicable for it. The tabbed properties framework then uses all the applicable contributions against this contributor ID. For example:

	public class MyDiagramEditor extends DiagramEditor 
		implements ITabbedPropertySheetPageContributor {
		
		public String getContributorId() {
			return "com.ibm.examples.properties";
		}
		
		...
	}

With the above code, the tabbed properties framework will collect all property categories, tabs and sections defined with the contributor ID "com.ibm.examples.properties" and display them as applicable.

Now we need to define the actual property contributions. Start by extending the org.eclipse.ui.views.properties.tabbed.propertyContributor extension-point to create categories.

   <extension point="org.eclipse.ui.views.properties.tabbed.propertyContributor">
      <propertyContributor
            contributorId="com.ibm.examples.properties"
            labelProvider="com.ibm.examples.properties.MyLabelProvider"
            actionProvider="com.ibm.examples.properties.MyActionProvider"
            typeMapper="com.ibm.examples.properties.MyTypeMapper">
         <propertyCategory category="category1"/>
      </propertyContributor>
   </extension>

Next, extend the org.eclipse.ui.views.properties.tabbed.propertyTabs extension-point to create tabs.

   <extension point="org.eclipse.ui.views.properties.tabbed.propertyTabs">
      <propertyTabs contributorId="com.ibm.examples.properties">
         <propertyTab
            label="My Tab 1"
            category="category1"
            id="com.ibm.examples.properties.tab1"/> 
      </propertyTabs>
   </extension>

Next, extend the org.eclipse.ui.views.properties.tabbed.propertySections extension-point to create sections.

   <extension point="org.eclipse.ui.views.properties.tabbed.propertySections">
      <propertySections contributorId="com.ibm.examples.properties">
         <propertySection
               class="com.ibm.examples.properties.sections.MyPropertySection"
               tab="com.ibm.examples.properties.tab1"
               filter="com.ibm.examples.properties.filters.MyPropertyFilter"
               id="com.ibm.examples.properties.section1"
               enablesFor="1">
         </propertySection>
      </propertySections>
   </extension>

The filter class is optional and is queried whenever a new selection is made. Simply return true if the selected element is a valid selection for the property section. In this example, the filter will return true if the object to test is an EObject or adaptable to an EObject.

public class MyPropertySectionFilter implements IFilter {

    public boolean select(Object toTest) {
        EObject eObject = null;
        if (toTest instanceof IAdaptable) {
            eObject = (EObject)((IAdaptable)toTest).getAdapter(EObject.class);
        } else if (toTest instanceof EObject) {
            eObject = (EObject)toTest;
        }
        if (eObject != null) {
            return true;
        }
        return false;
    }
}

The final step is to create the property sections which implements ISection. Extend one of the abstract implementations provided by GMF.


Legal notices