Additional Indexes
Note: The API described in this document is not an official contract and may change
without preserving a backward compatibility. Such changes will be announced in advance on
MDR mailing lists.
-
Content:
-
1. Overview
-
2. Definition of Additional Indexes
-
3. Multivalues Matching
-
4. Usage - Current Status
1. Overview
Additional indexes are support for fast and convenient searching objects in
repository that match some specified attribute and association values. For
example if the user works with an instance of a metamodel defining class
'Person' that contains attribute 'Age', an additional index can be build for the
attribute allowing the user to query for all instances of Person having Age
attribute of value, e.g., 30. Indexes can be combined - defined on several
attributes and association ends.
2. Definition of Additional Indexes
Additional indexes are defined on the metamodel level using tags. Every time
a model is to be instantiated, mdr looks for these tags and builds all needed
additional indexes. Once a model is instantiated, no more indexes can be added
or removed. An additional index is defined using a tag as follows:
- tagId: Have to be of value 'org.netbeans.attributeIndex'.
- values: Should contain one value that determines the name of the
index - this name is used to refer to the index in queries.
- elements: In general, the tag is attached to several attributes,
association ends and possibly to one class (we explain this later).
Here is a definition of the index described in Overview
(expressed using XMI):
<Model:Tag xmi.id = 'tag_1' name = 'not_important' annotation = '' tagId = 'org.netbeans.attributeIndex' values =
'ByAge'>
<Model:Tag.elements>
<Model:Attribute xmi.idref =
'Attribute_Age_ref'/>
</Model:Tag.elements>
</Model:Tag>
If we have class C and association A with ends E1 and E2, where one of the
ends is of type C (e.g. E1), it is possible to build index of instances of C for
E1. Let us consider that our metamodel contains (except class Person) class 'Address'
and association 'LivesAt' linking instances of Person (first end) and Address
(second end). To build an index allowing to find all instances of Person linked
to an instance of Address, we need the following tag:
<Model:Tag xmi.id = 'tag_2' name = '' annotation = '' tagId = 'org.netbeans.attributeIndex' values =
'ByAddress'>
<Model:Tag.elements>
<Model:Attribute xmi.idref =
'LivesAt_EndPerson_ref'/>
</Model:Tag.elements>
</Model:Tag>
Moreover, we can define index on several attributes and association ends. If
the type of used elements (attributes and assoc. ends) is not the same in all cases, it
is required to attach the tag to a class that is a subtype of all the
types (let us call it base class). Instances of this class and of all its
subclasses are stored in the index. If the class is not specified the only type
determined by elements the tag is attached to is taken as the base class.
Here is an example of multiple index definition:
<Model:Tag xmi.id = 'tag_3' name = '' annotation = '' tagId = 'org.netbeans.attributeIndex' values =
'ByAgeAndAddress'>
<Model:Tag.elements>
<Model:Attribute xmi.idref =
'Attribue_Age_ref'/>
<Model:Attribute xmi.idref =
'LivesAt_EndPerson_ref'/>
<Model:Class xmi.idref =
'Class_Person_ref'/>
</Model:Tag.elements>
</Model:Tag>
The tag defines index supporting queries on instances of Person matching a
pair of values - age and address. Note that attaching to Person class was not
required in this case since both defining elements are of the same type
(Person).
Note that the definition of base class can be used to filter instances in
results of queries according to the class hierarchy. Let us suppose class
'Friend' is a subclass of Person. If we attach (e.g.) the third tag to Friend
instead of Person, the index will store instances of Friend only and queries
will return these instances only as well (even if there are some another matching
instances of Person).
3. Multivalues Matching
If an indexed attribute or association end is multivalued an object matches
to a query if the attribute's (resp. assoc. end's) value, which is a collection,
has the same elements as the related collection specified in the query.
Moreover, if the attribute (resp. assoc. end) is ordered, an object matches if
both values, which are lists, contain the same elements in the same order.
4. Usage - Current Status
For now, additional indexes support is mdr internal thing only. There are not
any related find/query methods in mdr api yet (however they are planned to be
added). Despite the internal character additional indexes can be used, but it
requires to access the mdr storagemodel layer (if you are interested in mdr
architecture, see Architecture page).
First of all, we need to obtain an instance of MdrStorage related to the
package extent we work with. It is done as follows:
import org.netbeans.handlers.*;
import org.netbeans.storagemodel.*;
MdrStorage storage = ((BaseObjectHandler) extent)._getDelegate().getMdrStorage ();
MdrStorage has method
queryAdditionalIndex(String extentMofId, String
indexName, Map values)
returning Collection of instances of
org.netbeans.storagemodel.StorableObject. Each StorableObject can be translated
to RefObject using
org.netbeans.handlers.BaseObjectHandler.getHanler(StorableBaseObject storable)
static method. The parameters of the method are as follows:
- extentMofId mof id of the outermost package, i.e. extent.refMofId()
- indexName name of the index (defined by the value of the related
tag)
- values a map containing mapping of attributes and associations
single names to queried values
If an additional index is based on one element (attribute or assoc. end),
method
getObjectsFromAdditionalIndex(String extentMofId, String indexName, Object value)
can be used as well. Here is the only value passed directly, a map is not
required.
Test for additional indexes can serve as an example:
http://mdr.netbeans.org/source/browse/mdr/test/unit/src/org/netbeans/mdr/test/AdditionalIndexTest.java
.
The used metamodel containing tags that define indexes is
http://mdr.netbeans.org/source/browse/mdr/test/unit/src/org/netbeans/mdr/test/data/IndexedModel.xml
.