/*
* See the NOTICE file distributed with this work for additional
* information regarding copyright ownership.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package com.xpn.xwiki.api;
import java.io.IOException;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xwiki.component.manager.ComponentLookupException;
import org.xwiki.job.Job;
import org.xwiki.job.event.status.JobStatus;
import org.xwiki.job.event.status.JobStatus.State;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.model.reference.DocumentReferenceResolver;
import org.xwiki.model.reference.EntityReference;
import org.xwiki.model.reference.EntityReferenceSerializer;
import org.xwiki.model.reference.SpaceReference;
import org.xwiki.model.reference.WikiReference;
import org.xwiki.rendering.renderer.PrintRendererFactory;
import org.xwiki.rendering.syntax.Syntax;
import com.xpn.xwiki.XWikiContext;
import com.xpn.xwiki.XWikiException;
import com.xpn.xwiki.doc.XWikiDeletedDocument;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.internal.XWikiInitializerJob;
import com.xpn.xwiki.internal.XWikiInitializerJobStatus;
import com.xpn.xwiki.objects.meta.MetaClass;
import com.xpn.xwiki.user.api.XWikiUser;
import com.xpn.xwiki.util.Programming;
import com.xpn.xwiki.web.Utils;
import com.xpn.xwiki.web.XWikiEngineContext;
import com.xpn.xwiki.web.XWikiURLFactory;
public class XWiki extends Api
{
/** Logging helper object. */
protected static final Logger LOGGER = LoggerFactory.getLogger(XWiki.class);
/** The internal object wrapped by this API. */
private com.xpn.xwiki.XWiki xwiki;
/**
* @see #getStatsService()
*/
private StatsService statsService;
/**
* @see #getCriteriaService()
*/
private CriteriaService criteriaService;
/**
* @see com.xpn.xwiki.internal.model.reference.CurrentMixedStringDocumentReferenceResolver
*/
private DocumentReferenceResolver<String> currentMixedDocumentReferenceResolver;
/**
* @see org.xwiki.model.internal.reference.DefaultStringDocumentReferenceResolver
*/
private DocumentReferenceResolver<String> defaultDocumentReferenceResolver;
/**
* The object used to serialize entity references into strings. We need it because we have script APIs that work
* with entity references but have to call older, often internal, methods that still use string references.
*/
private EntityReferenceSerializer<String> defaultStringEntityReferenceSerializer;
private DocumentReferenceResolver<EntityReference> currentgetdocumentResolver;
/**
* XWiki API Constructor
*
* @param xwiki XWiki Main Object to wrap
* @param context XWikiContext to wrap
*/
public XWiki(com.xpn.xwiki.XWiki xwiki, XWikiContext context)
{
super(context);
this.xwiki = xwiki;
this.statsService = new StatsService(context);
this.criteriaService = new CriteriaService(context);
}
private DocumentReferenceResolver<String> getCurrentMixedDocumentReferenceResolver()
{
if (this.currentMixedDocumentReferenceResolver == null) {
this.currentMixedDocumentReferenceResolver =
Utils.getComponent(DocumentReferenceResolver.TYPE_STRING, "currentmixed");
}
return this.currentMixedDocumentReferenceResolver;
}
private DocumentReferenceResolver<EntityReference> getCurrentgetdocumentResolver()
{
if (this.currentgetdocumentResolver == null) {
this.currentgetdocumentResolver =
Utils.getComponent(DocumentReferenceResolver.TYPE_REFERENCE, "currentgetdocument");
}
return this.currentgetdocumentResolver;
}
private DocumentReferenceResolver<String> getDefaultDocumentReferenceResolver()
{
if (this.defaultDocumentReferenceResolver == null) {
this.defaultDocumentReferenceResolver = Utils.getComponent(DocumentReferenceResolver.TYPE_STRING);
}
return this.defaultDocumentReferenceResolver;
}
private EntityReferenceSerializer<String> getDefaultStringEntityReferenceSerializer()
{
if (this.defaultStringEntityReferenceSerializer == null) {
this.defaultStringEntityReferenceSerializer = Utils.getComponent(EntityReferenceSerializer.TYPE_STRING);
}
return this.defaultStringEntityReferenceSerializer;
}
/**
* Privileged API allowing to access the underlying main XWiki Object
*
* @return Privileged Main XWiki Object
*/
@Programming
public com.xpn.xwiki.XWiki getXWiki()
{
if (hasProgrammingRights()) {
return this.xwiki;
}
return null;
}
/**
* @return the status of the job initializing {@link com.xpn.xwiki.XWiki} instance
* @since 6.1M1
*/
public XWikiInitializerJobStatus getJobStatus()
{
XWikiInitializerJob job = Utils.getComponent((Type) Job.class, XWikiInitializerJob.JOBTYPE);
return job != null ? job.getStatus() : null;
}
/**
* @return the status of the job initializing the instance or the current wiki
* @since 8.4RC1
*/
public JobStatus getCurrentInitializerJobStatus()
{
// Get XWiki initializer job
JobStatus jobStatus = getJobStatus();
if (jobStatus == null) {
return null;
}
// The XWiki initialization is not done yet
if (jobStatus.getState() != State.FINISHED) {
return jobStatus;
}
// If XWiki initialization did not failed
if (this.xwiki != null) {
// Get current wiki initializer job
Job wikiJob = this.xwiki.getWikiInitializerJob(this.context.getWikiId());
jobStatus = wikiJob != null ? wikiJob.getStatus() : null;
}
return jobStatus;
}
/**
* @return XWiki's version in the format <code>(version).(SVN build number)</code>, or "Unknown version" if it
* failed to be retrieved
*/
public String getVersion()
{
return this.xwiki.getVersion();
}
/**
* API Allowing to access the current request URL being requested.
*
* @return the URL
* @throws XWikiException failed to create the URL
*/
public String getRequestURL() throws XWikiException
{
return getXWikiContext().getURLFactory().getRequestURL(getXWikiContext()).toString();
}
/**
* API Allowing to access the current request URL being requested as a relative URL.
*
* @return the URL
* @throws XWikiException failed to create the URL
* @since 4.0M1
*/
public String getRelativeRequestURL() throws XWikiException
{
XWikiURLFactory urlFactory = getXWikiContext().getURLFactory();
return urlFactory.getURL(urlFactory.getRequestURL(getXWikiContext()), getXWikiContext());
}
/**
* Loads an Document from the database. Rights are checked before sending back the document.
*
* @param fullName the full name of the XWiki document to be loaded
* @return a Document object (if the document couldn't be found a new one is created in memory - but not saved, you
* can check whether it's a new document or not by using {@link com.xpn.xwiki.api.Document#isNew()}
* @throws XWikiException
*/
public Document getDocument(String fullName) throws XWikiException
{
DocumentReference reference;
// We ignore the passed full name if it's null to be backward compatible with previous behaviors.
if (fullName != null) {
// Note: We use the CurrentMixed Resolver since we want to use the default page name if the page isn't
// specified in the passed string, rather than use the current document's page name.
reference = getCurrentMixedDocumentReferenceResolver().resolve(fullName);
} else {
reference = getDefaultDocumentReferenceResolver().resolve("");
}
return getDocument(reference);
}
/**
* Loads a Document from the database. Rights are checked before sending back the document.
*
* @param reference the reference of the XWiki document to be loaded
* @return a Document object (if the document couldn't be found a new one is created in memory - but not saved, you
* can check whether it's a new document or not by using {@link com.xpn.xwiki.api.Document#isNew()}
* @throws XWikiException
* @since 2.3M1
*/
public Document getDocument(DocumentReference reference) throws XWikiException
{
try {
XWikiDocument doc = this.xwiki.getDocument(reference, getXWikiContext());
if (this.xwiki.getRightService().hasAccessLevel("view", getXWikiContext().getUser(),
doc.getPrefixedFullName(), getXWikiContext()) == false) {
return null;
}
return doc.newDocument(getXWikiContext());
} catch (Exception ex) {
LOGGER.warn("Failed to access document " + reference + ": " + ex.getMessage());
return new Document(new XWikiDocument(reference), getXWikiContext());
}
}
/**
* Loads a Document from the store. Rights are checked before sending back the document.
* <p>
* The passed reference can be anything. If if a document child, the document reference will be extracted from it.
* If it's a document parent it will be completed with the necessary default references (for example if it's a space
* reference it will load the space home page).
*
* @param reference the reference close to the XWiki document to be loaded
* @return a Document object (if the document couldn't be found a new one is created in memory - but not saved, you
* can check whether it's a new document or not by using {@link com.xpn.xwiki.api.Document#isNew()}
* @throws XWikiException
* @since 7.1M2
*/
public Document getDocument(EntityReference reference) throws XWikiException
{
return getDocument(getCurrentgetdocumentResolver().resolve(reference));
}
/**
* Loads an Document from the database. Rights are checked on the author (contentAuthor) of the document containing
* the currently executing script before sending back the loaded document.
*
* @param fullName the full name of the XWiki document to be loaded
* @return a Document object (if the document couldn't be found a new one is created in memory - but not saved, you
* can check whether it's a new document or not by using {@link com.xpn.xwiki.api.Document#isNew()}
* @throws XWikiException
* @since 2.3M2
*/
public Document getDocumentAsAuthor(String fullName) throws XWikiException
{
DocumentReference reference;
// We ignore the passed full name if it's null to match behavior of getDocument
if (fullName != null) {
// Note: We use the CurrentMixed Resolver since we want to use the default page name if the page isn't
// specified in the passed string, rather than use the current document's page name.
reference = getCurrentMixedDocumentReferenceResolver().resolve(fullName);
} else {
reference = getDefaultDocumentReferenceResolver().resolve("");
}
return getDocumentAsAuthor(reference);
}
/**
* Loads an Document from the database. Rights are checked on the author (contentAuthor) of the document containing
* the currently executing script before sending back the loaded document.
*
* @param reference the reference of the XWiki document to be loaded
* @return a Document object (if the document couldn't be found a new one is created in memory - but not saved, you
* can check whether it's a new document or not by using {@link com.xpn.xwiki.api.Document#isNew()}
* @throws XWikiException
* @since 2.3M2
*/
public Document getDocumentAsAuthor(DocumentReference reference) throws XWikiException
{
String author = this.getEffectiveScriptAuthorName();
XWikiDocument doc = this.xwiki.getDocument(reference, getXWikiContext());
if (this.xwiki.getRightService().hasAccessLevel("view", author, doc.getFullName(),
getXWikiContext()) == false) {
return null;
}
Document newdoc = doc.newDocument(getXWikiContext());
return newdoc;
}
/**
* @param fullname the {@link XWikiDocument#getFullName() name} of the document to search for.
* @param locale an optional {@link XWikiDocument#getLocale() locale} to filter results.
* @return A list with all the deleted versions of a document in the recycle bin.
* @throws XWikiException if any error
*/
public List<DeletedDocument> getDeletedDocuments(String fullname, String locale) throws XWikiException
{
XWikiDeletedDocument[] deletedDocuments = this.xwiki.getDeletedDocuments(fullname, locale, this.context);
List<DeletedDocument> result = wrapDeletedDocuments(deletedDocuments);
return result;
}
/**
* @param batchId id of the operation that deleted multiple documents at the same time; useful when trying to revert
* the operation
* @return a list of all document versions that were deleted in the same batch, as part of the same operation
* @throws XWikiException if any error
* @since 9.4RC1
*/
public List<DeletedDocument> getDeletedDocuments(String batchId) throws XWikiException
{
XWikiDeletedDocument[] deletedDocuments = this.xwiki.getDeletedDocuments(batchId, this.context);
List<DeletedDocument> result = wrapDeletedDocuments(deletedDocuments);
return result;
}
private List<DeletedDocument> wrapDeletedDocuments(XWikiDeletedDocument[] deletedDocuments)
{
if (deletedDocuments == null || deletedDocuments.length == 0) {
return Collections.emptyList();
}
List<DeletedDocument> result = new ArrayList<>(deletedDocuments.length);
for (XWikiDeletedDocument deletedDocument : deletedDocuments) {
result.add(new DeletedDocument(deletedDocument, this.context));
}
return result;
}
/**
* @param fullname - {@link XWikiDocument#getFullName()}
* @param locale - {@link XWikiDocument#getLocale()}
* @param index - {@link XWikiDocument#getId()}
* @return the specified document from the recycle bin
* @throws XWikiException if any error
* @deprecated since 9.4RC1. Use {@link #getDeletedDocument(String)} instead.
*/
@Deprecated
public DeletedDocument getDeletedDocument(String fullname, String locale, String index) throws XWikiException
{
return getDeletedDocument(index);
}
/**
* @return the specified document from the recycle bin
* @throws XWikiException if any error
* @since 9.4RC1
*/
public DeletedDocument getDeletedDocument(String index) throws XWikiException
{
if (!NumberUtils.isDigits(index)) {
return null;
}
XWikiDeletedDocument dd = this.xwiki.getDeletedDocument(Long.parseLong(index), this.context);
if (dd == null) {
return null;
}
return new DeletedDocument(dd, this.context);
}
/**
* Retrieve all the deleted attachments that belonged to a certain document. Note that this does not distinguish
* between different incarnations of a document name, and it does not require that the document still exists, it
* returns all the attachments that at the time of their deletion had a document with the specified name as their
* owner.
*
* @param docName the {@link XWikiDocument#getFullName() name} of the owner document
* @return A list with all the deleted attachments which belonged to the specified document. If no such attachments
* are found in the trash, an empty list is returned.
*/
public List<DeletedAttachment> getDeletedAttachments(String docName)
{
try {
List<com.xpn.xwiki.doc.DeletedAttachment> attachments =
this.xwiki.getDeletedAttachments(docName, this.context);
if (attachments == null || attachments.isEmpty()) {
attachments = Collections.emptyList();
}
List<DeletedAttachment> result = new ArrayList<DeletedAttachment>(attachments.size());
for (com.xpn.xwiki.doc.DeletedAttachment attachment : attachments) {
result.add(new DeletedAttachment(attachment, this.context));
}
return result;
} catch (Exception ex) {
LOGGER.warn("Failed to retrieve deleted attachments", ex);
}
return Collections.emptyList();
}
/**
* Retrieve all the deleted attachments that belonged to a certain document and had the specified name. Multiple
* versions can be returned since the same file can be uploaded and deleted several times, creating different
* instances in the trash. Note that this does not distinguish between different incarnations of a document name,
* and it does not require that the document still exists, it returns all the attachments that at the time of their
* deletion had a document with the specified name as their owner.
*
* @param docName the {@link DeletedAttachment#getDocName() name of the document} the attachment belonged to
* @param filename the {@link DeletedAttachment#getFilename() name} of the attachment to search for
* @return A list with all the deleted attachments which belonged to the specified document and had the specified
* filename. If no such attachments are found in the trash, an empty list is returned.
*/
public List<DeletedAttachment> getDeletedAttachments(String docName, String filename)
{
try {
List<com.xpn.xwiki.doc.DeletedAttachment> attachments =
this.xwiki.getDeletedAttachments(docName, filename, this.context);
if (attachments == null) {
attachments = Collections.emptyList();
}
List<DeletedAttachment> result = new ArrayList<DeletedAttachment>(attachments.size());
for (com.xpn.xwiki.doc.DeletedAttachment attachment : attachments) {
result.add(new DeletedAttachment(attachment, this.context));
}
return result;
} catch (Exception ex) {
LOGGER.warn("Failed to retrieve deleted attachments", ex);
}
return Collections.emptyList();
}
/**
* Retrieve a specific attachment from the trash.
*
* @param id the unique identifier of the entry in the trash
* @return specified attachment from the trash, {@code null} if not found
*/
public DeletedAttachment getDeletedAttachment(String id)
{
try {
com.xpn.xwiki.doc.DeletedAttachment attachment = this.xwiki.getDeletedAttachment(id, this.context);
if (attachment != null) {
return new DeletedAttachment(attachment, this.context);
}
} catch (Exception ex) {
LOGGER.warn("Failed to retrieve deleted attachment", ex);
}
return null;
}
/**
* Returns whether a document exists or not
*
* @param fullname Fullname of the XWiki document to be loaded
* @return true if the document exists, false if not
* @throws XWikiException
*/
public boolean exists(String fullname) throws XWikiException
{
return this.xwiki.exists(fullname, getXWikiContext());
}
/**
* Returns whether a document exists or not
*
* @param reference the reference of the document to check for its existence
* @return true if the document exists, false if not
* @since 2.3M2
*/
public boolean exists(DocumentReference reference) throws XWikiException
{
return this.xwiki.exists(reference, getXWikiContext());
}
/**
* Verify the rights the current user has on a document. If the document requires rights and the user is not
* authenticated he will be redirected to the login page.
*
* @param docname fullname of the document
* @param right right to check ("view", "edit", "admin", "delete")
* @return true if it exists
*/
public boolean checkAccess(String docname, String right)
{
try {
DocumentReference docReference = getCurrentMixedDocumentReferenceResolver().resolve(docname);
XWikiDocument doc = getXWikiContext().getWiki().getDocument(docReference, this.context);
return getXWikiContext().getWiki().checkAccess(right, doc, getXWikiContext());
} catch (XWikiException e) {
return false;
}
}
/**
* Loads an Document from the database. Rights are checked before sending back the document.
*
* @param space Space to use in case no space is defined in the provided <code>fullname</code>
* @param fullname the full name or relative name of the document to load
* @return a Document object (if the document couldn't be found a new one is created in memory - but not saved, you
* can check whether it's a new document or not by using {@link com.xpn.xwiki.api.Document#isNew()}
* @throws XWikiException
*/
public Document getDocument(String space, String fullname) throws XWikiException
{
XWikiDocument doc = this.xwiki.getDocument(space, fullname, getXWikiContext());
if (this.xwiki.getRightService().hasAccessLevel("view", getXWikiContext().getUser(), doc.getFullName(),
getXWikiContext()) == false) {
return null;
}
return doc.newDocument(getXWikiContext());
}
/**
* Load a specific revision of a document
*
* @param doc Document for which to load a specific revision
* @param rev Revision number
* @return Specific revision of a document
* @throws XWikiException
*/
public Document getDocument(Document doc, String rev) throws XWikiException
{
if ((doc == null) || (doc.getDoc() == null)) {
return null;
}
if (this.xwiki.getRightService().hasAccessLevel("view", getXWikiContext().getUser(), doc.getFullName(),
getXWikiContext()) == false) {
// Finally we return null, otherwise showing search result is a real pain
return null;
}
try {
XWikiDocument revdoc = this.xwiki.getDocument(doc.getDoc(), rev, getXWikiContext());
return revdoc.newDocument(getXWikiContext());
} catch (Exception e) {
// Can't read versioned document
LOGGER.error("Failed to read versioned document", e);
return null;
}
}
/**
* Load a specific revision of a document
*
* @param reference Document for which to load a specific revision
* @param revision Revision number
* @return Specific revision of a document
* @throws XWikiException
* @since 9.3RC1
*/
public Document getDocument(DocumentReference reference, String revision) throws XWikiException
{
try {
XWikiDocument doc = this.xwiki.getDocument(reference, revision, getXWikiContext());
if (this.xwiki.getRightService().hasAccessLevel("view", getXWikiContext().getUser(),
doc.getPrefixedFullName(), getXWikiContext()) == false) {
return null;
}
return doc.newDocument(getXWikiContext());
} catch (Exception e) {
LOGGER.warn("Failed to access document {}: {}", reference, ExceptionUtils.getRootCauseMessage(e));
return null;
}
}
/**
* Output content in the edit content textarea
*
* @param content content to output
* @return the textarea text content
*/
public String getTextArea(String content)
{
return com.xpn.xwiki.XWiki.getTextArea(content, getXWikiContext());
}
/**
* Get the list of available classes in the wiki
*
* @return list of classes names
* @throws XWikiException
*/
public List<String> getClassList() throws XWikiException
{
return this.xwiki.getClassList(getXWikiContext());
}
/**
* Get the global MetaClass object
*
* @return MetaClass object
*/
public MetaClass getMetaclass()
{
return this.xwiki.getMetaclass();
}
/**
* API allowing to search for document names matching a query. Examples:
* <ul>
* <li>Query: <code>where doc.space='Main' order by doc.creationDate desc</code>. Result: All the documents in space
* 'Main' ordered by the creation date from the most recent</li>
* <li>Query: <code>where doc.name like '%sport%' order by doc.name asc</code>. Result: All the documents containing
* 'sport' in their name ordered by document name</li>
* <li>Query: <code>where doc.content like '%sport%' order by doc.author</code> Result: All the documents containing
* 'sport' in their content ordered by the author</li>
* <li>Query: <code>where doc.creator = 'XWiki.LudovicDubost' order by doc.creationDate
* desc</code>. Result: All the documents with creator LudovicDubost ordered by the creation date from the
* most recent</li>
* <li>Query: <code>where doc.author = 'XWiki.LudovicDubost' order by doc.date desc</code>. Result: All the
* documents with last author LudovicDubost ordered by the last modification date from the most recent.</li>
* <li>Query: <code>,BaseObject as obj where doc.fullName=obj.name and
* obj.className='XWiki.XWikiComments' order by doc.date desc</code>. Result: All the documents with at least
* one comment ordered by the last modification date from the most recent</li>
* <li>Query: <code>,BaseObject as obj, StringProperty as prop where
* doc.fullName=obj.name and obj.className='XWiki.XWikiComments' and obj.id=prop.id.id
* and prop.id.name='author' and prop.value='XWiki.LudovicDubost' order by doc.date
* desc</code>. Result: All the documents with at least one comment from LudovicDubost ordered by the last
* modification date from the most recent</li>
* </ul>
*
* @param wheresql Query to be run (either starting with ", BaseObject as obj where.." or by "where ..."
* @return List of document names matching (Main.Page1, Main.Page2)
* @throws XWikiException
* @deprecated use query service instead
*/
@Deprecated
public List<String> searchDocuments(String wheresql) throws XWikiException
{
return this.xwiki.getStore().searchDocumentsNames(wheresql, getXWikiContext());
}
/**
* API allowing to search for document names matching a query return only a limited number of elements and skipping
* the first rows. The query part is the same as searchDocuments
*
* @param wheresql query to use similar to searchDocuments(wheresql)
* @param nb return only 'nb' rows
* @param start skip the first 'start' rows
* @return List of document names matching
* @throws XWikiException
* @see List searchDocuments(String where sql)
* @deprecated use query service instead
*/
@Deprecated
public List<String> searchDocuments(String wheresql, int nb, int start) throws XWikiException
{
return this.xwiki.getStore().searchDocumentsNames(wheresql, nb, start, getXWikiContext());
}
/**
* Privileged API allowing to search for document names matching a query return only a limited number of elements
* and skipping the first rows. The return values contain the list of columns specified in addition to the document
* space and name The query part is the same as searchDocuments
*
* @param wheresql query to use similar to searchDocuments(wheresql)
* @param nb return only 'nb' rows
* @param start skip the first 'start' rows
* @param selectColumns List of columns to add to the result
* @return List of Object[] with the column values of the matching rows
* @throws XWikiException
* @deprecated use query service instead
*/
@Deprecated
public List<String> searchDocuments(String wheresql, int nb, int start, String selectColumns) throws XWikiException
{
if (hasProgrammingRights()) {
return this.xwiki.getStore().searchDocumentsNames(wheresql, nb, start, selectColumns, getXWikiContext());
}
return Collections.emptyList();
}
/**
* API allowing to search for documents allowing to have mutliple entries per locale
*
* @param wheresql query to use similar to searchDocuments(wheresql)
* @param distinctbylocale true to return multiple rows per locale
* @return List of Document object matching
* @throws XWikiException
*/
public List<Document> searchDocuments(String wheresql, boolean distinctbylocale) throws XWikiException
{
return convert(this.xwiki.getStore().searchDocuments(wheresql, distinctbylocale, getXWikiContext()));
}
/**
* API allowing to search for documents allowing to have multiple entries per locale
*
* @param wheresql query to use similar to searchDocuments(wheresql)
* @param distinctbylocale true to return multiple rows per locale
* @return List of Document object matching
* @param nb return only 'nb' rows
* @param start skip the first 'start' rows
* @throws XWikiException
*/
public List<Document> searchDocuments(String wheresql, boolean distinctbylocale, int nb, int start)
throws XWikiException
{
return convert(this.xwiki.getStore().searchDocuments(wheresql, distinctbylocale, nb, start, getXWikiContext()));
}
/**
* Search documents by passing HQL where clause values as parameters. This allows generating a Named HQL query which
* will automatically encode the passed values (like escaping single quotes). This API is recommended to be used
* over the other similar methods where the values are passed inside the where clause and for which you'll need to
* do the encoding/escaping yourself before calling them.
* <p>
* Example
* </p>
*
* <pre>
* <code>
* #set($orphans = $xwiki.searchDocuments(" where doc.fullName <> ? and (doc.parent = ? or "
* + "(doc.parent = ? and doc.space = ?))",
* ["${doc.fullName}as", ${doc.fullName}, ${doc.name}, ${doc.space}]))
* </code>
* </pre>
*
* @param parameterizedWhereClause the HQL where clause. For example
* {@code where doc.fullName <> ? and (doc.parent = ? or (doc.parent = ? and doc.space = ?))}
* @param maxResults the number of rows to return. If 0 then all rows are returned
* @param startOffset the number of rows to skip. If 0 don't skip any row
* @param parameterValues the where clause values that replace the question marks (?)
* @return a list of document names
* @throws XWikiException in case of error while performing the query
* @deprecated use query service instead
*/
@Deprecated
public List<String> searchDocuments(String parameterizedWhereClause, int maxResults, int startOffset,
List<?> parameterValues) throws XWikiException
{
return this.xwiki.getStore().searchDocumentsNames(parameterizedWhereClause, maxResults, startOffset,
parameterValues, getXWikiContext());
}
/**
* Same as {@link #searchDocuments(String, int, int, java.util.List)} but returns all rows.
*
* @see #searchDocuments(String, int, int, java.util.List)
* @deprecated use query service instead
*/
@Deprecated
public List<String> searchDocuments(String parameterizedWhereClause, List<?> parameterValues) throws XWikiException
{
return this.xwiki.getStore().searchDocumentsNames(parameterizedWhereClause, parameterValues, getXWikiContext());
}
/**
* Search documents in the provided wiki by passing HQL where clause values as parameters. See
* {@link #searchDocuments(String, int, int, java.util.List)} for more details.
*
* @param wikiName the name of the wiki where to search.
* @param parameterizedWhereClause the HQL where clause. For example
* {@code where doc.fullName <> ? and (doc.parent = ? or (doc.parent = ? and doc.space = ?))}
* @param maxResults the number of rows to return. If 0 then all rows are returned
* @param startOffset the number of rows to skip. If 0 don't skip any row
* @param parameterValues the where clause values that replace the question marks (?)
* @return a list of document full names (Space.Name).
* @see #searchDocuments(String, int, int, java.util.List)
* @throws XWikiException in case of error while performing the query
* @deprecated use query service instead
*/
@Deprecated
public List<String> searchDocumentsNames(String wikiName, String parameterizedWhereClause, int maxResults,
int startOffset, List<?> parameterValues) throws XWikiException
{
String database = this.context.getWikiId();
try {
this.context.setWikiId(wikiName);
return searchDocuments(parameterizedWhereClause, maxResults, startOffset, parameterValues);
} finally {
this.context.setWikiId(database);
}
}
/**
* Search spaces by passing HQL where clause values as parameters. See
* {@link #searchDocuments(String, int, int, List)} for more about parameterized hql clauses.
*
* @param parametrizedSqlClause the HQL where clause. For example
* {@code where doc.fullName <> ? and (doc.parent = ? or (doc.parent = ? and doc.space = ?))}
* @param nb the number of rows to return. If 0 then all rows are returned
* @param start the number of rows to skip. If 0 don't skip any row
* @param parameterValues the where clause values that replace the question marks (?)
* @return a list of spaces names.
* @throws XWikiException in case of error while performing the query
*/
public List<String> searchSpacesNames(String parametrizedSqlClause, int nb, int start, List<?> parameterValues)
throws XWikiException
{
return this.xwiki.getStore().search("select distinct doc.space from XWikiDocument doc " + parametrizedSqlClause,
nb, start, parameterValues, this.context);
}
/**
* Search attachments by passing HQL where clause values as parameters. See
* {@link #searchDocuments(String, int, int, List)} for more about parameterized hql clauses. You can specify
* properties of attach (the attachment) or doc (the document it is attached to)
*
* @param parametrizedSqlClause The HQL where clause. For example
* {@code where doc.fullName <> ? and (attach.author = ? or (attach.filename = ? and doc.space = ?))}
* @param nb The number of rows to return. If 0 then all rows are returned
* @param start The number of rows to skip at the beginning.
* @param parameterValues A {@link java.util.List} of the where clause values that replace the question marks (?)
* @return A List of {@link Attachment} objects.
* @throws XWikiException in case of error while performing the query
* @since 5.0M2
*/
public List<Attachment> searchAttachments(String parametrizedSqlClause, int nb, int start, List<?> parameterValues)
throws XWikiException
{
return convertAttachments(
this.xwiki.searchAttachments(parametrizedSqlClause, true, nb, start, parameterValues, this.context));
}
/**
* Count attachments returned by a given parameterized query
*
* @param parametrizedSqlClause Everything which would follow the "WHERE" in HQL see:
* {@link #searchDocuments(String, int, int, List)}
* @param parameterValues A {@link java.util.List} of the where clause values that replace the question marks (?)
* @return int number of attachments found.
* @throws XWikiException
* @see #searchAttachments(String, int, int, List)
* @since 5.0M2
*/
public int countAttachments(String parametrizedSqlClause, List<?> parameterValues) throws XWikiException
{
return this.xwiki.countAttachments(parametrizedSqlClause, parameterValues, this.context);
}
/**
* Function to wrap a list of XWikiDocument into Document objects
*
* @param docs list of XWikiDocument
* @return list of Document objects
*/
public List<Document> wrapDocs(List<?> docs)
{
List<Document> result = new ArrayList<Document>();
if (docs != null) {
for (java.lang.Object obj : docs) {
try {
if (obj instanceof XWikiDocument) {
XWikiDocument doc = (XWikiDocument) obj;
Document wrappedDoc = doc.newDocument(getXWikiContext());
result.add(wrappedDoc);
} else if (obj instanceof Document) {
result.add((Document) obj);
} else if (obj instanceof String) {
Document doc = getDocument(obj.toString());
if (doc != null) {
result.add(doc);
}
}
} catch (XWikiException ex) {
}
}
}
return result;
}
/**
* API allowing to parse a text content to evaluate velocity scripts
*
* @param content
* @return evaluated content if the content contains velocity scripts
* @deprecated Since 7.2M1. Use specific rendering/parsing options for the content type you want to parse/render.
*/
@Deprecated
public String parseContent(String content)
{
return this.xwiki.parseContent(content, getXWikiContext());
}
/**
* API to parse a velocity template provided by the current Skin The template is first looked in the skin active for
* the user, the space or the wiki. If the template does not exist in that skin, the template is looked up in the
* "parent skin" of the skin
*
* @param template Template name ("view", "edit", "comment")
* @return Evaluated content from the template
*/
public String parseTemplate(String template)
{
return this.xwiki.parseTemplate(template, getXWikiContext());
}
/**
* API to render a velocity template provided by the current Skin The template is first looked in the skin active
* for the user, the space or the wiki. If the template does not exist in that skin, the template is looked up in
* the "parent skin" of the skin
*
* @param template Template name ("view", "edit", "comment")
* @return Evaluated content from the template
*/
public String renderTemplate(String template)
{
return this.xwiki.renderTemplate(template, getXWikiContext());
}
/**
* Designed to include dynamic content, such as Servlets or JSPs, inside Velocity templates; works by creating a
* RequestDispatcher, buffering the output, then returning it as a string.
*
* @param url URL of the servlet
* @return text result of the servlet
*/
public String invokeServletAndReturnAsString(String url)
{
return this.xwiki.invokeServletAndReturnAsString(url, getXWikiContext());
}
/**
* Return the URL of the static file provided by the current skin The file is first looked in the skin active for
* the user, the space or the wiki. If the file does not exist in that skin, the file is looked up in the "parent
* skin" of the skin. The file can be a CSS file, an image file, a javascript file, etc.
*
* @param filename Filename to be looked up in the skin (logo.gif, style.css)
* @return URL to access this file
*/
public String getSkinFile(String filename)
{
return this.xwiki.getSkinFile(filename, getXWikiContext());
}
/**
* Return the URL of the static file provided by the current skin The file is first looked in the skin active for
* the user, the space or the wiki. If the file does not exist in that skin, the file is looked up in the "parent
* skin" of the skin. The file can be a CSS file, an image file, a javascript file, etc.
*
* @param filename Filename to be looked up in the skin (logo.gif, style.css)
* @param forceSkinAction true to make sure that static files are retrieved through the skin action, to allow
* parsing of velocity on CSS files
* @return URL to access this file
*/
public String getSkinFile(String filename, boolean forceSkinAction)
{
return this.xwiki.getSkinFile(filename, forceSkinAction, getXWikiContext());
}
/**
* API to retrieve the current skin for this request and user The skin is first derived from the request "skin"
* parameter If this parameter does not exist, the user preference "skin" is looked up If this parameter does not
* exist or is empty, the space preference "skin" is looked up If this parameter does not exist or is empty, the
* XWiki preference "skin" is looked up If this parameter does not exist or is empty, the xwiki.cfg parameter
* xwiki.defaultskin is looked up If this parameter does not exist or is empty, the xwiki.cfg parameter
* xwiki.defaultbaseskin is looked up If this parameter does not exist or is empty, the skin is "colibri"
*
* @return The current skin for this request and user
*/
public String getSkin()
{
return this.xwiki.getSkin(getXWikiContext());
}
/**
* API to retrieve the current skin for this request and user. Each skin has a skin it is based on. If not the base
* skin is the xwiki.cfg parameter "xwiki.defaultbaseskin". If this parameter does not exist or is empty, the base
* skin is "colibri".
*
* @return The current baseskin for this request and user
*/
public String getBaseSkin()
{
return this.xwiki.getBaseSkin(getXWikiContext());
}
/**
* API to access the copyright for this space. The copyright is read in the space preferences. If it does not exist
* or is empty it is read from the XWiki preferences.
*
* @return the text for the copyright
*/
public String getSpaceCopyright()
{
return this.xwiki.getSpaceCopyright(getXWikiContext());
}
/**
* API to access an XWiki Preference There can be one preference object per locale This function will find the right
* preference object associated to the current active locale
*
* @param preference Preference name
* @return The preference for this wiki and the current locale
*/
public String getXWikiPreference(String preference)
{
return this.xwiki.getXWikiPreference(preference, getXWikiContext());
}
/**
* API to access an XWiki Preference There can be one preference object per locale This function will find the right
* preference object associated to the current active locale
*
* @param preference Preference name
* @param defaultValue default value to return if the preference does not exist or is empty
* @return The preference for this wiki and the current locale
*/
public String getXWikiPreference(String preference, String defaultValue)
{
return this.xwiki.getXWikiPreference(preference, defaultValue, getXWikiContext());
}
/**
* API to access an Space Preference There can be one preference object per locale This function will find the right
* preference object associated to the current active locale If no preference is found it will look in the XWiki
* Preferences
*
* @param preference Preference name
* @return The preference for this wiki and the current locale
*/
public String getSpacePreference(String preference)
{
return this.xwiki.getSpacePreference(preference, getXWikiContext());
}
/**
* API to access an Space Preference There can be one preference object per locale This function will find the right
* preference object associated to the current active locale If no preference is found it will look in the XWiki
* Preferences
*
* @param preference Preference name
* @param defaultValue default value to return if the preference does not exist or is empty
* @return The preference for this wiki and the current locale
*/
public String getSpacePreference(String preference, String defaultValue)
{
return this.xwiki.getSpacePreference(preference, defaultValue, getXWikiContext());
}
/**
* API to access a Skin Preference The skin object is the current user's skin
*
* @param preference Preference name
* @return The preference for the current skin
*/
public String getSkinPreference(String preference)
{
return this.xwiki.getSkinPreference(preference, getXWikiContext());
}
/**
* API to access a Skin Preference The skin object is the current user's skin
*
* @param preference Preference name
* @param defaultValue default value to return if the preference does not exist or is empty
* @return The preference for the current skin
*/
public String getSkinPreference(String preference, String defaultValue)
{
return this.xwiki.getSkinPreference(preference, defaultValue, getXWikiContext());
}
/**
* Get the reference of the space and fallback on parent space or wiki in case nothing is found.
* <p>
* If the property is not set on any level then empty String is returned.
*
* @param preference Preference name
* @param space The space for which this preference is requested
* @return The preference for this wiki and the current locale
*/
public String getSpacePreferenceFor(String preference, String space)
{
return getSpacePreferenceFor(preference, space, "");
}
/**
* Get the reference of the space and fallback on parent space or wiki in case nothing is found.
* <p>
* If the property is not set on any level then <code>defaultValue</code> is returned.
*
* @param preference Preference name
* @param space The space for which this preference is requested
* @param defaultValue default value to return if the preference does not exist or is empty
* @return The preference for this wiki and the current locale in long format
*/
public String getSpacePreferenceFor(String preference, String space, String defaultValue)
{
return this.xwiki.getSpacePreference(preference, space, defaultValue, getXWikiContext());
}
/**
* Get the reference of the space and fallback on parent space or wiki in case nothing is found.
* <p>
* If the property is not set on any level then empty String is returned.
*
* @param preference the name of the preference key
* @param spaceReference the reference of the space
* @return the value of the preference or empty String if it could not be found
* @since 7.4M1
*/
public String getSpacePreferenceFor(String preference, SpaceReference spaceReference)
{
return this.xwiki.getSpacePreference(preference, spaceReference, getXWikiContext());
}
/**
* Get the reference of the space and fallback on parent space or wiki in case nothing is found.
* <p>
* If the property is not set on any level then <code>defaultValue</code> is returned.
*
* @param preference the name of the preference key
* @param spaceReference the reference of the space
* @param defaultValue the value to return if the preference can't be found
* @return the value of the preference or <code>defaultValue</code> if it could not be found
* @since 7.4M1
*/
public String getSpacePreferenceFor(String preference, SpaceReference spaceReference, String defaultValue)
{
return this.xwiki.getSpacePreference(preference, spaceReference, defaultValue, getXWikiContext());
}
/**
* API to access an XWiki Preference as a long number There can be one preference object per locale This function
* will find the right preference object associated to the current active locale
*
* @param preference Preference name
* @param defaultValue default value to return if the preference does not exist or is empty
* @return The preference for this wiki and the current locale in long format
*/
public long getXWikiPreferenceAsLong(String preference, long defaultValue)
{
return this.xwiki.getXWikiPreferenceAsLong(preference, defaultValue, getXWikiContext());
}
/**
* API to access an XWiki Preference as a long number There can be one preference object per locale This function
* will find the right preference object associated to the current active locale
*
* @param preference Preference name
* @return The preference for this wiki and the current locale in long format
*/
public long getXWikiPreferenceAsLong(String preference)
{
return this.xwiki.getXWikiPreferenceAsLong(preference, getXWikiContext());
}
/**
* API to access a Space Preference as a long number There can be one preference object per locale This function
* will find the right preference object associated to the current active locale If no preference is found it will
* look for the XWiki Preference
*
* @param preference Preference name
* @param defaultValue default value to return if the prefenrece does not exist or is empty
* @return The preference for this wiki and the current locale in long format
*/
public long getSpacePreferenceAsLong(String preference, long defaultValue)
{
return this.xwiki.getSpacePreferenceAsLong(preference, defaultValue, getXWikiContext());
}
/**
* API to access a Space Preference as a long number There can be one preference object per locale This function
* will find the right preference object associated to the current active locale If no preference is found it will
* look for the XWiki Preference
*
* @param preference Preference name
* @return The preference for this wiki and the current locale in long format
*/
public long getSpacePreferenceAsLong(String preference)
{
return this.xwiki.getSpacePreferenceAsLong(preference, getXWikiContext());
}
/**
* API to access an XWiki Preference as an int number There can be one preference object per locale This function
* will find the right preference object associated to the current active locale
*
* @param preference Preference name
* @param defaultValue default value to return if the prefenrece does not exist or is empty
* @return The preference for this wiki and the current locale in int format
*/
public int getXWikiPreferenceAsInt(String preference, int defaultValue)
{
return this.xwiki.getXWikiPreferenceAsInt(preference, defaultValue, getXWikiContext());
}
/**
* API to access an XWiki Preference as a int number There can be one preference object per locale This function
* will find the right preference object associated to the current active locale
*
* @param preference Preference name
* @return The preference for this wiki and the current locale in int format
*/
public int getXWikiPreferenceAsInt(String preference)
{
return this.xwiki.getXWikiPreferenceAsInt(preference, getXWikiContext());
}
/**
* API to access a space Preference as a int number There can be one preference object per locale This function will
* find the right preference object associated to the current active locale If no preference is found it will look
* for the XWiki Preference
*
* @param preference Preference name
* @param defaultValue default value to return if the prefenrece does not exist or is empty
* @return The preference for this wiki and the current locale in int format
*/
public int getSpacePreferenceAsInt(String preference, int defaultValue)
{
return this.xwiki.getSpacePreferenceAsInt(preference, defaultValue, getXWikiContext());
}
/**
* API to access a Space Preference as a int number There can be one preference object per locale This function will
* find the right preference object associated to the current active locale If no preference is found it will look
* for the XWiki Preference
*
* @param preference Preference name
* @return The preference for this wiki and the current locale in int format
*/
public int getSpacePreferenceAsInt(String preference)
{
return this.xwiki.getSpacePreferenceAsInt(preference, getXWikiContext());
}
/**
* API to access a User Preference This function will look in the User profile for the preference If no preference
* is found it will look in the Space Preferences If no preference is found it will look in the XWiki Preferences
*
* @param preference Preference name
* @return The preference for this wiki and the current locale
*/
public String getUserPreference(String preference)
{
return this.xwiki.getUserPreference(preference, getXWikiContext());
}
/**
* API to access a User Preference from cookie This function will look in the session cookie for the preference
*
* @param preference Preference name
* @return The preference for this wiki and the current locale
*/
public String getUserPreferenceFromCookie(String preference)
{
return this.xwiki.getUserPreferenceFromCookie(preference, getXWikiContext());
}
/**
* Same as {@link #getLocalePreference()} but as a String.
*
* @return the locale to use
* @deprecated since 8.0M1, use {@link #getLocalePreference()} instead
*/
@Deprecated
public String getLanguagePreference()
{
return this.xwiki.getLanguagePreference(getXWikiContext());
}
/**
* First try to find the current locale in use from the XWiki context. If none is used and if the wiki is not
* multilingual use the default locale defined in the XWiki preferences. If the wiki is multilingual try to get the
* locale passed in the request. If none was passed try to get it from a cookie. If no locale cookie exists then use
* the user default locale and barring that use the browser's "Accept-Language" header sent in HTTP request. If none
* is defined use the default locale.
*
* @return the locale to use
* @since 8.0M1
*/
public Locale getLocalePreference()
{
return this.xwiki.getLocalePreference(getXWikiContext());
}
/**
* Same as {@link #getInterfaceLocalePreference()} but as a String.
*
* @return the document locale preference for the request
* @deprecated since 8.0M1, use {@link #getInterfaceLocalePreference()} instead
*/
@Deprecated
public String getInterfaceLanguagePreference()
{
return this.xwiki.getInterfaceLanguagePreference(getXWikiContext());
}
/**
* API to access the interface locale preference for the request Order of evaluation is: locale of the wiki in
* mono-lingual mode locale request parameter locale in context locale user preference locale in cookie locale
* accepted by the navigator
*
* @return the document locale preference for the request
*/
public Locale getInterfaceLocalePreference()
{
return this.xwiki.getInterfaceLocalePreference(getXWikiContext());
}
/**
* @return the list of all wiki names, including the main wiki, corresponding to the available wiki descriptors.
* Example: the descriptor for the wiki <i>wikiname</i> is a document in the main wiki, named
* <i>XWiki.XWikiServerWikiname</i>, containing an XWiki.XWikiServerClass object.
* @see com.xpn.xwiki.XWiki#getVirtualWikisDatabaseNames(XWikiContext)
*/
public List<String> getWikiNames()
{
List<String> result = new ArrayList<String>();
try {
result = this.xwiki.getVirtualWikisDatabaseNames(getXWikiContext());
} catch (Exception e) {
LOGGER.error("Failed to get the list of all wiki names", e);
}
return result;
}
/**
* Convenience method to ask if the current XWiki instance contains subwikis (in addition to the main wiki)
*
* @return true if at least 1 subwiki exists; false otherwise
* @see #getWikiNames()
*/
public boolean hasSubWikis()
{
return getWikiNames().size() > 1;
}
/**
* API to check is wiki is multi-lingual
*
* @return true for multi-lingual/false for mono-lingual
*/
public boolean isMultiLingual()
{
return this.xwiki.isMultiLingual(getXWikiContext());
}
/**
* Privileged API to flush the cache of the Wiki installation This flushed the cache of all wikis, all plugins, all
* renderers
*/
public void flushCache()
{
if (hasProgrammingRights()) {
this.xwiki.flushCache(getXWikiContext());
}
}
/**
* Privileged API to create a new user from the request This API is used by RegisterNewUser wiki page
*
* @return the integer status code
* <ul>
* <li>1: ok</li>
* <li>-2: passwords are different or password is empty</li>
* <li>-3: user already exists</li>
* <li>-4: invalid username provided</li>
* <li>-8: user already exists</li>
* </ul>
* @throws XWikiException
*/
public int createUser() throws XWikiException
{
return createUser(false, "edit");
}
/**
* Privileged API to create a new user from the request This API is used by RegisterNewUser wiki page This version
* sends a validation email to the user Configuration of validation email is in the XWiki Preferences
*
* @param withValidation true to send the validationemail
* @return the integer status code
* <ul>
* <li>1: ok</li>
* <li>-2: passwords are different or password is empty</li>
* <li>-3: user already exists</li>
* <li>-4: invalid username provided</li>
* <li>-8: user already exists</li>
* </ul>
* @throws XWikiException
*/
public int createUser(boolean withValidation) throws XWikiException
{
return createUser(withValidation, "edit");
}
/**
* Privileged API to create a new user from the request.
* <p>
* This API is used by the RegisterNewUser wiki page.
* <p>
* This version sends a validation email to the user. Configuration of validation email is in the XWiki Preferences.
*
* @param withValidation true to send the validation email
* @param userRights Rights to set for the user for it's own page(defaults to "edit")
* @return the integer status code
* <ul>
* <li>1: ok</li>
* <li>-2: passwords are different or password is empty</li>
* <li>-3: user already exists</li>
* <li>-4: invalid username provided</li>
* <li>-8: user already exists</li>
* </ul>
* @throws XWikiException
*/
public int createUser(boolean withValidation, String userRights) throws XWikiException
{
boolean registerRight;
try {
// So, what's the register right for? This says that if the creator of the page
// (Admin) has programming rights, anybody can register. Is this OK?
if (hasProgrammingRights()) {
registerRight = true;
} else {
registerRight = this.xwiki.getRightService().hasAccessLevel("register", getXWikiContext().getUser(),
"XWiki.XWikiPreferences", getXWikiContext());
}
if (registerRight) {
return this.xwiki.createUser(withValidation, userRights, getXWikiContext());
}
return -1;
} catch (Exception e) {
LOGGER.error("Failed to create user", e);
return -10;
}
}
/**
* Privileged API to validate the return code given by a user in response to an email validation email The
* validation information are taken from the request object
*
* @param withConfirmEmail true to send a account confirmation email/false to not send it
* @return Success of Failure code (0 for success, -1 for missing programming rights, > 0 for other errors
* @throws XWikiException
*/
public int validateUser(boolean withConfirmEmail) throws XWikiException
{
return this.xwiki.validateUser(withConfirmEmail, getXWikiContext());
}
/**
* Privileged API to add a user to the XWiki.XWikiAllGroup
*
* @param fullwikiname user name to add
* @throws XWikiException
*/
public void addToAllGroup(String fullwikiname) throws XWikiException
{
if (hasProgrammingRights()) {
this.xwiki.setUserDefaultGroup(fullwikiname, getXWikiContext());
}
}
/**
* Privileged API to send a confirmation email to a user
*
* @param xwikiname user to send the email to
* @param password password to put in the mail
* @param email email to send to
* @param add_message Additional message to send to the user
* @param contentfield Preference field to use as a mail template
* @throws XWikiException if the mail was not send successfully
*/
public void sendConfirmationMail(String xwikiname, String password, String email, String add_message,
String contentfield) throws XWikiException
{
if (hasProgrammingRights()) {
this.xwiki.sendConfirmationEmail(xwikiname, password, email, add_message, contentfield, getXWikiContext());
}
}
/**
* Privileged API to send a confirmation email to a user
*
* @param xwikiname user to send the email to
* @param password password to put in the mail
* @param email email to send to
* @param contentfield Preference field to use as a mail template
* @throws XWikiException if the mail was not send successfully
*/
public void sendConfirmationMail(String xwikiname, String password, String email, String contentfield)
throws XWikiException
{
if (hasProgrammingRights()) {
this.xwiki.sendConfirmationEmail(xwikiname, password, email, "", contentfield, getXWikiContext());
}
}
/**
* API to copy a document to another document in the same wiki
*
* @param docname source document
* @param targetdocname target document
* @return true if the copy was sucessfull
* @throws XWikiException if the document was not copied properly
*/
public boolean copyDocument(String docname, String targetdocname) throws XWikiException
{
return this.copyDocument(docname, targetdocname, null, null, null, false, false);
}
/**
* API to copy a translation of a document to another document in the same wiki
*
* @param docname source document
* @param targetdocname target document
* @param wikilocale locale to copy
* @return true if the copy was sucessfull
* @throws XWikiException if the document was not copied properly
*/
public boolean copyDocument(String docname, String targetdocname, String wikilocale) throws XWikiException
{
return this.copyDocument(docname, targetdocname, null, null, wikilocale, false, false);
}
/**
* API to copy a translation of a document to another document of the same name in another wiki
*
* @param docname source document
* @param sourceWiki source wiki
* @param targetWiki target wiki
* @param wikilocale locale to copy
* @return true if the copy was sucessfull
* @throws XWikiException if the document was not copied properly
*/
public boolean copyDocument(String docname, String sourceWiki, String targetWiki, String wikilocale)
throws XWikiException
{
return this.copyDocument(docname, docname, sourceWiki, targetWiki, wikilocale, true, false);
}
/**
* API to copy a translation of a document to another document of the same name in another wiki additionally
* resetting the version
*
* @param docname source document
* @param sourceWiki source wiki
* @param targetWiki target wiki
* @param wikilocale locale to copy
* @param reset true to reset versions
* @return true if the copy was sucessfull
* @throws XWikiException if the document was not copied properly
*/
public boolean copyDocument(String docname, String targetdocname, String sourceWiki, String targetWiki,
String wikilocale, boolean reset) throws XWikiException
{
return this.copyDocument(docname, targetdocname, sourceWiki, targetWiki, wikilocale, reset, false);
}
/**
* API to copy a translation of a document to another document of the same name in another wiki additionally
* resetting the version and overwriting the previous document
*
* @param docname source document name
* @param targetdocname target document name
* @param sourceWiki source wiki
* @param targetWiki target wiki
* @param wikilocale locale to copy
* @param reset true to reset versions
* @param force true to overwrite the previous document
* @return true if the copy was sucessfull
* @throws XWikiException if the document was not copied properly
*/
public boolean copyDocument(String docname, String targetdocname, String sourceWiki, String targetWiki,
String wikilocale, boolean reset, boolean force) throws XWikiException
{
DocumentReference sourceDocumentReference = getCurrentMixedDocumentReferenceResolver().resolve(docname);
if (!StringUtils.isEmpty(sourceWiki)) {
sourceDocumentReference = sourceDocumentReference.replaceParent(sourceDocumentReference.getWikiReference(),
new WikiReference(sourceWiki));
}
DocumentReference targetDocumentReference = getCurrentMixedDocumentReferenceResolver().resolve(targetdocname);
if (!StringUtils.isEmpty(targetWiki)) {
targetDocumentReference = targetDocumentReference.replaceParent(targetDocumentReference.getWikiReference(),
new WikiReference(targetWiki));
}
return this.copyDocument(sourceDocumentReference, targetDocumentReference, wikilocale, reset, force);
}
/**
* API to copy a translation of a document to another document of the same name in another wiki additionally
* resetting the version and overwriting the previous document
*
* @param sourceDocumentReference the reference to the document to copy
* @param targetDocumentReference the reference to the document to create
* @param wikilocale locale to copy
* @param resetHistory {@code true} to reset versions
* @param overwrite {@code true} to overwrite the previous document
* @return {@code true} if the copy was sucessful
* @throws XWikiException if the document was not copied properly
* @since 3.0M3
*/
public boolean copyDocument(DocumentReference sourceDocumentReference, DocumentReference targetDocumentReference,
String wikilocale, boolean resetHistory, boolean overwrite) throws XWikiException
{
// In order to copy the source document the user must have at least the right to view it.
if (hasAccessLevel("view", getDefaultStringEntityReferenceSerializer().serialize(sourceDocumentReference))) {
String targetDocStringRef = getDefaultStringEntityReferenceSerializer().serialize(targetDocumentReference);
// To create the target document the user must have edit rights. If the target document exists and the user
// wants to overwrite it then he needs delete right.
// Note: We have to check if the target document exists before checking the delete right because delete
// right is denied if not explicitly specified.
if (hasAccessLevel("edit", targetDocStringRef)
&& (!overwrite || !exists(targetDocumentReference) || hasAccessLevel("delete", targetDocStringRef))) {
// Reset creation data otherwise the required rights for page copy need to be reconsidered.
return this.xwiki.copyDocument(sourceDocumentReference, targetDocumentReference, wikilocale,
resetHistory, overwrite, true, getXWikiContext());
}
}
return false;
}
/**
* Privileged API to copy a space to another wiki, optionally deleting all document of the target space
*
* @param space source Space
* @param sourceWiki source Wiki
* @param targetWiki target Wiki
* @param locale locale to copy
* @param clean true to delete all document of the target space
* @return number of copied documents
* @throws XWikiException if the space was not copied properly
*/
public int copySpaceBetweenWikis(String space, String sourceWiki, String targetWiki, String locale, boolean clean)
throws XWikiException
{
if (hasProgrammingRights()) {
return this.xwiki.copySpaceBetweenWikis(space, sourceWiki, targetWiki, locale, clean, getXWikiContext());
}
return -1;
}
/**
* API to include a topic into another The topic is rendered fully in the context of itself
*
* @param topic page name of the topic to include
* @return the content of the included page
* @throws XWikiException if the include failed
*/
public String includeTopic(String topic) throws XWikiException
{
return includeTopic(topic, true);
}
/**
* API to execute a form in the context of an including topic The rendering is evaluated in the context of the
* including topic All velocity variables are the one of the including topic This api is usually called using
* #includeForm in a page, which modifies the behavior of "Edit this page" button to direct for Form mode (inline)
*
* @param topic page name of the form to execute
* @return the content of the included page
* @throws XWikiException if the include failed
*/
public String includeForm(String topic) throws XWikiException
{
return includeForm(topic, true);
}
/**
* API to include a topic into another, optionally surrounding the content with {pre}{/pre} to avoid future wiki
* rendering. The topic is rendered fully in the context of itself.
*
* @param topic page name of the topic to include
* @param pre true to add {pre} {/pre} (only if includer document is 1.0 syntax)
* @return the content of the included page
* @throws XWikiException if the include failed
*/
public String includeTopic(String topic, boolean pre) throws XWikiException
{
String result = this.xwiki.include(topic, false, getXWikiContext());
if (pre) {
String includerSyntax = this.xwiki.getCurrentContentSyntaxId(null, this.context);
if (includerSyntax != null && Syntax.XWIKI_1_0.toIdString().equals(includerSyntax)) {
result = "{pre}" + result + "{/pre}";
}
}
return result;
}
/**
* API to execute a form in the context of an including topic, optionnaly surrounding the content with {pre}{/pre}
* to avoid future wiki rendering The rendering is evaluated in the context of the including topic All velocity
* variables are the one of the including topic This api is usually called using #includeForm in a page, which
* modifies the behavior of "Edit this page" button to direct for Form mode (inline).
*
* @param topic page name of the form to execute
* @param pre true to add {pre} {/pre} (only if includer document is 1.0 syntax)
* @return the content of the included page
* @throws XWikiException if the include failed
*/
public String includeForm(String topic, boolean pre) throws XWikiException
{
String result = this.xwiki.include(topic, true, getXWikiContext());
if (pre) {
String includerSyntax = this.xwiki.getCurrentContentSyntaxId(null, this.context);
if (includerSyntax != null && Syntax.XWIKI_1_0.toIdString().equals(includerSyntax)) {
result = "{pre}" + result + "{/pre}";
}
}
return result;
}
/**
* API to check rights on the current document for the current user
*
* @param level right to check (view, edit, comment, delete)
* @return true if right is granted/false if not
*/
public boolean hasAccessLevel(String level)
{
return hasAccessLevel(level, getXWikiContext().getUser(), getXWikiContext().getDoc().getFullName());
}
/**
* API to check rights on a document for a given user
*
* @param level right to check (view, edit, comment, delete)
* @param user user for which to check the right
* @param docname document on which to check the rights
* @return true if right is granted/false if not
*/
public boolean hasAccessLevel(String level, String user, String docname)
{
try {
return this.xwiki.getRightService().hasAccessLevel(level, user, docname, getXWikiContext());
} catch (Exception e) {
return false;
}
}
/**
* API to list all spaces in the current wiki.
* <p>
* Hidden spaces are filtered unless current user enabled them.
*
* @return a list of string representing all non-hidden spaces (ie spaces that have non-hidden pages) for the
* current wiki
* @throws XWikiException if something went wrong
* @deprecated use query service instead
*/
@Deprecated
public List<String> getSpaces() throws XWikiException
{
return this.xwiki.getSpaces(getXWikiContext());
}
/**
* API to list all documents in a space.
* <p>
* Hidden spaces are filtered unless current user enabled them.
*
* @param spaceReference the local reference of the space for which to return all non-hidden documents
* @return the list of document names (in the format {@code Space.Page}) for non-hidden documents in the specified
* space
* @throws XWikiException if the loading went wrong
* @deprecated use query service instead
*/
@Deprecated
public List<String> getSpaceDocsName(String spaceReference) throws XWikiException
{
return this.xwiki.getSpaceDocsName(spaceReference, getXWikiContext());
}
/**
* API to retrieve the current encoding of the wiki engine The encoding is stored in xwiki.cfg Default encoding is
* ISO-8891-1
*
* @return encoding active in this wiki
*/
public String getEncoding()
{
return this.xwiki.getEncoding();
}
/**
* API to retrieve the URL of an attached file in a Wiki Document The URL is generated differently depending on the
* environement (Servlet, Portlet, PDF, etc..) The URL generation can be modified by implementing a new
* XWikiURLFactory object For compatibility with any target environement (and especially the portlet environment) It
* is important to always use the URL functions to generate URL and never hardcode URLs
*
* @param fullname page name which includes the attached file
* @param filename attached filename to create a link for
* @return a URL as a string pointing to the filename
* @throws XWikiException if the URL could not be generated properly
*/
public String getAttachmentURL(String fullname, String filename) throws XWikiException
{
return this.xwiki.getAttachmentURL(fullname, filename, getXWikiContext());
}
/**
* API to retrieve the URL of an a Wiki Document in view mode The URL is generated differently depending on the
* environement (Servlet, Portlet, PDF, etc..) The URL generation can be modified by implementing a new
* XWikiURLFactory object For compatibility with any target environement (and especially the portlet environment) It
* is important to always use the URL functions to generate URL and never hardcode URLs
*
* @param fullname the name of the document for which to return the URL for
* @return a URL as a string pointing to the wiki document in view mode
* @throws XWikiException if the URL could not be generated properly
*/
public String getURL(String fullname) throws XWikiException
{
return this.xwiki.getURL(fullname, "view", getXWikiContext());
}
/**
* Retrieve the URL of an entity using the default mode/action for that entity type. The URL is generated
* differently depending on the environement (Servlet, Portlet, PDF, etc..). The URL generation can be modified by
* implementing a new XWikiURLFactory object. For compatibility with any target environement (and especially the
* portlet environment) it is important to always use the URL functions to generate URLs and never hardcode URLs.
*
* @param reference the reference to the entity for which to return the URL
* @return a URL as a string pointing to the specified entity, using the default mode/action for that entity type
* @throws XWikiException if the URL could not be generated properly
* @since 7.2M1
*/
public String getURL(EntityReference reference) throws XWikiException
{
return this.xwiki.getURL(reference, getXWikiContext());
}
/**
* API to retrieve the URL of an entity in any mode, optionally adding a query string The URL is generated
* differently depending on the environment (Servlet, Portlet, PDF, etc..) The URL generation can be modified by
* implementing a new XWikiURLFactory object. The query string will be modified to be added in the way the
* environment needs it. It is important to not add the query string parameter manually after a URL. Some
* environments will not accept this (like the Portlet environement).
*
* @param reference the reference to the entity for which to return the URL for
* @param action the mode in which to access the entity (view/edit/save/..). Any valid XWiki action is possible
* @param querystring the Query String to provide in the usual mode ({@code name1=value1&name2=value=2}) including
* encoding
* @return a URL as a string pointing to the entity
* @throws XWikiException if the URL could not be generated properly
* @since 7.2M1
*/
public String getURL(EntityReference reference, String action, String querystring) throws XWikiException
{
return this.xwiki.getURL(reference, action, querystring, null, getXWikiContext());
}
/**
* API to retrieve the URL of an a Wiki Document in view mode The URL is generated differently depending on the
* environement (Servlet, Portlet, PDF, etc..) The URL generation can be modified by implementing a new
* XWikiURLFactory object For compatibility with any target environement (and especially the portlet environment) It
* is important to always use the URL functions to generate URL and never hardcode URLs
*
* @param reference the reference to the document for which to return the URL for
* @return a URL as a string pointing to the wiki document in view mode
* @throws XWikiException if the URL could not be generated properly
* @since 2.3M2
*/
public String getURL(DocumentReference reference) throws XWikiException
{
return this.xwiki.getURL(reference, "view", getXWikiContext());
}
/**
* API to retrieve the URL of an a Wiki Document in any mode. The URL is generated differently depending on the
* environment (Servlet, Portlet, PDF, etc..). The URL generation can be modified by implementing a new
* XWikiURLFactory object For compatibility with any target environement (and especially the portlet environment).
* It is important to always use the URL functions to generate URL and never hardcode URLs.
*
* @param fullname the page name which includes the attached file
* @param action the mode in which to access the document (view/edit/save/..). Any valid XWiki action is possible.
* @return a URL as a string pointing to the wiki document in view mode
* @throws XWikiException if the URL could not be generated properly
*/
public String getURL(String fullname, String action) throws XWikiException
{
return this.xwiki.getURL(fullname, action, getXWikiContext());
}
/**
* API to retrieve the URL of a Wiki Document in any mode, optionally adding a query string The URL is generated
* differently depending on the environment (Servlet, Portlet, PDF, etc..) The URL generation can be modified by
* implementing a new XWikiURLFactory object. The query string will be modified to be added in the way the
* environment needs it. It is important to not add the query string parameter manually after a URL. Some
* environments will not accept this (like the Portlet environement).
*
* @param fullname the page name which includes the attached file
* @param action the mode in which to access the document (view/edit/save/..). Any valid XWiki action is possible
* @param querystring the Query String to provide in the usual mode ({@code name1=value1&name2=value=2}) including
* encoding
* @return a URL as a string pointing to the wiki document in view mode
* @throws XWikiException if the URL could not be generated properly
*/
public String getURL(String fullname, String action, String querystring) throws XWikiException
{
return this.xwiki.getURL(fullname, action, querystring, getXWikiContext());
}
/**
* API to retrieve the URL of a Wiki Document in any mode, optionally adding a query string The URL is generated
* differently depending on the environment (Servlet, Portlet, PDF, etc..) The URL generation can be modified by
* implementing a new XWikiURLFactory object. The query string will be modified to be added in the way the
* environment needs it. It is important to not add the query string parameter manually after a URL. Some
* environments will not accept this (like the Portlet environement).
*
* @param reference the reference to the document for which to return the URL for
* @param action the mode in which to access the document (view/edit/save/..). Any valid XWiki action is possible
* @param querystring the Query String to provide in the usual mode ({@code name1=value1&name2=value=2}) including
* encoding
* @return a URL as a string pointing to the wiki document in view mode
* @throws XWikiException if the URL could not be generated properly
* @since 3.0M3
*/
public String getURL(DocumentReference reference, String action, String querystring) throws XWikiException
{
return this.xwiki.getURL(reference, action, querystring, null, getXWikiContext());
}
/**
* API to retrieve the URL of an a Wiki Document in any mode, optionally adding an anchor. The URL is generated
* differently depending on the environement (Servlet, Portlet, PDF, etc..) The URL generation can be modified by
* implementing a new XWikiURLFactory object. The anchor will be modified to be added in the way the environment
* needs it. It is important to not add the anchor parameter manually after a URL. Some environments will not accept
* this (like the Portlet environement).
*
* @param fullname the page name which includes the attached file
* @param action the mode in which to access the document (view/edit/save/..). Any valid XWiki action is possible
* @param querystring the Query String to provide in the usual mode ({@code name1=value1&name2=value=2}) including
* encoding
* @param anchor the anchor that points at a location within the passed document name
* @return a URL as a string pointing to the wiki document in view mode
* @throws XWikiException if the URL could not be generated properly
*/
public String getURL(String fullname, String action, String querystring, String anchor) throws XWikiException
{
return this.xwiki.getURL(fullname, action, querystring, anchor, getXWikiContext());
}
/**
* API to retrieve a viewable referer text for a referer Referers are URL where users have clicked on a link to an
* XWiki page Search engine referer URLs are transformed to a nicer view (Google: search query string) For other URL
* the http:// part is stripped
*
* @param referer referer URL to transform
* @return A viewable string
*/
public String getRefererText(String referer)
{
try {
return this.xwiki.getRefererText(referer, getXWikiContext());
} catch (Exception e) {
return "";
}
}
/**
* API to retrieve a viewable referer text for a referer with a maximum length Referers are URL where users have
* clicked on a link to an XWiki page Search engine referer URLs are transformed to a nicer view (Google: search
* query string) For other URL the http:// part is stripped
*
* @param referer referer URL to transform
* @param length Maximum length. "..." is added to the end of the text
* @return A viewable string
*/
public String getShortRefererText(String referer, int length)
{
try {
return this.xwiki.getRefererText(referer, getXWikiContext()).substring(0, length);
} catch (Exception e) {
return this.xwiki.getRefererText(referer, getXWikiContext());
}
}
/**
* Generate and return an unescaped user display name.
*
* @param userReference the user reference
* @return the unescaped display user name
* @since 6.4RC1
*/
public String getPlainUserName(DocumentReference userReference)
{
return this.xwiki.getPlainUserName(userReference, getXWikiContext());
}
/**
* API to retrieve a link to the User Name page displayed for the first name and last name of the user. The link
* will link to the page on the wiki where the user is registered
*
* @param user Fully qualified username as retrieved from $xcontext.user (XWiki.LudovicDubost)
* @return The first name and last name fields surrounded with a link to the user page
*/
public String getUserName(String user)
{
return this.xwiki.getUserName(user, null, getXWikiContext());
}
/**
* API to retrieve a link to the User Name page displayed with a custom view. The link will link to the page on the
* wiki where the user is registered. The formating is done using the format parameter which can contain velocity
* scripting and access all properties of the User profile using variables ($first_name $last_name $email $city)
*
* @param user Fully qualified username as retrieved from $xcontext.user (XWiki.LudovicDubost)
* @param format formatting to be used ("$first_name $last_name", "$first_name")
* @return The first name and last name fields surrounded with a link to the user page
*/
public String getUserName(String user, String format)
{
return this.xwiki.getUserName(user, format, getXWikiContext());
}
/**
* API to retrieve a link to the User Name page displayed for the first name and last name of the user. The link
* will link to the page on the local wiki even if the user is registered on a different wiki.
*
* @param user Fully qualified username as retrieved from $xcontext.user (XWiki.LudovicDubost)
* @return The first name and last name fields surrounded with a link to the user page
*/
public String getLocalUserName(String user)
{
try {
return this.xwiki.getUserName(user.substring(user.indexOf(":") + 1), null, getXWikiContext());
} catch (Exception e) {
return this.xwiki.getUserName(user, null, getXWikiContext());
}
}
/**
* API to retrieve a link to the User Name page displayed with a custom view. The link will link to the page on the
* local wiki even if the user is registered on a different wiki. The formating is done using the format parameter
* which can contain velocity scripting and access all properties of the User profile using variables ($first_name
* $last_name $email $city)
*
* @param user Fully qualified username as retrieved from $xcontext.user (XWiki.LudovicDubost)
* @param format formatting to be used ("$first_name $last_name", "$first_name")
* @return The first name and last name fields surrounded with a link to the user page
*/
public String getLocalUserName(String user, String format)
{
try {
return this.xwiki.getUserName(user.substring(user.indexOf(":") + 1), format, getXWikiContext());
} catch (Exception e) {
return this.xwiki.getUserName(user, format, getXWikiContext());
}
}
/**
* API to retrieve a text representing the user with the first name and last name of the user. With the link param
* set to false it will not link to the user page With the link param set to true, the link will link to the page on
* the wiki where the user was registered.
*
* @param user Fully qualified username as retrieved from $xcontext.user (XWiki.LudovicDubost)
* @param link false to not add an HTML link to the user profile
* @return The first name and last name fields surrounded with a link to the user page
*/
public String getUserName(String user, boolean link)
{
return this.xwiki.getUserName(user, null, link, getXWikiContext());
}
/**
* API to retrieve a text representing the user with a custom view With the link param set to false it will not link
* to the user page. With the link param set to true, the link will link to the page on the wiki where the user was
* registered. The formating is done using the format parameter which can contain velocity scripting and access all
* properties of the User profile using variables ($first_name $last_name $email $city)
*
* @param user Fully qualified username as retrieved from $xcontext.user (XWiki.LudovicDubost)
* @param format formatting to be used ("$first_name $last_name", "$first_name")
* @param link false to not add an HTML link to the user profile
* @return The first name and last name fields surrounded with a link to the user page
*/
public String getUserName(String user, String format, boolean link)
{
return this.xwiki.getUserName(user, format, link, getXWikiContext());
}
/**
* API to retrieve a text representing the user with the first name and last name of the user. With the link param
* set to false it will not link to the user page. With the link param set to true, the link will link to the page
* on the local wiki even if the user is registered on a different wiki.
*
* @param user Fully qualified username as retrieved from $xcontext.user (XWiki.LudovicDubost)
* @param link false to not add an HTML link to the user profile
* @return The first name and last name fields surrounded with a link to the user page
*/
public String getLocalUserName(String user, boolean link)
{
try {
return this.xwiki.getUserName(user.substring(user.indexOf(":") + 1), null, link, getXWikiContext());
} catch (Exception e) {
return this.xwiki.getUserName(user, null, link, getXWikiContext());
}
}
/**
* API to retrieve a text representing the user with a custom view. The formating is done using the format parameter
* which can contain velocity scripting and access all properties of the User profile using variables ($first_name
* $last_name $email $city). With the link param set to false it will not link to the user page. With the link param
* set to true, the link will link to the page on the local wiki even if the user is registered on a different wiki.
*
* @param user Fully qualified username as retrieved from $xcontext.user (XWiki.LudovicDubost)
* @param format formatting to be used ("$first_name $last_name", "$first_name")
* @param link false to not add an HTML link to the user profile
* @return The first name and last name fields surrounded with a link to the user page
*/
public String getLocalUserName(String user, String format, boolean link)
{
try {
return this.xwiki.getUserName(user.substring(user.indexOf(":") + 1), format, link, getXWikiContext());
} catch (Exception e) {
return this.xwiki.getUserName(user, format, link, getXWikiContext());
}
}
public User getUser()
{
return this.xwiki.getUser(getXWikiContext());
}
public User getUser(String username)
{
return this.xwiki.getUser(username, getXWikiContext());
}
/**
* API allowing to format a date according to the default Wiki setting The date format is provided in the
* 'dateformat' parameter of the XWiki Preferences
*
* @param date date object to format
* @return A string with the date formating from the default Wiki setting
*/
public String formatDate(Date date)
{
return this.xwiki.formatDate(date, null, getXWikiContext());
}
/**
* API allowing to format a date according to a custom format The date format is from java.text.SimpleDateFormat
* Example: "dd/MM/yyyy HH:mm:ss" or "d MMM yyyy" If the format is invalid the default format will be used to show
* the date
*
* @param date date to format
* @param format format of the date to be used
* @return the formatted date
* @see java.text.SimpleDateFormat
*/
public String formatDate(Date date, String format)
{
return this.xwiki.formatDate(date, format, getXWikiContext());
}
/*
* Allow to read user setting providing the user timezone All dates will be expressed with this timezone @return the
* timezone
*/
public String getUserTimeZone()
{
return this.xwiki.getUserTimeZone(this.context);
}
/**
* Returns a plugin from the plugin API. Plugin Rights can be verified. Note that although this API is a duplicate
* of {@link #getPlugin(String)} it used to provide an easy access from Velocity to XWiki plugins. Indeed Velocity
* has a feature in that if a class has a get method, using the dot notation will automatically call the get method
* for the class. See http://velocity.apache.org/engine/releases/velocity-1.5/user-guide.html#propertylookuprules.
* This this allows the following constructs: <code>$xwiki.pluginName.somePluginMethod()</code>
*
* @param name Name of the plugin to retrieve (either short of full class name)
* @return a plugin object
*/
public Api get(String name)
{
return getPlugin(name);
}
/**
* Returns a plugin from the plugin API. Plugin Rights can be verified.
*
* @param name Name of the plugin to retrieve (either short of full class name)
* @return a plugin object
*/
public Api getPlugin(String name)
{
return this.xwiki != null ? this.xwiki.getPluginApi(name, getXWikiContext()) : null;
}
/**
* Returns the Advertisement system from the preferences
*
* @return "google" or "none"
*/
public String getAdType()
{
return this.xwiki.getAdType(getXWikiContext());
}
/**
* Returns the Advertisement client ID from the preferences
*
* @return an Ad affiliate ID
*/
public String getAdClientId()
{
return this.xwiki.getAdClientId(getXWikiContext());
}
/**
* Returns the content of an HTTP/HTTPS URL protected using Basic Authentication
*
* @param surl url to retrieve
* @param username username for the basic authentication
* @param password password for the basic authentication
* @return Content of the specified URL
* @throws IOException
*/
public String getURLContent(String surl, String username, String password) throws IOException
{
try {
return this.xwiki.getURLContent(surl, username, password, this.context);
} catch (Exception e) {
LOGGER.warn("Failed to retrieve content from [" + surl + "]", e);
return "";
}
}
/**
* Returns the content of an HTTP/HTTPS URL
*
* @param surl url to retrieve
* @return Content of the specified URL
* @throws IOException
*/
public String getURLContent(String surl) throws IOException
{
try {
return this.xwiki.getURLContent(surl, this.context);
} catch (Exception e) {
LOGGER.warn("Failed to retrieve content from [" + surl + "]", e);
return "";
}
}
/**
* Returns the content of an HTTP/HTTPS URL protected using Basic Authentication
*
* @param surl url to retrieve
* @param username username for the basic authentication
* @param password password for the basic authentication
* @param timeout manuel timeout in milliseconds
* @return Content of the specified URL
* @throws IOException
*/
public String getURLContent(String surl, String username, String password, int timeout) throws IOException
{
try {
return this.xwiki.getURLContent(surl, username, password, timeout,
this.xwiki.getHttpUserAgent(this.context));
} catch (Exception e) {
return "";
}
}
/**
* Returns the content of an HTTP/HTTPS URL
*
* @param surl url to retrieve
* @param timeout manuel timeout in milliseconds
* @return Content of the specified URL
* @throws IOException
*/
public String getURLContent(String surl, int timeout) throws IOException
{
try {
return this.xwiki.getURLContent(surl, timeout, this.xwiki.getHttpUserAgent(this.context));
} catch (Exception e) {
return "";
}
}
/**
* Returns the content of an HTTP/HTTPS URL protected using Basic Authentication as Bytes
*
* @param surl url to retrieve
* @param username username for the basic authentication
* @param password password for the basic authentication
* @return Content of the specified URL
* @throws IOException
*/
public byte[] getURLContentAsBytes(String surl, String username, String password) throws IOException
{
try {
return this.xwiki.getURLContentAsBytes(surl, username, password, this.context);
} catch (Exception e) {
return null;
}
}
/**
* Returns the content of an HTTP/HTTPS URL as Bytes
*
* @param surl url to retrieve
* @return Content of the specified URL
* @throws IOException
*/
public byte[] getURLContentAsBytes(String surl) throws IOException
{
try {
return this.xwiki.getURLContentAsBytes(surl, this.context);
} catch (Exception e) {
return null;
}
}
/**
* Returns the list of Macros documents in the specified content
*
* @param defaultSpace Default space to use for relative path names
* @param content Content to parse
* @return ArrayList of document names
*/
public List<String> getIncludedMacros(String defaultSpace, String content)
{
return this.xwiki.getIncludedMacros(defaultSpace, content, getXWikiContext());
}
/**
* returns true if xwiki.readonly is set in the configuration file
*
* @return the value of xwiki.isReadOnly()
* @see com.xpn.xwiki.XWiki
*/
public boolean isReadOnly()
{
return this.xwiki.isReadOnly();
}
/**
* Privileged API to set/unset the readonly status of the Wiki After setting this to true no writing to the database
* will be performed All Edit buttons will be removed and save actions disabled This is used for maintenance
* purposes
*
* @param ro true to set read-only mode/false to unset
*/
public void setReadOnly(boolean ro)
{
if (hasAdminRights()) {
this.xwiki.setReadOnly(ro);
}
}
/**
* Priviledge API to regenerate the links/backlinks table Normally links and backlinks are stored when a page is
* modified This function will regenerate all the backlinks This function can be long to run
*
* @throws XWikiException exception if the generation fails
*/
public void refreshLinks() throws XWikiException
{
if (hasAdminRights()) {
this.xwiki.refreshLinks(getXWikiContext());
}
}
/**
* API to check if the backlinks feature is active Backlinks are activated in xwiki.cfg or in the XWiki Preferences
*
* @return true if the backlinks feature is active
* @throws XWikiException exception if the preference could not be retrieved
*/
public boolean hasBacklinks() throws XWikiException
{
return this.xwiki.hasBacklinks(getXWikiContext());
}
/**
* API to check if the tags feature is active. Tags are activated in xwiki.cfg or in the XWiki Preferences
*
* @return true if the tags feature is active, false otherwise
* @throws XWikiException exception if the preference could not be retrieved
*/
public boolean hasTags() throws XWikiException
{
return this.xwiki.hasTags(getXWikiContext());
}
/**
* API to check if the edit comment feature is active Edit comments are activated in xwiki.cfg or in the XWiki
* Preferences
*
* @return
*/
public boolean hasEditComment()
{
return this.xwiki.hasEditComment(this.context);
}
/**
* API to check if the edit comment field is shown in the edit form Edit comments are activated in xwiki.cfg or in
* the XWiki Preferences
*
* @return
*/
public boolean isEditCommentFieldHidden()
{
return this.xwiki.isEditCommentFieldHidden(this.context);
}
/**
* API to check if the edit comment is suggested (prompted once by Javascript if empty) Edit comments are activated
* in xwiki.cfg or in the XWiki Preferences
*
* @return
*/
public boolean isEditCommentSuggested()
{
return this.xwiki.isEditCommentSuggested(this.context);
}
/**
* API to check if the edit comment is mandatory (prompted by Javascript if empty) Edit comments are activated in
* xwiki.cfg or in the XWiki Preferences
*
* @return
*/
public boolean isEditCommentMandatory()
{
return this.xwiki.isEditCommentMandatory(this.context);
}
/**
* API to check if the minor edit feature is active minor edit is activated in xwiki.cfg or in the XWiki Preferences
*/
public boolean hasMinorEdit()
{
return this.xwiki.hasMinorEdit(this.context);
}
/**
* API to check if the recycle bin feature is active recycle bin is activated in xwiki.cfg or in the XWiki
* Preferences
*/
public boolean hasRecycleBin()
{
return this.xwiki.hasRecycleBin(this.context);
}
/**
* API to rename a page (experimental) Rights are necessary to edit the source and target page All objects and
* attachments ID are modified in the process to link to the new page name
*
* @param doc page to rename
* @param newFullName target page name to move the information to
*/
public boolean renamePage(Document doc, String newFullName)
{
try {
if (this.xwiki.exists(newFullName, getXWikiContext()) && !this.xwiki.getRightService()
.hasAccessLevel("delete", getXWikiContext().getUser(), newFullName, getXWikiContext())) {
return false;
}
if (this.xwiki.getRightService().hasAccessLevel("edit", getXWikiContext().getUser(), doc.getFullName(),
getXWikiContext())) {
this.xwiki.renamePage(doc.getFullName(), newFullName, getXWikiContext());
}
} catch (XWikiException e) {
return false;
}
return true;
}
/**
* Retrieves the current editor preference for the request The preference is first looked up in the user preference
* and then in the space and wiki preference
*
* @return "wysiwyg" or "text"
*/
public String getEditorPreference()
{
return this.xwiki.getEditorPreference(getXWikiContext());
}
/**
* Privileged API to retrieve an object instantiated from groovy code in a String. Note that Groovy scripts
* compilation is cached.
*
* @param script the Groovy class definition string (public class MyClass { ... })
* @return An object instantiating this class
* @throws XWikiException
*/
public java.lang.Object parseGroovyFromString(String script) throws XWikiException
{
if (hasProgrammingRights()) {
return this.xwiki.parseGroovyFromString(script, getXWikiContext());
}
return "groovy_missingrights";
}
/**
* Privileged API to retrieve an object instantiated from groovy code in a String, using a classloader including all
* JAR files located in the passed page as attachments. Note that Groovy scripts compilation is cached
*
* @param script the Groovy class definition string (public class MyClass { ... })
* @return An object instantiating this class
* @throws XWikiException
*/
public java.lang.Object parseGroovyFromPage(String script, String jarWikiPage) throws XWikiException
{
XWikiDocument doc = this.xwiki.getDocument(script, getXWikiContext());
if (this.xwiki.getRightService().hasProgrammingRights(doc, getXWikiContext())) {
return this.xwiki.parseGroovyFromString(doc.getContent(), jarWikiPage, getXWikiContext());
}
return "groovy_missingrights";
}
/**
* Privileged API to retrieve an object instanciated from groovy code in a String Groovy scripts compilation is
* cached
*
* @param fullname // script containing a Groovy class definition (public class MyClass { ... })
* @return An object instanciating this class
* @throws XWikiException
*/
public java.lang.Object parseGroovyFromPage(String fullname) throws XWikiException
{
XWikiDocument doc = this.xwiki.getDocument(fullname, getXWikiContext());
if (this.xwiki.getRightService().hasProgrammingRights(doc, getXWikiContext())) {
return this.xwiki.parseGroovyFromString(doc.getContent(), getXWikiContext());
}
return "groovy_missingrights";
}
/**
* API to get the macro list from the XWiki Preferences The macro list are the macros available from the Macro
* Mapping System
*
* @return String with each macro on each line
*/
public String getMacroList()
{
return this.xwiki.getMacroList(getXWikiContext());
}
/**
* API to check if using which toolbars in Wysiwyg editor
*
* @return a string value
*/
public String getWysiwygToolbars()
{
return this.xwiki.getWysiwygToolbars(getXWikiContext());
}
/**
* API to create an object from the request The parameters are the ones that are created from
* doc.display("field","edit") calls
*
* @param className XWiki Class Name to create the object from
* @return a BaseObject wrapped in an Object
* @throws XWikiException exception if the object could not be read
*/
public com.xpn.xwiki.api.Object getObjectFromRequest(String className) throws XWikiException
{
return new com.xpn.xwiki.api.Object(this.xwiki.getObjectFromRequest(className, getXWikiContext()),
getXWikiContext());
}
/**
* API to create an empty document
*
* @return an XWikiDocument wrapped in a Document
*/
public Document createDocument()
{
return new XWikiDocument().newDocument(getXWikiContext());
}
/**
* API to convert the username depending on the configuration The username can be converted from email to a valid
* XWiki page name hidding the email address The username can be then used to login and link to the right user page
*
* @param username username to use for login
* @return converted wiki page name for this username
*/
public String convertUsername(String username)
{
return this.xwiki.convertUsername(username, getXWikiContext());
}
/**
* API to get the Property object from a class based on a property path A property path looks like
* XWiki.ArticleClass_fieldname
*
* @param propPath Property path
* @return a PropertyClass object from a BaseClass object
*/
public com.xpn.xwiki.api.PropertyClass getPropertyClassFromName(String propPath)
{
return new PropertyClass(this.xwiki.getPropertyClassFromName(propPath, getXWikiContext()), getXWikiContext());
}
/**
* Generates a unique page name based on initial page name and already existing pages
*
* @param name
* @return a unique page name
*/
public String getUniquePageName(String name)
{
return this.xwiki.getUniquePageName(name, getXWikiContext());
}
/**
* Generates a unique page name based on initial page name and already existing pages
*
* @param space
* @param name
* @return a unique page name
*/
public String getUniquePageName(String space, String name)
{
return this.xwiki.getUniquePageName(space, name, getXWikiContext());
}
/**
* Inserts a tooltip using toolTip.js
*
* @param html HTML viewed
* @param message HTML Tooltip message
* @param params Parameters in Javascropt added to the tooltip config
* @return HTML with working tooltip
*/
public String addTooltip(String html, String message, String params)
{
return this.xwiki.addTooltip(html, message, params, getXWikiContext());
}
/**
* Inserts a tooltip using toolTip.js
*
* @param html HTML viewed
* @param message HTML Tooltip message
* @return HTML with working tooltip
*/
public String addTooltip(String html, String message)
{
return this.xwiki.addTooltip(html, message, getXWikiContext());
}
/**
* Inserts the tooltip Javascript
*
* @return
*/
public String addTooltipJS()
{
return this.xwiki.addTooltipJS(getXWikiContext());
}
/*
* Inserts a Mandatory asterix
*/
public String addMandatory()
{
return this.xwiki.addMandatory(getXWikiContext());
}
/**
* Get the XWiki Class object defined in the passed Document name.
* <p>
* Note: This method doesn't require any rights for accessing the passed Document (as opposed to the
* {@link com.xpn.xwiki.api.Document#getClass()} method which does require to get a Document object first. This is
* thus useful in cases where the calling code doesn't have the access right to the specified Document. It is safe
* because there are no sensitive data stored in a Class definition.
* </p>
*
* @param documentName the name of the document for which to get the Class object. For example
* "XWiki.XWikiPreferences"
* @return the XWiki Class object defined in the passed Document name. If the passed Document name points to a
* Document with no Class defined then an empty Class object is returned (i.e. a Class object with no
* properties).
* @throws XWikiException if the passed document name doesn't point to a valid Document
*/
public Class getClass(String documentName) throws XWikiException
{
// TODO: The implementation should be done in com.xpn.xwiki.XWiki as this class should
// delegate all implementations to that Class.
DocumentReference docReference = getCurrentMixedDocumentReferenceResolver().resolve(documentName);
return new Class(this.xwiki.getDocument(docReference, this.context).getXClass(), this.context);
}
/**
* Provides an absolute counter
*
* @param name Counter name
* @return String
*/
public String getCounter(String name)
{
XWikiEngineContext econtext = this.context.getEngineContext();
Integer counter = (Integer) econtext.getAttribute(name);
if (counter == null) {
counter = 0;
}
counter = counter.intValue() + 1;
econtext.setAttribute(name, counter);
return counter.toString();
}
/**
* Check authentication from request and set according persitent login information If it fails user is unlogged
*
* @return null if failed, non null XWikiUser if sucess
* @throws XWikiException
*/
public XWikiUser checkAuth() throws XWikiException
{
return this.context.getWiki().getAuthService().checkAuth(this.context);
}
/**
* Check authentication from username and password and set according persitent login information If it fails user is
* unlogged
*
* @param username username to check
* @param password password to check
* @param rememberme "1" if you want to remember the login accross navigator restart
* @return null if failed, non null XWikiUser if sucess
* @throws XWikiException
*/
public XWikiUser checkAuth(String username, String password, String rememberme) throws XWikiException
{
return this.context.getWiki().getAuthService().checkAuth(username, password, rememberme, this.context);
}
/**
* Access statistics api
*
* @return a StatsService instance that can be used to retrieve different xwiki statistics
*/
public StatsService getStatsService()
{
return this.statsService;
}
/**
* API to get the xwiki criteria service which allow to create various criteria : integer ranges, date periods, date
* intervals, etc.
*
* @return the xwiki criteria service
*/
public CriteriaService getCriteriaService()
{
return this.criteriaService;
}
/**
* @return the ids of configured syntaxes for this wiki (eg "xwiki/1.0", "xwiki/2.0", "mediawiki/1.0", etc)
* @deprecated since 8.2M1, use the XWiki Rendering Configuration component or the Rendering Script Service one
* instead
*/
@Deprecated
public List<String> getConfiguredSyntaxes()
{
return this.xwiki.getConfiguredSyntaxes();
}
/**
* API to get the Servlet path for a given wiki. In mono wiki this is "bin/" or "xwiki/". In virtual mode and if
* <tt>xwiki.virtual.usepath</tt> is enabled in xwiki.cfg, it is "wiki/wikiname/".
*
* @param wikiName wiki for which to get the path
* @return The servlet path
*/
public String getServletPath(String wikiName)
{
return this.xwiki.getServletPath(wikiName, this.context);
}
/**
* API to get the Servlet path for the current wiki. In mono wiki this is "bin/" or "xwiki/". In virtual mode and if
* <tt>xwiki.virtual.usepath</tt> is enabled in xwiki.cfg, it is "wiki/wikiname/".
*
* @return The servlet path
*/
public String getServletPath()
{
return this.xwiki.getServletPath(this.context.getWikiId(), this.context);
}
/**
* API to get the webapp path for the current wiki. This usually is "xwiki/". It can be configured in xwiki.cfg with
* the config <tt>xwiki.webapppath</tt>.
*
* @return The servlet path
*/
public String getWebAppPath()
{
return this.xwiki.getWebAppPath(this.context);
}
/**
* @return the syntax id of the syntax to use when creating new documents.
*/
public String getDefaultDocumentSyntax()
{
return this.xwiki.getDefaultDocumentSyntax();
}
/**
* Find the corresponding available renderer syntax.
* <p>
* If <code>syntaxVersion</code> is null the last version of the available provided syntax type is returned.
*
* @param syntaxType the syntax type
* @param syntaxVersion the syntax version
* @return the available corresponding {@link Syntax}. Null if no available renderer can be found.
*/
public Syntax getAvailableRendererSyntax(String syntaxType, String syntaxVersion)
{
Syntax syntax = null;
try {
List<PrintRendererFactory> factories =
Utils.getContextComponentManager().getInstanceList((Type) PrintRendererFactory.class);
for (PrintRendererFactory factory : factories) {
Syntax factorySyntax = factory.getSyntax();
if (syntaxVersion != null) {
if (factorySyntax.getType().getId().equalsIgnoreCase(syntaxType)
&& factorySyntax.getVersion().equals(syntaxVersion)) {
syntax = factorySyntax;
break;
}
} else {
// TODO: improve version comparaison since it does not work when comparing 2.0 and 10.0 for example.
// We
// should have a Version which implements Comparable like we have SyntaxId in Syntax
if (factorySyntax.getType().getId().equalsIgnoreCase(syntaxType)
&& (syntax == null || factorySyntax.getVersion().compareTo(syntax.getVersion()) > 0)) {
syntax = factorySyntax;
}
}
}
} catch (ComponentLookupException e) {
LOGGER.error("Failed to lookup available renderer syntaxes", e);
}
return syntax;
}
/**
* @return true if section editing is enabled (can be configured through the {@code xwiki.section.edit}
* configuration property. Defaults to 1 (=enabled) when not defined
*/
public boolean hasSectionEdit()
{
return this.xwiki.hasSectionEdit(getXWikiContext());
}
/**
* @return the section depth for which section editing is available (can be configured through
* {@code xwiki.section.depth} configuration property. Defaults to 2 when not defined
*/
public long getSectionEditingDepth()
{
return this.xwiki.getSectionEditingDepth();
}
/**
* @return true if title handling should be using the compatibility mode or not. When the compatibility mode is
* active, if the document's content first header (level 1 or level 2) matches the document's title the
* first header is stripped.
*/
public boolean isTitleInCompatibilityMode()
{
return this.xwiki.isTitleInCompatibilityMode();
}
/**
* Get the syntax of the content currently being executed.
* <p>
* The document currently being executed is not the same than the actual content syntax since the executed code
* might come from an included page or some macro that change the context syntax. The same logic used inside
* rendering macros is used (see {@link org.xwiki.rendering.macro.MacroContentParser}).
* <p>
* If the current document can't be found, the method assume that the executed document is the context document
* (it's generally the case when a document is directly rendered with
* {@link XWikiDocument#getRenderedContent(XWikiContext)} for example).
*
* @return the syntax identifier
*/
public String getCurrentContentSyntaxId()
{
return this.xwiki.getCurrentContentSyntaxId(getXWikiContext());
}
}