 | Provides an API for the XWiki Model (Wikis, Spaces, Documents, Objects, etc) |
| Bundled With | XWiki Enterprise, XWiki Enterprise Manager |
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
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.
Examples:
// A Document Reference pointing to the wiki:space.page document
DocumentReference reference = new DocumentReference("wiki", "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)));
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 than 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.
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.
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);
}
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 4.0
DocumentReferenceResolver<String> stringResolver = componentManager.getInstance(DocumentReferenceResolver.TYPE_STRING, "current");
DocumentReferenceResolver<EntityReference> referenceResolver = componentManager.getInstance(DocumentReferenceResolver.TYPE_REFERENCE, "current");
Before 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
General string syntax: Wiki:Space.Page@Filename
Examples of string representations:
- Wiki:Space.Page@Filename
- Space.Page@Filename (wiki not specified, it's a relative reference)
- Page@Filename (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)
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)
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)
Full API is available here.
Examples:
- 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 workspace manager on the XEM main wiki:
#set ($workspaceManagerMainDocumentReference = $services.model.createDocumentReference($xcontext.mainWikiName, 'WorkspaceManager', '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')))