Model Module

Last modified by Thomas Mortagne on 2016/09/26 16:49

shape_groupProvides an API for the XWiki Model (Wikis, Spaces, Documents, Objects, etc)
TypeJAR
Developed by

XWiki Development Team

Rating
Rate!
0 Votes
LicenseGNU Lesser General Public License 2.1
Bundled With

XWiki Enterprise

Description

The XWiki Model is made of Entities, such as:

  • A Wiki contains Spaces
  • A Space contains Documents
  • A Document contains Attachments and Objects (a.k.a XObjects), and can also contain one Class definition (XClass)
  • An Object contains Object Properties
  • A Class contain Class Properties

Entity Reference API

There are 3 concepts to understand:

  • The notion of EntityReference (or Reference for short).
    • A Reference points to an Entity from the Model (wiki, space, document, object, etc).
    • A Reference can have a parent Reference (e.g. a Document Reference's parent is a Space Reference)
    • A Reference can be absolute (i.e. all its parent references are defined till the wiki Reference) or relative.
    • To make it easy to construct References, a typed API exists. For example WikiReference, SpaceReference, DocumentReference, AttachmentReference, and more.
  • The notion of EntityReferenceResolver (Resolver for short). The goal of a Resolver is to take some input and convert it to an EntityReference instance. An example is an input defined as a String, such as wiki:space.page.
  • The notion of EntityReferenceSerializer (Serializer for short).  The goal of a Serializer is to convert an EntityReference instance into a given representation. For example a Serializer could convert a Reference into its string representation, e.g. xwiki:space.page.

Constructing an Entity Reference

Examples:

 // A Document Reference pointing to the wiki:space.page document
 DocumentReference reference = new DocumentReference("wiki", "space", "page");

 // A Document Reference pointing to the space.page document in an undefined wiki (i.e. without the wiki part)
 LocalDocumentReference reference = new LocalDocumentReference("space", "page");

 // A relative reference, specifying only a space
 EntityReference reference = new EntityReference("space", EntityType.SPACE);

 // A document reference, specified using the generic EntityReference API, defining parent references
 // The constructed reference is equivalent to: new DocumentReference("wiki", "space", "page").
 EntityReference reference = new EntityReference("page", EntityType.DOCUMENT,
     new EntityReference("space", EntityType.SPACE,
         new EntityReference("wiki", EntityType.WIKI)));

Resolving a Reference

There are 2 types of Resolvers:

  • Resolvers which take a String representing a Reference as input and convert it to an EntityReference (usually Absolute)
  • Resolvers which take an EntityReference as input and convert it to a EntityReference (usually Absolute). These Resolvers are often used to convert a relative Reference into an absolute Reference.

For both types of Resolver, there are various Resolvers that exist:

  • default Resolver(String or EntityReference input): When some reference parts are missing from the input, default values are used (see the configuration example below for default values). These default values can be configured (using the Configuration Module) to use specific default values for missing Entity parts. This is achieved by editing the xwiki.properties file. For example:
    model.reference.default.wiki = mywiki (defaults to "xwiki")
    model.reference.default.space = myspace (defaults to "Main")
    model.reference.default.document = mypage (defaults to "WebHome")
    model.reference.default.attachment = myfilename (defaults to "filename")
    model.reference.default.object = myobject (defaults to "object")
    model.reference.default.object_property = myproperty (defaults to "property")
  • current Resolver(String or EntityReference input): Uses the current Entity Reference to fill missing parts from the input (i.e. current wiki, current space, etc). If there's no current entity part then uses the default part values.
  • currentmixed Resolver(String or EntityReference input): Same as current but if the passed reference doesn't have a page name specified (or if it's empty) the value used is the default page name (instead of the page name of the current document's reference)
  • relative Resolver(String input only): Doesn't generate absolute references; simply transforms a String representation into an EntityReference instance without resolving any missing parts (space, wiki, etc).

The API to call a Resolver is:

public interface EntityReferenceResolver<T>
{
   /**
     * @param entityReferenceRepresentation the representation of an entity reference (eg as a String)
     * @param type the type of the Entity (Document, Space, Attachment, Wiki, etc) to resolve out of the representation
     * @param parameters optional parameters. Their meaning depends on the resolver implementation
     * @return the valid resolved reference as an Object
     */

    EntityReference resolve(T entityReferenceRepresentation, EntityType type, Object... parameters);
}

Note that all the Resolvers listed above will honor passing an EntityReference as parameters. If one is passed then it'll be used to resolve missing entity parts.

In addition to the Resolved listed above there's a special one:

  • explicit Resolver (String or EntityReference input): Must be called with an EntityReference parameter and this reference is used exclusively to resolve missing entity parts.

Some "typed" resolvers are also provided as helpers:

  • org.xwiki.model.reference.DocumentReferenceResolver (since 2.2M1)
  • org.xwiki.model.reference.AttachmentReferenceResolver (since 2.2M1)
  • org.xwiki.model.reference.ObjectReferenceResolver (since 2.3M1)
  • org.xwiki.model.reference.ObjectPropertyReferenceResolver (since 2.3M1)
  • org.xwiki.model.reference.SpaceReferenceResolver (since 7.2M1).

Serializing a Reference

There are various Serializers that all take an EntityReference as input and generate a String representation of it:

  • default: Prints all parts of the passed EntityReference.
  • compact: Don't print parts that are the same as either the current entity in the Execution Context or as the passed entity reference (if any). Note that the terminal part is always kept (eg the document's page for a document reference or the attachment's filename for an attachment reference).
  • compactwiki: Don't print the wiki reference part if the passed reference matches the current wiki or as the wiki of the passed entity reference (if any). The space reference and page references are always printed.
  • uid: Fast unique String reference. It's not meant to be parsed but to get a unique String for a given reference as fast as possible. It's mostly used as cache and database identifiers. Since 8.3RC1 it also support serializing the Locale part of a DocumentReference.

The API to call a Serializer is:

public interface EntityReferenceSerializer<T>
{
   /**
     * Serialize an entity reference into a new representation of type <T>.
     *
     * @param reference the reference to serialize
     * @param parameters optional parameters. Their meaning depends on the serializer implementation
     * @return the new representation (eg as a String)
     */

    T serialize(EntityReference reference, Object... parameters);
}

Reference Set

Since XWiki 5.2 org.xwiki.model.reference.EntityReferenceSet can be used to create a matcher combining included and excluded references.

The following example matches all references in the wiki:space space except the wiki:space.document document:

  EntityReferenceSet set = new EntityReferenceSet();

  set.includes(new SpaceReference("space", new WikiReference("wiki")));
  set.excludes(new DocumentReference("wiki", "space", "document"));

Reference tree

Since XWiki 5.4 org.xwiki.model.reference.EntityReferenceTree can be used to create a navigable tree of entity references.

  EntityReferenceTree tree = new EntityReferenceTree(new DocumentReference("wiki", "space", "page"), new DocumentReference("wiki", "space", "page2"));

The various References types

Document References

General string syntax: wiki:space.page

Examples of string representations:

  • Wiki:Space.Page
  • Space.Page (wiki not specified, it's a relative reference)
  • Page (wiki and space not specified, it's a relative reference)
  • My\.Page (page with a dot in the name which needs to be escaped as otherwise "My" would be considered as a space name)

API examples:

  • Generate a DocumentReference using a "current" Resolver, filling wiki and space parts with the current wiki and space:
    @Inject
    @Named("current")
    private DocumentReferenceResolver<String> resolver;
    ...
    DocumentReference reference = resolver.resolve("Page");
  • Generate a DocumentReference using a "default" Resolver, filling the wiki part with the default wiki name ("xwiki" by default but can be configured):
    @Inject
    private DocumentReferenceResolver<String> resolver;
    ...
    DocumentReference reference = resolver.resolve("Space.Page");
  • Generate a DocumentReference using a "default" Resolver, filling the space part with the default space name ("Main" by default but can be configured), and forcing the wiki part to use a fixed value if not defined:
    @Inject
    private DocumentReferenceResolver<String> resolver;
    ...
    DocumentReference reference = resolver.resolve("Page", new WikiReference("mywiki"));
  • Serialize a Document Reference into a String:
    @Inject
    private EntityReferenceSerializer<String> serializer;
    ...
    String serializer = serializer.serialize(reference);
  • Lookup the "current" Document Reference resolver (in case you can't have it injected):

    Starting with XWiki 4.0:

    DocumentReferenceResolver<String> stringResolver = componentManager.getInstance(DocumentReferenceResolver.TYPE_STRING, "current");
    DocumentReferenceResolver<EntityReference> referenceResolver = componentManager.getInstance(DocumentReferenceResolver.TYPE_REFERENCE, "current");

    Before XWiki 4.0:

    DocumentReferenceResolver<String> stringResolver = componentManager.getInstance(DocumentReferenceResolver.class, "current");
    DocumentReferenceResolver<EntityReference> referenceResolver = componentManager.getInstance(DocumentReferenceResolver.class, "current/reference");
  • Resolve the sandbox page reference and generate its string representation filling the missing wiki with the current wiki (starting with 4.0):
      DocumentReferenceResolver<String> stringResolver = componentManager.getInstance(DocumentReferenceResolver.TYPE_STRING, "current");
      EntityReferenceSerializer<String> stringSerializer = componentManager.getInstance(EntityReferenceSerializer.class);
      String sandboxName = "Sandbox.TestPage1";

      DocumentReference sandboxRef = stringResolver.resolve(sandboxName);
     // sandboxRef.getName() will give the page name TestPage1
     // sandboxRef.getParent().getName() will give the space Sandbox
     // sandboxRef.getParent().getParent().getName() will give the current wiki

     // serialize the reference:
     String sandbox = stringSerializer.serialize(sandboxRef) // will give <current_wiki>:Sandbox.TestPage1

Local Document References

Same as DocumentReference but without the wiki part.

There is no dedicated resolver, its mostly used as a helper to create a local document reference (often used for XWiki classes for example).

LocalDocumentReference reference = new LocalDocumentReference("Space", "page");

Attachment References

General string syntax: Wiki:[email protected]

Examples of string representations:

  • Wiki:[email protected]
  • [email protected] (wiki not specified, it's a relative reference)
  • [email protected] (wiki and space not specified, it's a relative reference)
  • Filename  (wiki, space, page not defined, it's a relative reference)
  • File\@name (attachment name with a '@' symbol in the name which needs to be escaped as otherwise "File" would be considered as a page name)

Object References

General string syntax: Wiki:Space.Page^Object

Examples of string representations:

  • Wiki:Space.Page^Object
  • Space.Page^Object (wiki not specified, it's a relative reference)
  • Page^Object (wiki and space not specified, it's a relative reference)
  • Object  (wiki, space, page not defined, it's a relative reference)
  • Ob\^ject (object name with a '^' symbol in the name which needs to be escaped as otherwise "Ob" would be considered as a page name)

Object Property References

General string Syntax: Wiki:Space.Page^Object.Property

Examples of string representations:

  • Wiki:Space.Page^Object.Property
  • Space.Page^Object.Property (wiki not specified, it's a relative reference)
  • Page^Object.Property (wiki and space not specified, it's a relative reference)
  • Object.Property  (wiki, space, page not defined, it's a relative reference)
  • Property  (wiki, space, page and object not defined, it's a relative reference)
  • Pro\.perty (object name with a dot in the name which needs to be escaped as otherwise "Pro" would be considered as an object name)

Class Property References

General string Syntax: Wiki:Space.Page^ClassProperty

Script Service API

Full API is available here.

Examples:

  • Create a Document Reference:
    #set ($reference = $services.model.createDocumentReference("wiki", ["space"], "page"))

    Note that prior to XWiki 7.2, the API was:

    #set ($reference = $services.model.createDocumentReference("wiki", "space", "page"))
  • Generate a string representation for the parent reference relative to the current document (example in Velocity):
    #set ($parentReference = $services.model.resolveDocument($doc.parent, 'currentmixed', $doc.documentReference))
    $services.model.serialize($parentReference)
  • Create a document reference for the Space1.Space2.WebHome page on the main wiki:
    #set ($workspaceManagerMainDocumentReference = $services.model.createDocumentReference($xcontext.mainWikiName, ['Space1', 'Space2'], 'WebHome'))
  • Create a document reference for the Space1.Space2.WebHome page on the current wiki (any param can be an empty string and in this case it'll be resolved using the current resolver):
    #set ($workspaceManagerMainDocumentReference = $services.model.createDocumentReference('', ['Space1', 'Space2'], 'WebHome'))
  • Create an Entity Reference for a document with a wiki parent specified but not space reference specified:
    #set ($ref = $services.model.createEntityReference('page', 'document', $services.model.createEntityReference('wiki', 'wiki')))
  • Since XWiki 5.4 Create an Entity Reference tree from a list of Entity References:
    #set ($ref = $services.model.toTree($references))
  • Create a reference to a sibling of the current document:
    // Solution 1 (simplest and best):
    #set ($ref = $services.model.resolveDocument('siblingpage', $doc.documentReference))
    // Solution 2:
    #set ($ref = $services.model.createEntityReference('siblingpage', 'DOCUMENT', $doc.documentReference.parent))
Tags: development
Created by Vincent Massol on 2010/05/26 16:18
    

Get Connected