STP/Policy Component/XEF Reference
XEF Reference
Contents
- 1 XEF Reference
- 1.1 Basics
- 1.2 Password fields & filters
- 1.3 Context-sensitive values
- 1.4 Subelements in <xs:sequence> and <xs:choice> groups
- 1.5 Catalogue Modifiers
- 1.6 Registering specific field editors
- 1.7 Supported XML Schema data types
The way the XEF editor renders widgets is based on the XML Schema definition of the elements and attributes. It can be influenced by putting additional information in the schema and by providing special annotations in the schema. The annotations are divided over two namespaces, xef (http://schemas.eclipse.org/stp/xsd/2006/05/xef) and xefgui (http://schemas.eclipse.org/stp/xsd/2006/05/xef/gui). The xef namespace contains information that is not purely GUI-related (e.g. it could also be used for non-gui purposes such as generating extra documentation around an element). The xefgui namespace contains purely widget-related information.
The xef and xefgui namespaces are documented in their own XML-Schema files that can be found in the following locations: [xef] [xefgui]
This page provides a reference of the various ways in which the XEF editor can be influenced.
Note that a getting started guide on the XEF editor can be found here: http://wiki.eclipse.org/STP/Policy_editor_documentation .
Basics
Category
Boolean values
Defaults
Display Name
Annotation | <xef:displayName> - String |
---|---|
Description | Provides a human readable name for the attribute or element. |
Applies to | <xs:element> and <xs:attribute> |
Before |
|
After |
|
Example |
<xs:attribute name="every_client" type="xs:boolean"> <xs:annotation> <xs:appinfo> <xef:displayName>Every Client</xef:displayName> </xs:appinfo> </xs:annotation> </xs:attribute> |
Documentation and Help
Drop-down Combo
Multi-line text
Pattern validation
Read-Only Widgets
Getting a field displayed using read-only widgets is possible in two ways:
- using the
fixed="..."
attribute in the XML Schema definition. This doesn't allow the value to be changed at all. - there is an alternative for when it's desirable that the editor doesn't change it. The use of
<xefgui:widget>read_only</xefgui:widget>
simply draws a readonly widget. In this case the value can still be changed in the underlying XML.
In both cases the way the read-only field is presented to the user is the same.
Fixing the value in the Schema
Marking the widget as Read-Only
Required text and examples
Required attributes can be marked as such in the XML Schema. The XEF editor adheres to this. Requires attributes can't have a default value. To help the user with filling in these attributes, the <xef:example> annotation can be used.
Required text field
Examples for required text fields
Spinners
Tool Tips
Units
Password fields & filters
Password fields provide a way to hide what the user types in as a password. Password filters provide a puggable way to process these passwords before they are stored in the XML.
Password Fields
Password Filters
Annotation | <xef:filter> - (filter ID) |
---|---|
Description | Password filtering allows the password entered using a password widget to be processed before it is stored in the XML file. This prevents users from seeing the actual password entered by looking at the XML source of the document being edited.
Password filters implement the package org.eclipse.stp.ui.xef.editor; public interface TextFilter { public String filter(String data); } New password filters can be provided in eclipse plugins and need to be registered through the A number of sample filters are provided with the XEF editor, e.g. <extension point="org.eclipse.stp.xef.xefExtension"> <filter class="org.eclipse.stp.ui.xef.editor.SimpleHashFilter" filterId="SimpleHashFilter"/> </extension> The There is also a |
Applies to | attributes of type <xs:string> |
Before | The password text uses the default filter to protect passwords, for a password "abcd" entered, the XML would contain the following:
<example:audit xmlns:example="http://www.example.com/xsd/2006/02/test_audit" lock_password="2987074" /> |
After | The password uses our ReverseTextFilter, which is not very secure but clearly demonstrates the filtering functionality. This filter simply reverses the string, so the XML will be:
<example:audit xmlns:example="http://www.example.com/xsd/2006/02/test_audit" lock_password="dcba" /> |
Example | <xs:attribute name="lock_password" type="xs:string"> <xs:annotation> <xs:appinfo> <xef:displayName>Lock Password</xef:displayName> <xef:filter>ReverseTextFilter</xef:filter> <xefgui:widget>password</xefgui:widget> </xs:appinfo> </xs:annotation> </xs:attribute |
Context-sensitive values
It is possible to pre-populate combo boxes with values that do not come directly from schema, but from the context of the application. To enable this functionality an IContextProvider callback object needs to be provided with the XMLProviderEditorInput. The org.eclipse.stp.ui.xef.schema.IContextProvider interface has the following api:
package org.eclipse.stp.ui.xef.schema; public interface IContextProvider { public Object getData(String ctxId); public String[] getValues(String ctxId, String ctxFilter); }
For context-sensitive values the getValues() callback will be made on this object which can then provide information from the underlying application.
As an example take the following policy schema element definition:
<xs:element name = "target"> <xs:complexType> <xs:attribute name="service" type="xs:string"> <xs:annotation> <xs:appinfo> <xefgui:context> <xefgui:values>target_service</xefgui:values> </xefgui:context> </xs:appinfo> </xs:annotation> </xs:attribute> <xs:attribute name="port" type="xs:string"> <xs:annotation> <xs:appinfo> <xefgui:context> <xefgui:values>endpoint</xefgui:values> <xefgui:dependency>@service</xefgui:dependency> </xefgui:context> <xefgui:widget>read_write</xefgui:widget> </xs:appinfo> </xs:annotation> </xs:attribute> </xs:complexType> </xs:element>
The service
attribute has as context values the identifier target_service
. This identifier is passed into the ctxId argument of the getValues() method of the IContextProvider callback to obtain the values that are possible for this attribute. The returned values will be displayed as a drop-down combo box in the editor.
The port attribute similarly has a context values identifier of endpoint
. There is another attibute here: the dependency
annotation. This defines when the values in the combo box will need to be refreshed. An XPath to another attribute can be specified. When the value of the specified attribute changes, the values in the combo box will be reloaded. When this happens, the attribute that triggered the reload is passed in as the ctxFilter
argument to the getValues()
method.
So the possible values in the port attribute change.
Note: the XPath can also reference attributes on other XML elements than the current one, in that case use a relative path to that element, e.g. ../target/@service
|
One more thing to note: the <xefgui:widget>read_write</xefgui:widget>
annotation. This causes the combo box generated to be not strict, so the user can type in values other than the ones suggested in this combo box too for the port attribute, where the service attribute is more strict and doesn't allow any other values to be specified.
My Context Provider implementation is as follows and will need to be passed as an argument to the XMLProviderEditorInput when opening the editor.
package org.eclipse.stp.ui.xef.editor; import org.eclipse.stp.ui.xef.schema.IContextProvider; public class MyContextProvider implements IContextProvider { public Object getData(String ctxId) { return null; } public String[] getValues(String ctxId, String ctxFilter) { if ("target_service".equals(ctxId)) { return new String [] {"Service 1", "Service 2"}; } else if ("Service 1".equals(ctxFilter) && "endpoint".equals(ctxId)) { return new String [] {"s1ep1", "s1ep2"}; } else if ("Service 2".equals(ctxFilter) && "endpoint".equals(ctxId)) { return new String [] {"s2ep"}; } return new String [] {}; } }This implementation will cause different port values to be displayed for
Service 1
than for Service 2
. The resulting screen looks like this:
Subelements in <xs:sequence> and <xs:choice> groups
XML Schema defined elements can have sub-elements if the element is of type xs:complexType. Currently xs:choice and xs:sequence definitions of complex types are supported.
An element having potential sub-elements is marked with a small 'plus' sign as a hint to the user that sub-elements are available.
<xs:choice>
<xs:sequence>
Sequence of <xs:any>
Catalogue Modifiers
Category
Elements inhibiting other elements
Sometimes only one element of a certain type should be allowed to be added. E.g. the XEF editor used as a policy editor should only allow one transport policy at a time. This behaviour can be achieved by specifying qualifiers. In the following example there are two policies, one for CORBA and another one for HTTP. The CORBA policy implies both a binding and a transport, where the HTTP binding only relates to the transport:
<xs:element name="corba"> <xs:annotation> <xs:appinfo> <xef:qualifier multiple="false">binding</xef:qualifier> <xef:qualifier multiple="false">transport</xef:qualifier> </xs:appinfo> </xs:annotation> </xs:element> <xs:element name="http"> <xs:annotation> <xs:appinfo> <xef:qualifier multiple="false">transport</xef:qualifier> </xs:appinfo> </xs:annotation> </xs:element>
When elements are given a qualifier with multiple="false"
multiple elements with that qualifier won't be allowed. In the example, when a document already has the HTTP policy, the CORBA policy can't be added because the transport qualifier is only allowed once:
Elements requiring other elements
Certain elements are only valid in the context of other elements. For example a HTTPS element may only make sense in the context of a HTTP element. This can be specified with the requires
annotation which takes the QName of the element that is required for the current element to be enabled:
<xs:element name="https"> <xs:annotation> <xs:appinfo> <xef:requires> <xef:element_qname>{http://www.example.com/xsd/2007/02/test_http}http</xef:element_qname> </xef:requires> </xs:appinfo> </xs:annotation> </xs:element>
Multiple requirements can be specified within a single requires section. If there are alternatives, multple requires sections can be specified. The following element requires either HTTP and SOAP or alternatively requires CORBA.
<xs:element name="some_element"> <xs:annotation> <xs:appinfo> <xef:requires> <xef:element_qname>{http://www.example.com/xsd/2007/02/test_http}http</xef:element_qname> <xef:element_qname>{http://www.example.com/xsd/2007/02/test_soap}soap</xef:element_qname> </xef:requires> <xef:requires> <xef:element_qname>{http://www.example.com/xsd/2007/05/test_corba}corba</xef:element_qname> </xef:requires> </xs:appinfo> </xs:annotation> </xs:element>
Unique Elements
By default, elements are considered to be unique, meaning that only a single instance of a given element can be added to a document. (Note: this default can be reversed by providing the POLICIES_UNIQUE Setting when opening the editor).
If a given element needs to deviate from the default, this can be specified with the unique
annotation. Consider a 'config' element that would be allowed more than once in a document while other elements, such as HTTP would only be allowed once. This can be achieved using the following schema:
<xs:element name="config"> <xs:annotation> <xs:appinfo> <xef:unique>false</xef:unique> </xs:appinfo> </xs:annotation> </xs:element>
In the following example you can see that the editor won't allow multiple HTTP policies specified, but it does allow multiple 'config' policies specified:
The <xef:unique>
annotation can take false
or true
as values and when not specified, the element will get the default behaviour for multiplicity.
Registering specific field editors
Sometimes you may have values in your XML document that require a specific field editor in order to be conveniently edited.
For example, you may have an attribute that represents a contact person for a certain entity and you'd like the users to properly fill in the first and last name of this person.
To achieve this, a custom field editor can be registered via an Extension Point. When an attribute is marked with the fieldEditor
annotation, it will get a '...' button beside it and editing is done in a dialog specifically created for this type of field.
Creating a Field Editor
First, create a dialog class that extends org.eclipse.stp.ui.xef.editor.AbstractFieldEditor
. This class will contain the actual dialog code:
package org.eclipse.stp.xef.test; import java.util.StringTokenizer; import org.eclipse.stp.ui.xef.editor.AbstractFieldEditor; import org.eclipse.swt.SWT; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.widgets.*; public class MyFieldEditor extends AbstractFieldEditor { private Text firstName; private Text lastName; private String result; public MyFieldEditor() { super(null); } protected void configureShell(Shell newShell) { super.configureShell(newShell); newShell.setText("Enter details"); } protected Control createDialogArea(Composite parent) { Composite area = (Composite) super.createDialogArea(parent); final GridLayout gridLayout = new GridLayout(); gridLayout.numColumns = 2; gridLayout.makeColumnsEqualWidth = false; area.setLayout(gridLayout); new Label(area, SWT.NONE).setText("First Name: "); firstName = new Text(area, SWT.BORDER); new Label(area, SWT.NONE).setText("Last Name: "); lastName = new Text(area, SWT.BORDER); return area; } protected void okPressed() { result = firstName.getText() + " " + lastName.getText(); super.okPressed(); } public String getFieldText() { return result; } public void setFieldText(String text) { result = text; try { StringTokenizer tok = new StringTokenizer(text); firstName.setText(tok.nextToken()); lastName.setText(tok.nextToken()); } catch (Throwable e) { } } public void setFieldData(Object data) {} }
The getFieldText()
and setFieldText()
are the interface with the outside world. setFieldText()
will be called by the framework to initialize the dialog with the current value (if any). The getFieldText()
method will be called when the framework wants to obtain the value of the field editor. Note that this method is called when the dialog is already closed, so you will have to store the result in a member variable, possibly in the okPressed()
method.
Then register the field editor with a XEF extension point, in the example below it is registered under the nameFieldEditor
ID.
<extension point="org.eclipse.stp.xef.xefExtension"> <fieldEditor class="org.eclipse.stp.xef.test.MyFieldEditor" fieldEditorId="nameFieldEditor"> </fieldEditor> </extension>
Using the Custom Field Editor
Finally, mark the attribute that requires the special Field Editor with the <xef:fieldEditor>
annotation. The field editor is referenced by ID. In the screenshot above the following attribute definition was used:
<xs:attribute name="contact_person" type="xs:string"> <xs:annotation> <xs:appinfo> <xef:fieldEditor>nameFieldEditor</xef:fieldEditor> </xs:appinfo> </xs:annotation> </xs:attribute>
Supported XML Schema data types
- xsd:boolean
- xsd:byte
- xsd:int
- xsd:integer
- xsd:long
- xsd:NCName
- xsd:negativeInteger
- xsd:nonNegativeInteger
- xsd:nonPositiveInteger
- xsd:positiveInteger
- xsd:QName - pops up a QName Field Editor
- xsd:short
- xsd:string
- xsd:unsignedByte
- xsd:unsignedInt
- xsd:unsignedShort
other schema types work too but will render as a text field.