MSW Client Library Description

Contents

1. Data Model
2. User Context
2.1. Enumerating domain names
2.2. Retrieving domains by name
2.3. Creating new domains
2.4. Removing existing domains
3. Data Domains
3.1. Retrieving domain name
3.2. Retrieving items by MSWID
3.3. Retrieving items by DATAID
3.4. Searching for items using query language
3.5. Query language syntax
3.6. Creating new items
3.7. Saving items to the storage
3.8. Deleting items
4. Items
4.1. Retrieving MSWID of an item
4.2. Retrieving DATAID of an item
4.3. Retrieving item domain
4.4. Retrieving item attributes
4.5. Checking if an item is actual
4.6. Retrieving last save time of an item
5. Retrieving performance data
6. See also

1. Data Model

The data for each user is stored in the form of data domains containing an unlimited number of information units (see Fig. 1). A data domain represents a query execution context, queries across domains are not possible. Each domain has a unique string identifier. The information units are expressed as attribute-value sets with unique attribute names. Both attribute names and attribute values can be arbitrary strings.

Fig. 1. Data model.

Each information unit is uniquely identified by a unique string called DATAID identifier. At the same time, each time an information unit is modified, a new MSW structure element is created to store the updated version of the information unit. The MSW structure element containing the obsolete version of the information unit is retained for network integrity purposes (no removal procedure is currently implemented for MSW structure elements). Hence every information unit exists as a number of persistent MSW structure elements containing its actual version and previous versions. Each version of the information unit (actual or previous) is accessible by the second identifier called MSWID (also a unique string). Access by MSWID is performed directly, returning the requested information unit version in one step. At the same time, retrieval by DATAID requires searching the storage for an actual version of an information unit with the given DATAID. Only actual versions of unformation units can be retrieved by DATAID.

An information unit can be logically deleted from the storage by marking its actual version as not actual and not providing a new actual version. After this procedure, the information unit can no longer be found by its DATAID, which can be later reused. There is currently no way to retrieve previous versions of an information unit other than by MSWID . In the MSW Client Library, information unit versions are represented by items.

Fig. 2 depicts the information unit lifecycle. Black circle marks the actual version of the information unit, cross - the actual version being marked not actual without replacement. The right part of the figure indicates the Domain interface methods which control the lifecycle (see 3. Data Domains).

Fig. 2. Information unit lifecycle.

2. User Context

User context is the entry point to the the private user area of the MSW Service. The user context is represented by a UserContext interface instance obtained by calling the static method getUserContext() of UserContextFactory class. The parameters are:

  1. Filesystem path to the unpacked client distributive
  2. MSW SOAP service endpoint URL
  3. User ID
  4. Secret key
UserContext context = UserContextFactory.getUserContext("c:/mswclient",

    "https://srv.meralabs.com:8443/axis2/services/MSWService", "user_id", "secret_key");

The last three parameters are obtained during the user registration process.

The following subsections decribe the operations performed by UserContext.

2.1. Enumerating domain names

The UserContext.listDomainNames() method returns an array of existing domain names:

String[] domainNames = context.listDomainNames();

If the context contains no domains, an empty array is returned.

2.2. Retrieving domains by name

The UserContext.getDomain() method returns a Domain instance representing domain with the given name:

Domain domain = context.getDomain("myDomain");

Multiple calls produce distinct Domain instances for the same domain name. If the requested domain does not exist, this method returns null.

2.3. Creating new domains

The UserContext.createDomain() method creates a new domain and returns the Domain instance representing that domain:

Domain newDomain = context.createDomain("myNewDomain");

If the name is already in use, a ClientException is thrown.

2.4. Removing existing domains

The UserContext.hideDomain() method removes an existing domain with the given name:

context.hideDomain("myDomain");

After calling this method, the name can be used to create a new domain. Previously obtained Domain instances for the removed domain remain valid (see the next section).

3. Data Domains

Data domains are essentially sets of items. Search queries cannot involve multiple domains (each domain has its own separate MSW structure in the MSW storage).

Domains are represented by the Domain interface instances which are retrieved by name using the UserContext.getDomain() method. The same domain can be represented by multiple Domain instances.

At the SOAP interface level, the domains are represented by persistent unique ids rather than by names. These ids are stored in Domain instances. A map of domain names to do domain ids is stored for each user, allowing domain retrieval by name. When a domain is removed, the name-to-id mapping is terminated while anything else remains intact. This allows to continue using the previously obtained (possibly by different client) Domain instances and possibly restore the removed domain.

The following subsections describe the operations available for the Domain interface.

3.1. Retrieving domain name

The Domain.getName() method retrieves the domain name:

String name = domain.getName();

3.2. Retrieving items by MSWID

The Domain.getItemByMswId() method retrieves the item by MSWID:

Item item = domain.getItemByMswId("http://www.meralabs.com/item/84029842094");

Every call of this method produces a new Item instance for the same MSWID. If no item with the given MSWID exists the method returns null. Non-actual versions of information units may be obtained by this method.

3.3. Retrieving items by DATAID

The Domain.getItemByDataID() the actual version of the information unit by its DATAID:

Item item = domain.getItemByDataId("c9615ffd-1e33-4e4c-b750-98d60ec8b537");

If no actual version exists for the information unit with the given DATAID this method returns null. Every call produces a new Item instance for the same DATAID.

3.4. Searching for items using query language

The Domain.execQuery() method searches for items using query language and returns an array of items matching the query:

Item[] results = domain.execQuery("GET [a] > '5'");

Only actual versions of information units appear in search results. If no items were found, an empty array is returned.

3.5. Query language syntax

The query string consists of the following parts:

GET <conditions> <results limit> <time limit>
  1. The search criteria are expressed by a set of comparison operations of attributes and literal values joined by logical operations. Use round parentheses to override the priority of logical operations.
  2. Maximum number of results (results limit) is expressed as "MAXRESULTS x" where x is a positive integer denoting the maximum number of obtained results after which the search stops. If this condition is omitted or exceeds the internal MSW platform limits, the number of results is limited by the internal MSW platform limits.
  3. Maximum search time (time limit) is expressed as "MAXTIME x" where x is a positive integer which denotes the maximum query execution time in milliseconds. When the time limit is reached, currently obtained results are returned. The actual execution time may exceed the limit due to internal implementation features. If this parameter is omitted or exceeds the internal MSW platform limit, execution time is limited by the internal MSW platform limit.

Formal query language definition in EBNF form:

query ::= 'GET' S ('*' S)? conditionExp (S resultLimit)? (S timeLimit)?
conditionExp ::= logicalValue
attributeRef ::= '['escapedName']'
attributeValue ::= "'" escapedValue "'" | '"' escapedValue '"'
escapedName ::= ? escaped attribute name string (see below) ?
escapedValue ::= ? escaped attribute value string (see below) ?
comparisonOp ::= '=' | '<>' | '<' | '>' | '<=' | '>='
comparisonExp ::= attributeRef S? comparisonOp S? attributeValue
logicalValue ::= logicalExp | comparisonExp | '(' logicalValue ')'
logicalExp ::= 'not' S? logicalValue | logicalValue S? ('and' | 'or') S? logicalValue
resultLimit ::= 'MAXRESULTS' S positiveInteger
timetLimit ::= 'MAXTIME' S positiveInteger
positiveInteger ::= '0'* [1-9] [0-9]*
S ::= (#x20 | #x9 | #xD | #xA)+

Attribute names are enclosed by square parentheses ([name]). Attribute values are enclosed by either single or double quotes ('value' or "value"). The following escaping rules apply to attribute names and values.

Attribute names:

Character Escape sequence
[ /[
] /]
/ //

Attribute values:

Character Escape sequence
' /'
" /"
/ //

The comparison operations imply the lexicographical order of case-sensitive string values. If the attribute values have other semantics they must be converted to a form where their natural order corresponds to the lexicographical order of their string representations.

Operation precedence:

  1. =, <>, >, <, >=, <=
  2. not
  3. and
  4. or

Query examples:

GET [color] = "red" and [weight] > "009" MAXRESULTS 10

Return no more than 10 information units with the color attribute value equal to "red" and the weight attribute value lexicographically following "009".

GET * [price] <= '1500' and ([manufacturer] = 'IBM' or [manufacturer] = 'Sony') MAXTIME 2000

Return information units with price attribute equal or lexicographically preceding "1500" and manufacturer parameter equal to "IBM" or "Sony". The query execution time limit is two seconds.

3.6. Creating new items

The Domain.createNewItem() method creates a new item in memory without transferring it to the storage:

Item newItem = domain.createNewItem(dataId);

The created Item instance is initialized as follows:

  1. MSWID has null value.
  2. DATAID receives the dataId parameter value, or an autogenerated unique value if dataId is null.
  3. Attribute map is empty.
  4. The Item instance is marked as not actual.
  5. Last commit date is null.

To save the created item to the storage, use the Domain.commitItem() method.

3.7. Saving items to the storage

The Domain.commitItem method saves the item to the storage:

domain.commitItem(item);

The Item instance passed to this method must be obtained from the same domain to which it is saved.

The state of the item is saved to the storage as the actual information unit version for item's DATAID. If the storage already contains an actual information unit version with the same DATAID, this existing version becomes not actual.

The contents of the item is modified in the following way:

  1. MSWID is replaced with the MSWID value of the new actual information unit version.
  2. The item is marked as actual.
  3. The last commit time is updated.

3.8. Deleting items

The Domain.deleteItem() method deletes an item from the storage:

domain.deleteItem(item);

The Item instance passed to this method must be obtained from the same domain to which it is saved.

The information unit version represented by the item (i.e. having the item's MSWID) becomes marked as not actual in the storage. The item is also marked as not actual.

4. Items

Item interface instances represent information unit versions. Item instances are obtained and updated via Domain class methods.

4.1. Retrieving MSWID of an item

The Item.getMswId() method returns the MSWID of the item:

String mswid = item.getMswId();

For new items created by Domain.createNewItem() this method returns null.

4.2. Retrieving DATAID of an item

The Item.getDataId() method returns the DATAID of the item:

String dataid = item.getDataId();

4.3. Retrieving item domain

The Item.getDomain method returns the domain to which the item belongs:

Domain domain = item.getDomain();

4.4. Retrieving item attributes

The Item.getAttributes() method returns a mutable Map instance containing item's attributes:

Map attributes = item.getAttributes();

For a given Item instance, the same Map instance is returned by multiple calls to getAttributes(). The returned Map instance is not synchronized so explicit synchronization is required in case of multithreaded access.

4.5. Checking if an item is actual

The Item.isActual() method checks if the item is actual.

boolean actual = item.isActual();

This method returns true if the item represented the actual version of an information unit when it was last updated from the storage. For items created by Domain.createNewItem() this method returns false.

4.6. Retrieving last save time of an item

The Item.getCommitTime() method returns the last date and time when the item was saved to the storage:

Date commitTime = item.getCommitTime();

If the item has never been passed to Domain.commitItem(), this method returns null.

5. Retrieving performance data

During request execution the server collects performance data and transmits it to the client in the form of attribute name-value map. On the client side, this map is stored as a thread-local variable which contains the performance data map for the last request executed by the thread.

To obtain this map, use the PerformanceData.getPerformanceData() method:

Item[] results = domain.execQuery("GET [a] > '003'");

Map<String, String> perfData = PerformanceData.getPerformanceData();

If the thread hasn't executed any request, this methods returns null.

The following table contains currently implemented performace attributes:

Attribute nameMeaning
serviceNanosRequest execution time on server side, nanoseconds

6. See also

Client library javadoc