cogAn API for accessing structured data
TypeJAR
CategoryAPI
Developed by

Yann Flory

Active Installs1
Rating
Rate!
0 Votes
LicenseGNU Lesser General Public License 2.1
Installable with the Extension Manager

Description

With this application, you can easily access the data from your application. Among the functionalities, you can easily see, modify, add or delete items of your extension.

With this extension, you are able to access data from a Script Service ($services.xapp in velocity) and using REST queries.
If you want to access the data from JavaScript code, you can also install the Structured data access JS API.

Although it is easier to use with AppWithinMinutes applications (AWM app), it can also be used with normal XWiki classes (XWiki class app).

How to use

From Velocity or Groovy

See the Movies application example to have a more complete example.

## Get the application
#set ($app = $services.xapp.current)

## Find or create an item
#set ($item = $app.getItem("foo"))

## Modify the item
$item.set('genre', 'drama')
$item.set('releaseDate', $datetool.getSystemTime())

## Create the item in the wiki/ save the modifications
$app.storeItem($item)

From REST

Main wiki data

  • GET /xwiki/rest/applications/{applicationId}
  • GET /xwiki/rest/applications/{applicationId}/items/{itemId}

Multi-wiki data

  • GET /xwiki/rest/wikis/{wikiName}/applications/{applicationId}

Available Methods

xapp.getApp 

 Parameters 

id: The application id (see Application ID structure).

 Returns An object (AWM app OR XWiki class app) containing all the methods for accessing applications data.

 Parameters 

reference: The document reference of the XWiki class.

 Returns An object (XWiki class app* only) containing all the methods for accessing applications data (see next sections).

xapp.getCurrent

 Parameters (none)
 Returns An object (AWM app only) containing all the methods for accessing applications data.
 Remarks Also work with xapp.current in Velocity.

application.getItem

 Parameters 
  • id The item id (see Item ID structure)
  • (Optional) properties: The list of properties which should be displayed in the item map. All properties are displayed by default. (e.g. {"properties" : ['item.city', 'item.product']})
 Returns An ItemMap suitable for storage using storeItem
 REST binding 
  • Request: GET /xwiki/rest/[wikis/{wikiName}/]applications/{applicationId}/items/{itemId}
  • Response: A JSON serialization of the return value + appropriate status code
 Remarks In the event that an object does not exist, an empty "new" object is returned, but not saved in the wiki until the user use storeItem

application.getItems

 Parameters 
  • (Optional) options: A map containing a set of options that can be used for customizing the items fetching. Available options are :
    • offset: The offset from where to start fetching the items (pagination)
    • limit: The number of items to be returned (pagination)
    • hidden: When set to true or 1, items in hidden documents will be displayed. They are not returned by default.
    • properties: The list of properties which should be displayed in the items maps. All properties are displayed by default. (e.g. {"properties" : ['item.city', 'item.product']})
    • query: An SQL-like "where" clause to filter on "item" properties. (e.g. where item.city = 'Paris' and item.age > 30 and item.product like 'XWiki%' order by item.city)
 Returns A map of ItemMap with the structure:
{
  "Item1ID" : {
    "prop1" : "value1-1",
    "prop2" : "value1-2"
  },
  "Item2ID": {
    "prop1" : "value2-1",
    "prop2" : "value2-2"
  }
}
 REST binding 
  • Request: GET /xwiki/rest/[wikis/{wikiName}/]applications/{applicationId}/items
    • options parameters can be individually specified as query string parameters (e.g. .../{applicationId}/items?limit=42)
  • Response: A JSON serialization of the return value + appropriate status code
 Remarks The IDs returned are formatted depending on the type of application (see Item ID structure)

application.storeItem

 Parameters 
  • itemData the ItemMap to be stored
  • (Optional) documentData the DocumentMap containing the document data (author, title, creation date, etc.)
 Returns 
  • In case of success: A map showing the success
  • In case of error: A map containing the following fields:
    • error The error description
 REST binding 
  • Request #1: PUT .../{applicationId}/items/{itemId} for item data
  • Request #2: PUT .../{applicationId}/items/{itemId}/document for document data
  • Request body: A JSON serialization of the item data map
  • Response: A JSON serialization of the return value + appropriate status code

application.deleteItem

 Parameters 
 Returns 
  • In case of success: A map showing the success
  • In case of error: A map containing the following fields:
    • error The error description
 REST binding 
  • Request: DELETE .../{applicationId}/items/{itemId}
  • Response: A JSON serialization of the return value + appropriate status code

application.getSchema

 Parameters  None
 Returns 

A map with a key for every attribute that define the application items. The value associated to each key is a map that describe the type of the corresponding attribute.

 REST binding 
  • Request #1: GET .../{applicationId}/schema
  • Request #2: GET .../{applicationId}
  • Response: A JSON serialization of the return value + appropriate status code

item.getDocumentFields()

 Parameters 
  • (Optional) properties: The list of properties which should be displayed in the document map. All properties are displayed by default. (e.g. {"properties" : ['author', 'creator']})
    • Available fields: author, creator, creationDate, updateDate, parent, hidden, title, content
 Returns 

A DocumentMap with some fields from the document where the object is located.

 REST binding 
  • Request: GET .../{applicationId}/items/{itemId}/document
  • Response: A JSON serialization of the return value + appropriate status code

Serialization

Schema serialization

{
 'name' : {
   'type': 'String'
  },
 'genre' : {
   'type': 'Enum',
   'values': ['action', 'drama', 'scifi']
  },
 'releaseDate' : {
   'type': 'Timestamp',
  }
}

Item Map

The data of an item :

{
 "name" : "foo",
 "genre" : "drama",
 "releaseDate" : "2016-01-01 00:00:00"
}

Application ID

  • AWM app : the name of the application
  • XWiki class app : the full name of the class

Item ID

  • AWM app : the page name of the item (located in the "Data" space of the application)
  • XWiki class app : id = {ItemDocumentFullName}|{ObjectNumber} where |{ObjNumber} can be omitted if the number is 0

Get Started : Movie Library Application

In this guide we'll create a basic application in which a library of movies can be stored. The Structured Data Access API will be used to get some statistic about the moview and realize some operations.

Creation of the application

First, we have to create the structure of the application using AppWithinMinutes.
The application is called "Movies", and we should add the following fields :

  • name (Short Text) : Name
  • genre (Static List) : Genre (Action, Comedy, Drama, Science-fiction, etc.)
  • releaseDate (Date) : Release Date
  • director (Short Text) : Director
  • synopsis (Long Text) : Synopsis
  • ratings (Number, Float) : Ratings
    Then, we can customize the livetable to display only the important fields : Name, Genre, Release Date, Director, Ratings, Actions, and create the application.

Now, we can add some data which we will be able to use later. Here you can add the movies you want using the application main page (Movies.WebHome).
Example :

GenreRelease DateDirectorRatings
Star Wars Episode VII: The Force AwakensScience-fictionDecember 16, 2015j. j. abrams8.4
The Hateful EightWesternDecember 25, 2015quentin qarantino8.0
The MartianScience-fictionOctober 21, 2015ridley scott8.1

Creation of the Statistics page

Now we can create a new page "Statistics" in the space "Movies".
First, we have to get the application object with Velocity :

#set ($app = $services.xapp.current) ## Since we are working in the "Movies" space, we can use ".current" to get the Movies app

Display the list of directors
To display the list of distinct directors, we need to get all the movies in the database and, for each movie, get the "director" value and store compare it with the directors already displayed :

#set ($directorsList = {}) ## Store the list of directors already displayed
#foreach ($item in $app.items)
 #set ($director = $item.director)
 #if (!$directorsList.get($director)) ## Check if the director is already displayed
    * $director
   #set ($discard = $directorsList.put($director, 1)) ## Add the director in the list to avoid duplicates
 #end
#end

Get all science-fiction movies

#foreach ($item in $app.items)
 #set ($genres = $item.genre)
 #if ($genres.contains("sci-fi")) ## Check if "sci-fi" is in the list of genres
    * $item.name
 #end
#end

Change the values of some properties

Fix a property

Now we want a script to make sure all the directors names are capitalized, and fix them if that's not the case.
We can do that in a new page called "FixProperties", using the "storeItem()" method. First, we will get the list of directors, then we will capitalize their name, and finally, we will store the new name if the objects.

#foreach ($item in $app.items) ## Get all the movies
 #set ($director = $item.director) ## Get the director
 #set($namesList = $director.split(' ')) ## Split the names to capitalize the first name and the last name
 #foreach($name in $namesList)
   #set($index = $velocityCount - 1)
   #set($namesList[$index] = $stringtool.capitalize($name))
 #end
 #set($updatedName = $stringtool.join($namesList, ' ')) ## Join the first name and the last name
 #set($discard = $item.set("director", $updatedName)) ## Change the value in the item
 #set($discard = $app.storeItem($item)) ## Store the updated "Movie" item
  * $updatedName
#end

List all the possible values for "genre"

If we have to change the genre of a movie, we have to make sure the new value exists in the static list used to represent that property. We can check the list of available values using the schema of the application:

#set ($genreValues = $app.schema.genre)
#foreach ($genre in $genreValues)
  * $genre
#end

Prerequisites & Installation Instructions

We recommend using the Extension Manager to install this extension (Make sure that the text "Installable with the Extension Manager" is displayed at the top right location on this page to know if this extension can be installed with the Extension Manager). Note that installing Extensions when being offline is currently not supported and you'd need to use some complex manual method.

You can also use the manual method which involves dropping the JAR file and all its dependencies into the WEB-INF/lib folder and restarting XWiki.

Dependencies

Dependencies for this extension (org.xwiki.contrib:api-structured-data-code 0.5):

Tags:
Created by Yann Flory on 2016/01/14 11:22
    

Get Connected