Permalink
Switch branches/tags
xwiki-xmldoc-update-plugin-1.4 xwiki-xmldoc-update-plugin-1.3 xwiki-xmldoc-update-plugin-1.2 xwiki-xmldoc-update-plugin-1.1 xwiki-xmldoc-update-plugin-1.0 xwiki-xar-plugin-1.14 xwiki-xar-plugin-1.13 xwiki-xar-plugin-1.12 xwiki-xar-plugin-1.11 xwiki-xar-plugin-1.10 xwiki-xar-plugin-1.9 xwiki-xar-plugin-1.8 xwiki-xar-handlers-1.9 xwiki-xar-handlers-1.8 xwiki-web-3.0 xwiki-web-3.0-rc-1 xwiki-web-3.0-milestone-3 xwiki-web-3.0-milestone-2 xwiki-web-3.0-milestone-1 xwiki-web-2.7.1 xwiki-web-2.7 xwiki-web-2.7-rc-1 xwiki-web-2.6.2 xwiki-web-2.6.1 xwiki-web-2.6 xwiki-web-2.6-rc-2 xwiki-web-2.6-rc-1 xwiki-web-2.5.2 xwiki-web-2.5.1 xwiki-web-2.5 xwiki-web-2.5-rc-1 xwiki-web-2.5-milestone-2 xwiki-web-2.5-milestone-1 xwiki-web-2.4.4 xwiki-web-2.4.3 xwiki-web-2.4.2 xwiki-web-2.4.1 xwiki-web-2.4 xwiki-web-2.4-rc-1 xwiki-web-2.4-milestone-2 xwiki-web-2.4-milestone-1 xwiki-web-2.3.2 xwiki-web-2.3.1 xwiki-web-2.3 xwiki-web-2.3-rc-1 xwiki-web-2.3-milestone-2 xwiki-web-2.3-milestone-1 xwiki-web-2.2.6 xwiki-web-2.2.5 xwiki-web-2.2.4 xwiki-web-2.2.3 xwiki-web-2.2.2 xwiki-web-2.2.1 xwiki-web-2.2 xwiki-web-2.2-rc-2 xwiki-web-2.2-rc-1 xwiki-web-2.2-milestone-2 xwiki-web-2.2-milestone-1 xwiki-web-2.1.2 xwiki-web-2.1.1 xwiki-web-2.1 xwiki-web-2.1-rc-1 xwiki-web-2.1-milestone-2 xwiki-web-2.1-milestone-1 xwiki-web-2.0.5 xwiki-web-2.0.4 xwiki-web-2.0.3 xwiki-web-2.0.2 xwiki-web-2.0.1 xwiki-web-2.0 xwiki-web-2.0-rc-2 xwiki-web-2.0-rc-1 xwiki-web-2.0-milestone-4 xwiki-web-2.0-milestone-3 xwiki-web-2.0-milestone-2 xwiki-web-2.0-milestone-1 xwiki-web-1.9.4 xwiki-web-1.9.3 xwiki-web-1.9.2 xwiki-web-1.9.1 xwiki-web-1.9 xwiki-web-1.9-rc-1 xwiki-web-1.9-milestone-2 xwiki-web-1.9-milestone-1 xwiki-web-1.8.4 xwiki-web-1.8.3 xwiki-web-1.8.2 xwiki-web-1.8.1 xwiki-web-1.8 xwiki-web-1.8-rc-2 xwiki-web-1.8-rc-1 xwiki-web-1.8-milestone-2 xwiki-web-1.8-milestone-1 xwiki-web-1.7.2 xwiki-web-1.7.1 xwiki-web-1.7 xwiki-web-1.7-rc-1 xwiki-web-1.7-milestone-3 xwiki-web-1.7-milestone-2 xwiki-web-1.7-milestone-1
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
7428 lines (6419 sloc) 289 KB
/*
* 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;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.DateFormatSymbols;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;
import java.util.zip.ZipOutputStream;
import javax.annotation.Priority;
import javax.inject.Provider;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.naming.NamingException;
import javax.script.ScriptContext;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.httpclient.Credentials;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.URIException;
import org.apache.commons.httpclient.UsernamePasswordCredentials;
import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.httpclient.util.URIUtil;
import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.LocaleUtils;
import org.apache.commons.lang3.RandomStringUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.apache.commons.lang3.math.NumberUtils;
import org.apache.commons.lang3.reflect.FieldUtils;
import org.apache.velocity.VelocityContext;
import org.hibernate.HibernateException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xwiki.bridge.event.DocumentCreatedEvent;
import org.xwiki.bridge.event.DocumentCreatingEvent;
import org.xwiki.bridge.event.DocumentDeletedEvent;
import org.xwiki.bridge.event.DocumentDeletingEvent;
import org.xwiki.bridge.event.DocumentRolledBackEvent;
import org.xwiki.bridge.event.DocumentRollingBackEvent;
import org.xwiki.bridge.event.DocumentUpdatedEvent;
import org.xwiki.bridge.event.DocumentUpdatingEvent;
import org.xwiki.bridge.event.WikiCopiedEvent;
import org.xwiki.bridge.event.WikiDeletedEvent;
import org.xwiki.cache.Cache;
import org.xwiki.classloader.ClassLoaderManager;
import org.xwiki.component.event.ComponentDescriptorAddedEvent;
import org.xwiki.component.manager.ComponentLookupException;
import org.xwiki.component.manager.ComponentManager;
import org.xwiki.component.manager.NamespacedComponentManager;
import org.xwiki.component.util.DefaultParameterizedType;
import org.xwiki.configuration.ConfigurationSource;
import org.xwiki.container.servlet.HttpServletUtils;
import org.xwiki.context.Execution;
import org.xwiki.edit.EditConfiguration;
import org.xwiki.job.Job;
import org.xwiki.job.JobException;
import org.xwiki.job.JobExecutor;
import org.xwiki.job.annotation.Serializable;
import org.xwiki.job.event.status.JobProgressManager;
import org.xwiki.job.event.status.JobStatus.State;
import org.xwiki.localization.ContextualLocalizationManager;
import org.xwiki.mail.MailListener;
import org.xwiki.mail.MailSender;
import org.xwiki.mail.MailSenderConfiguration;
import org.xwiki.mail.MailStatusResultSerializer;
import org.xwiki.mail.XWikiAuthenticator;
import org.xwiki.model.EntityType;
import org.xwiki.model.reference.AttachmentReference;
import org.xwiki.model.reference.AttachmentReferenceResolver;
import org.xwiki.model.reference.DocumentReference;
import org.xwiki.model.reference.DocumentReferenceResolver;
import org.xwiki.model.reference.EntityReference;
import org.xwiki.model.reference.EntityReferenceResolver;
import org.xwiki.model.reference.EntityReferenceSerializer;
import org.xwiki.model.reference.LocalDocumentReference;
import org.xwiki.model.reference.ObjectReference;
import org.xwiki.model.reference.PageReference;
import org.xwiki.model.reference.PageReferenceResolver;
import org.xwiki.model.reference.RegexEntityReference;
import org.xwiki.model.reference.SpaceReference;
import org.xwiki.model.reference.WikiReference;
import org.xwiki.observation.EventListener;
import org.xwiki.observation.ObservationManager;
import org.xwiki.observation.event.CancelableEvent;
import org.xwiki.observation.event.Event;
import org.xwiki.query.QueryException;
import org.xwiki.query.QueryFilter;
import org.xwiki.refactoring.batch.BatchOperationExecutor;
import org.xwiki.rendering.block.Block;
import org.xwiki.rendering.block.Block.Axes;
import org.xwiki.rendering.block.MetaDataBlock;
import org.xwiki.rendering.block.match.MetadataBlockMatcher;
import org.xwiki.rendering.internal.transformation.MutableRenderingContext;
import org.xwiki.rendering.listener.MetaData;
import org.xwiki.rendering.parser.ParseException;
import org.xwiki.rendering.syntax.Syntax;
import org.xwiki.rendering.syntax.SyntaxContent;
import org.xwiki.rendering.transformation.RenderingContext;
import org.xwiki.resource.ResourceReference;
import org.xwiki.resource.ResourceReferenceManager;
import org.xwiki.resource.ResourceReferenceResolver;
import org.xwiki.resource.ResourceType;
import org.xwiki.resource.ResourceTypeResolver;
import org.xwiki.resource.entity.EntityResourceReference;
import org.xwiki.script.ScriptContextManager;
import org.xwiki.skin.Resource;
import org.xwiki.skin.Skin;
import org.xwiki.skin.SkinManager;
import org.xwiki.stability.Unstable;
import org.xwiki.template.TemplateManager;
import org.xwiki.url.ExtendedURL;
import org.xwiki.velocity.VelocityManager;
import org.xwiki.wiki.descriptor.WikiDescriptor;
import org.xwiki.wiki.descriptor.WikiDescriptorManager;
import org.xwiki.wiki.manager.WikiManager;
import org.xwiki.wiki.manager.WikiManagerException;
import org.xwiki.xml.XMLUtils;
import com.xpn.xwiki.api.Api;
import com.xpn.xwiki.api.Document;
import com.xpn.xwiki.api.User;
import com.xpn.xwiki.criteria.api.XWikiCriteriaService;
import com.xpn.xwiki.doc.DeletedAttachment;
import com.xpn.xwiki.doc.DocumentRevisionProvider;
import com.xpn.xwiki.doc.MandatoryDocumentInitializer;
import com.xpn.xwiki.doc.XWikiAttachment;
import com.xpn.xwiki.doc.XWikiDeletedDocument;
import com.xpn.xwiki.doc.XWikiDocument;
import com.xpn.xwiki.doc.XWikiDocument.XWikiAttachmentToRemove;
import com.xpn.xwiki.doc.XWikiDocumentArchive;
import com.xpn.xwiki.internal.WikiInitializerJob;
import com.xpn.xwiki.internal.WikiInitializerRequest;
import com.xpn.xwiki.internal.XWikiCfgConfigurationSource;
import com.xpn.xwiki.internal.XWikiConfigDelegate;
import com.xpn.xwiki.internal.XWikiInitializerJob;
import com.xpn.xwiki.internal.event.XObjectPropertyAddedEvent;
import com.xpn.xwiki.internal.event.XObjectPropertyDeletedEvent;
import com.xpn.xwiki.internal.event.XObjectPropertyEvent;
import com.xpn.xwiki.internal.event.XObjectPropertyUpdatedEvent;
import com.xpn.xwiki.internal.mandatory.XWikiPreferencesDocumentInitializer;
import com.xpn.xwiki.internal.render.OldRendering;
import com.xpn.xwiki.internal.render.groovy.ParseGroovyFromString;
import com.xpn.xwiki.internal.skin.InternalSkinConfiguration;
import com.xpn.xwiki.internal.skin.InternalSkinManager;
import com.xpn.xwiki.internal.skin.WikiSkin;
import com.xpn.xwiki.internal.skin.WikiSkinUtils;
import com.xpn.xwiki.internal.store.StoreConfiguration;
import com.xpn.xwiki.internal.velocity.VelocityEvaluator;
import com.xpn.xwiki.job.JobRequestContext;
import com.xpn.xwiki.objects.BaseObject;
import com.xpn.xwiki.objects.PropertyInterface;
import com.xpn.xwiki.objects.classes.BaseClass;
import com.xpn.xwiki.objects.classes.PasswordClass;
import com.xpn.xwiki.objects.classes.PropertyClass;
import com.xpn.xwiki.objects.meta.MetaClass;
import com.xpn.xwiki.plugin.XWikiPluginInterface;
import com.xpn.xwiki.plugin.XWikiPluginManager;
import com.xpn.xwiki.render.groovy.XWikiPageClassLoader;
import com.xpn.xwiki.stats.api.XWikiStatsService;
import com.xpn.xwiki.stats.impl.SearchEngineRule;
import com.xpn.xwiki.stats.impl.XWikiStatsServiceImpl;
import com.xpn.xwiki.store.AttachmentRecycleBinStore;
import com.xpn.xwiki.store.AttachmentVersioningStore;
import com.xpn.xwiki.store.XWikiAttachmentStoreInterface;
import com.xpn.xwiki.store.XWikiCacheStoreInterface;
import com.xpn.xwiki.store.XWikiHibernateStore;
import com.xpn.xwiki.store.XWikiRecycleBinStoreInterface;
import com.xpn.xwiki.store.XWikiStoreInterface;
import com.xpn.xwiki.store.XWikiVersioningStoreInterface;
import com.xpn.xwiki.user.api.XWikiAuthService;
import com.xpn.xwiki.user.api.XWikiGroupService;
import com.xpn.xwiki.user.api.XWikiRightService;
import com.xpn.xwiki.user.api.XWikiUser;
import com.xpn.xwiki.user.impl.xwiki.XWikiAuthServiceImpl;
import com.xpn.xwiki.user.impl.xwiki.XWikiGroupServiceImpl;
import com.xpn.xwiki.user.impl.xwiki.XWikiRightServiceImpl;
import com.xpn.xwiki.util.Util;
import com.xpn.xwiki.util.XWikiStubContextProvider;
import com.xpn.xwiki.web.Utils;
import com.xpn.xwiki.web.XWikiEngineContext;
import com.xpn.xwiki.web.XWikiMessageTool;
import com.xpn.xwiki.web.XWikiRequest;
import com.xpn.xwiki.web.XWikiServletRequestStub;
import com.xpn.xwiki.web.XWikiURLFactory;
import com.xpn.xwiki.web.XWikiURLFactoryService;
import com.xpn.xwiki.web.XWikiURLFactoryServiceImpl;
import com.xpn.xwiki.web.includeservletasstring.IncludeServletAsString;
@Serializable(false)
public class XWiki implements EventListener
{
/** Name of the default wiki. */
public static final String DEFAULT_MAIN_WIKI = "xwiki";
/** Name of the default home space. */
public static final String DEFAULT_HOME_SPACE = "Main";
/** Name of the default system space. */
public static final String SYSTEM_SPACE = "XWiki";
/** Name of the default space homepage. */
public static final String DEFAULT_SPACE_HOMEPAGE = "WebHome";
public static final String CKEY_SKIN = InternalSkinManager.CKEY_SKIN;
public static final String CKEY_BASESKIN = InternalSkinManager.CKEY_PARENTSKIN;
public static final String DEFAULT_SKIN = InternalSkinConfiguration.DEFAULT_SKIN;
/** Logging helper object. */
protected static final Logger LOGGER = LoggerFactory.getLogger(XWiki.class);
/** Frequently used Document reference, the class which holds virtual wiki definitions. */
private static final DocumentReference VIRTUAL_WIKI_DEFINITION_CLASS_REFERENCE =
new DocumentReference(DEFAULT_MAIN_WIKI, SYSTEM_SPACE, "XWikiServerClass");
/** The default encoding, and the internally used encoding when dealing with byte representation of strings. */
public static final String DEFAULT_ENCODING = "UTF-8";
/** Represents no value (ie the default value will be used) in xproperties */
private static final String NO_VALUE = "---";
/**
* List of top level space names that can be used in the fake context document created when accessing a resource
* with the 'skin' action.
*/
private static final List<String> SKIN_RESOURCE_SPACE_NAMES = Arrays.asList("skins", "resources");
/** The main document storage. */
private XWikiStoreInterface store;
/** The attachment content storage. */
private XWikiAttachmentStoreInterface defaultAttachmentContentStore;
/** The attachment archive storage. */
private AttachmentVersioningStore defaultAttachmentArchiveStore;
/** Document versioning storage. */
private XWikiVersioningStoreInterface versioningStore;
/** Deleted documents storage. */
private XWikiRecycleBinStoreInterface recycleBinStore;
private AttachmentRecycleBinStore attachmentRecycleBinStore;
private XWikiPluginManager pluginManager;
private XWikiAuthService authService;
private XWikiRightService rightService;
private XWikiGroupService groupService;
private XWikiStatsService statsService;
private XWikiURLFactoryService urlFactoryService;
private XWikiCriteriaService criteriaService;
/** Lock object used for the lazy initialization of the authentication service. */
private final Object AUTH_SERVICE_LOCK = new Object();
/** Lock object used for the lazy initialization of the authorization service. */
private final Object RIGHT_SERVICE_LOCK = new Object();
/** Lock object used for the lazy initialization of the group management service. */
private final Object GROUP_SERVICE_LOCK = new Object();
/** Lock object used for the lazy initialization of the statistics service. */
private final Object STATS_SERVICE_LOCK = new Object();
/** Lock object used for the lazy initialization of the URL Factory service. */
private final Object URLFACTORY_SERVICE_LOCK = new Object();
private MetaClass metaclass;
private String version;
private XWikiEngineContext engine_context;
private String database;
private String fullNameSQL;
/**
* The list of initialized wikis.
*/
private Map<String, WikiInitializerJob> initializedWikis = new ConcurrentHashMap<>();
private boolean isReadOnly = false;
/**
* @deprecated since 6.1M2, use {@link XWikiCfgConfigurationSource#CFG_ENV_NAME} instead
*/
@Deprecated
public static final String CFG_ENV_NAME = XWikiCfgConfigurationSource.CFG_ENV_NAME;
public static final String MACROS_FILE = "/templates/macros.txt";
/**
* File containing XWiki's version, in the format: <version name>.<SVN revision number>.
*/
private static final String VERSION_FILE = "/WEB-INF/version.properties";
/**
* Property containing the version value in the {@link #VERSION_FILE} file.
*/
private static final String VERSION_FILE_PROPERTY = "version";
private static XWikiInitializerJob job;
/** List of configured syntax ids. */
private List<String> configuredSyntaxes;
/** Used to convert a proper Document Reference to string (standard form). */
private EntityReferenceSerializer<String> defaultEntityReferenceSerializer;
/**
* Used to resolve a string into a proper Document Reference using the current document's reference to fill the
* blanks, except for the page name for which the default page name is used instead.
*/
private DocumentReferenceResolver<String> currentMixedDocumentReferenceResolver;
private DocumentReferenceResolver<EntityReference> currentReferenceDocumentReferenceResolver;
private EntityReferenceResolver<String> currentMixedEntityReferenceResolver;
private EntityReferenceResolver<String> relativeEntityReferenceResolver;
private EntityReferenceSerializer<String> localStringEntityReferenceSerializer;
private ResourceReferenceManager resourceReferenceManager;
private JobExecutor jobExecutor;
private InternalSkinManager internalSkinManager;
private TemplateManager templateManager;
private RenderingContext renderingContext;
private VelocityEvaluator velocityEvaluator;
/**
* Whether backlinks are enabled or not (cached for performance).
*
* @since 3.2M2
*/
private Boolean hasBacklinks;
private ConfigurationSource xwikicfg;
private ConfigurationSource wikiConfiguration;
private ConfigurationSource userConfiguration;
private ConfigurationSource spaceConfiguration;
private EditConfiguration editConfiguration;
private StoreConfiguration storeConfiguration;
private ObservationManager observationManager;
private Provider<XWikiContext> xcontextProvider;
private ContextualLocalizationManager localization;
private Provider<OldRendering> oldRenderingProvider;
private ParseGroovyFromString parseGroovyFromString;
private JobProgressManager progress;
private Provider<DocumentReference> defaultDocumentReferenceProvider;
private DocumentReferenceResolver<EntityReference> currentgetdocumentResolver;
private PageReferenceResolver<EntityReference> currentgetpageResolver;
private AttachmentReferenceResolver<EntityReference> currentAttachmentReferenceResolver;
private WikiSkinUtils wikiSkinUtils;
private DocumentRevisionProvider documentRevisionProvider;
private WikiDescriptorManager wikiDescriptorManager;
private ConfigurationSource getConfiguration()
{
if (this.xwikicfg == null) {
this.xwikicfg = Utils.getComponent(ConfigurationSource.class, XWikiCfgConfigurationSource.ROLEHINT);
}
return this.xwikicfg;
}
private ConfigurationSource getWikiConfiguration()
{
if (this.wikiConfiguration == null) {
this.wikiConfiguration = Utils.getComponent(ConfigurationSource.class, "wiki");
}
return this.wikiConfiguration;
}
private ConfigurationSource getSpaceConfiguration()
{
if (this.spaceConfiguration == null) {
this.spaceConfiguration = Utils.getComponent(ConfigurationSource.class, "space");
}
return this.spaceConfiguration;
}
private ConfigurationSource getUserConfiguration()
{
if (this.userConfiguration == null) {
this.userConfiguration = Utils.getComponent(ConfigurationSource.class, "user");
}
return this.userConfiguration;
}
private EditConfiguration getEditConfiguration()
{
if (this.editConfiguration == null) {
this.editConfiguration = Utils.getComponent(EditConfiguration.class);
}
return this.editConfiguration;
}
private StoreConfiguration getStoreConfiguration()
{
if (this.storeConfiguration == null) {
this.storeConfiguration = Utils.getComponent(StoreConfiguration.class);
}
return this.storeConfiguration;
}
private InternalSkinManager getInternalSkinManager()
{
if (this.internalSkinManager == null) {
this.internalSkinManager = Utils.getComponent(InternalSkinManager.class);
}
return this.internalSkinManager;
}
private TemplateManager getTemplateManager()
{
if (this.templateManager == null) {
this.templateManager = Utils.getComponent(TemplateManager.class);
}
return this.templateManager;
}
private RenderingContext getRenderingContext()
{
if (this.renderingContext == null) {
this.renderingContext = Utils.getComponent(RenderingContext.class);
}
return this.renderingContext;
}
private MutableRenderingContext getMutableRenderingContext()
{
return getRenderingContext() instanceof MutableRenderingContext
? (MutableRenderingContext) getRenderingContext() : null;
}
private VelocityEvaluator getVelocityEvaluator()
{
if (this.velocityEvaluator == null) {
this.velocityEvaluator = Utils.getComponent(VelocityEvaluator.class);
}
return this.velocityEvaluator;
}
private ObservationManager getObservationManager()
{
if (this.observationManager == null) {
this.observationManager = Utils.getComponent(ObservationManager.class);
}
return this.observationManager;
}
private XWikiContext getXWikiContext()
{
if (this.xcontextProvider == null) {
this.xcontextProvider = Utils.getComponent(XWikiContext.TYPE_PROVIDER);
}
return this.xcontextProvider.get();
}
private ContextualLocalizationManager getLocalization()
{
if (this.localization == null) {
this.localization = Utils.getComponent(ContextualLocalizationManager.class);
}
return this.localization;
}
private OldRendering getOldRendering()
{
if (this.oldRenderingProvider == null) {
this.oldRenderingProvider = Utils.getComponent(OldRendering.TYPE_PROVIDER);
}
return this.oldRenderingProvider.get();
}
private ParseGroovyFromString getParseGroovyFromString()
{
if (this.parseGroovyFromString == null) {
this.parseGroovyFromString = Utils.getComponent(ParseGroovyFromString.class);
}
return this.parseGroovyFromString;
}
private JobProgressManager getProgress()
{
if (this.progress == null) {
this.progress = Utils.getComponent(JobProgressManager.class);
}
return this.progress;
}
private Provider<DocumentReference> getDefaultDocumentReferenceProvider()
{
if (this.defaultDocumentReferenceProvider == null) {
this.defaultDocumentReferenceProvider = Utils.getComponent(DocumentReference.TYPE_PROVIDER);
}
return this.defaultDocumentReferenceProvider;
}
private DocumentReferenceResolver<EntityReference> getCurrentGetDocumentResolver()
{
if (this.currentgetdocumentResolver == null) {
this.currentgetdocumentResolver =
Utils.getComponent(DocumentReferenceResolver.TYPE_REFERENCE, "currentgetdocument");
}
return this.currentgetdocumentResolver;
}
private PageReferenceResolver<EntityReference> getCurrentGetPageResolver()
{
if (this.currentgetpageResolver == null) {
this.currentgetpageResolver = Utils.getComponent(PageReferenceResolver.TYPE_REFERENCE, "currentgetpage");
}
return this.currentgetpageResolver;
}
private AttachmentReferenceResolver<EntityReference> getCurrentAttachmentResolver()
{
if (this.currentAttachmentReferenceResolver == null) {
this.currentAttachmentReferenceResolver =
Utils.getComponent(AttachmentReferenceResolver.TYPE_REFERENCE, "current");
}
return this.currentAttachmentReferenceResolver;
}
private EntityReferenceSerializer<String> getDefaultEntityReferenceSerializer()
{
if (this.defaultEntityReferenceSerializer == null) {
this.defaultEntityReferenceSerializer = Utils.getComponent(EntityReferenceSerializer.TYPE_STRING);
}
return this.defaultEntityReferenceSerializer;
}
private DocumentReferenceResolver<String> getCurrentMixedDocumentReferenceResolver()
{
if (this.currentMixedDocumentReferenceResolver == null) {
this.currentMixedDocumentReferenceResolver =
Utils.getComponent(DocumentReferenceResolver.TYPE_STRING, "currentmixed");
}
return this.currentMixedDocumentReferenceResolver;
}
private DocumentReferenceResolver<EntityReference> getCurrentReferenceDocumentReferenceResolver()
{
if (this.currentReferenceDocumentReferenceResolver == null) {
this.currentReferenceDocumentReferenceResolver =
Utils.getComponent(DocumentReferenceResolver.TYPE_REFERENCE, "current");
}
return this.currentReferenceDocumentReferenceResolver;
}
private EntityReferenceResolver<String> getCurrentMixedEntityReferenceResolver()
{
if (this.currentMixedEntityReferenceResolver == null) {
this.currentMixedEntityReferenceResolver =
Utils.getComponent(EntityReferenceResolver.TYPE_STRING, "currentmixed");
}
return this.currentMixedEntityReferenceResolver;
}
private EntityReferenceResolver<String> getRelativeEntityReferenceResolver()
{
if (this.relativeEntityReferenceResolver == null) {
this.relativeEntityReferenceResolver = Utils.getComponent(EntityReferenceResolver.TYPE_STRING, "relative");
}
return this.relativeEntityReferenceResolver;
}
private EntityReferenceSerializer<String> getLocalStringEntityReferenceSerializer()
{
if (this.localStringEntityReferenceSerializer == null) {
this.localStringEntityReferenceSerializer =
Utils.getComponent(EntityReferenceSerializer.TYPE_STRING, "local");
}
return this.localStringEntityReferenceSerializer;
}
private ResourceReferenceManager getResourceReferenceManager()
{
if (this.resourceReferenceManager == null) {
this.resourceReferenceManager = Utils.getComponent(ResourceReferenceManager.class);
}
return this.resourceReferenceManager;
}
private JobExecutor getJobExecutor()
{
if (this.jobExecutor == null) {
this.jobExecutor = Utils.getComponent(JobExecutor.class);
}
return this.jobExecutor;
}
private DocumentReference getDefaultDocumentReference()
{
return getDefaultDocumentReferenceProvider().get();
}
private WikiSkinUtils getWikiSkinUtils()
{
if (this.wikiSkinUtils == null) {
this.wikiSkinUtils = Utils.getComponent(WikiSkinUtils.class);
}
return this.wikiSkinUtils;
}
private DocumentRevisionProvider getDocumentRevisionProvider()
{
if (this.documentRevisionProvider == null) {
this.documentRevisionProvider = Utils.getComponent(DocumentRevisionProvider.class);
}
return this.documentRevisionProvider;
}
private WikiDescriptorManager getWikiDescriptorManager()
{
if (this.wikiDescriptorManager == null) {
this.wikiDescriptorManager = Utils.getComponent(WikiDescriptorManager.class);
}
return this.wikiDescriptorManager;
}
private String localizePlainOrKey(String key, Object... parameters)
{
return StringUtils.defaultString(getLocalization().getTranslationPlain(key, parameters), key);
}
/**
* @param context see {@link XWikiContext}
*/
public static XWiki getMainXWiki(XWikiContext context) throws XWikiException
{
return getMainXWiki(true, context);
}
/**
* @param wait true if the method should way for {@link XWiki} instance to be initialized
* @param context see {@link XWikiContext}
*/
public static XWiki getMainXWiki(boolean wait, XWikiContext context) throws XWikiException
{
String xwikiname = DEFAULT_MAIN_WIKI;
context.setMainXWiki(xwikiname);
XWiki xwiki;
try {
XWikiEngineContext econtext = context.getEngineContext();
xwiki = (XWiki) econtext.getAttribute(xwikiname);
if (xwiki == null) {
// Start XWiki initialization
synchronized (XWiki.class) {
xwiki = (XWiki) econtext.getAttribute(xwikiname);
if (xwiki == null && job == null) {
job = Utils.getComponent((Type) Job.class, XWikiInitializerJob.JOBTYPE);
if (job.getStatus() == null) {
// "Pre-initialize" XWikiStubContextProvider so that XWiki initializer can find one
Utils.<XWikiStubContextProvider>getComponent(XWikiStubContextProvider.class)
.initialize(context);
job.startAsync();
}
}
}
// Wait until XWiki is initialized
if (wait) {
job.join();
xwiki = (XWiki) econtext.getAttribute(xwikiname);
}
}
context.setWiki(xwiki);
return xwiki;
} catch (Exception e) {
throw new XWikiException(XWikiException.MODULE_XWIKI, XWikiException.ERROR_XWIKI_INIT_FAILED,
"Could not initialize main XWiki instance", e);
}
}
public static boolean isInitializing(XWikiContext xcontext)
{
return Boolean.TRUE.equals(xcontext.getEngineContext().getAttribute("xwiki.init"));
}
/**
* Return the XWiki object (as in "the Wiki API") corresponding to the requested wiki.
*
* @param context see {@link XWikiContext}
* @return an XWiki object configured for the wiki corresponding to the current request
* @throws XWikiException if the requested URL does not correspond to a real wiki, or if there's an error in the
* storage
*/
public static XWiki getXWiki(XWikiContext context) throws XWikiException
{
return getXWiki(true, context);
}
/**
* Return the XWiki object (as in "the Wiki API") corresponding to the requested wiki.
* <p>
* Unless <code>wait</code> is false the method return right away null if XWiki is not yet initialized.
*
* @param wait wait until XWiki is initialized
* @param xcontext see {@link XWikiContext}
* @return an XWiki object configured for the wiki corresponding to the current request
* @throws XWikiException if the requested URL does not correspond to a real wiki, or if there's an error in the
* storage
*/
public static XWiki getXWiki(boolean wait, XWikiContext xcontext) throws XWikiException
{
XWiki xwiki = getMainXWiki(wait, xcontext);
if (xwiki == null) {
return null;
}
// Extract Entity Resource from URL and put it in the Execution Context
EntityResourceReference entityResourceReference = initializeResourceFromURL(xcontext);
// If not an entity resource reference assume main wiki
if (entityResourceReference == null) {
return xwiki;
}
// Get the wiki id
String wikiId = entityResourceReference.getEntityReference().extractReference(EntityType.WIKI).getName();
if (wikiId.equals(xcontext.getMainXWiki())) {
// The main wiki was requested.
return xwiki;
}
// Check if the wiki exists by checking if a descriptor exists for the wiki id.
WikiDescriptorManager wikiDescriptorManager = Utils.getComponent(WikiDescriptorManager.class);
WikiDescriptor descriptor;
try {
descriptor = wikiDescriptorManager.getById(wikiId);
} catch (WikiManagerException e) {
throw new XWikiException(XWikiException.MODULE_XWIKI, XWikiException.ERROR_XWIKI_STORE_MISC,
String.format("Failed find wiki descriptor for wiki id [%s]", wikiId), e);
}
if (descriptor == null) {
throw new XWikiException(XWikiException.MODULE_XWIKI, XWikiException.ERROR_XWIKI_DOES_NOT_EXIST,
String.format("The wiki [%s] does not exist", wikiId));
}
// Initialize wiki
xcontext.setWikiId(wikiId);
xcontext.setOriginalWikiId(wikiId);
if (!xwiki.initializeWiki(wikiId, wait, xcontext)) {
// The wiki is still initializing
return null;
}
return xwiki;
}
/**
* @param wikiId the identifier of the wiki
* @return the current {@link WikiInitializerJob} associated to the passed wiki or null if there is none
*/
public Job getWikiInitializerJob(String wikiId)
{
return this.initializedWikis.get(wikiId);
}
/**
* Make sure the wiki is initializing or wait for it.
*
* @param wikiId the identifier of the wiki to initialize
* @param wait true if the method should return only when the wiki is fully initialized
* @return true if the wiki is fully initialized
* @param xcontext the XWiki context
* @throws XWikiException when the initialization failed
* @since 8.4RC1
*/
public boolean initializeWiki(String wikiId, boolean wait, XWikiContext xcontext) throws XWikiException
{
Job wikiJob = this.initializedWikis.get(wikiId);
// Create and start the job if it does not exist
if (wikiJob == null) {
try {
wikiJob = initializeWiki(wikiId, xcontext);
} catch (JobException e) {
throw new XWikiException(XWikiException.MODULE_XWIKI, XWikiException.ERROR_XWIKI_INIT_FAILED,
"Could not start [" + wikiId + "] wiki initialization", e);
}
}
// Check if the job is done
if (wikiJob.getStatus().getState() == State.FINISHED) {
return true;
}
// Wait until the job is finished if asked to
if (wait) {
try {
wikiJob.join();
} catch (InterruptedException e) {
throw new XWikiException(XWikiException.MODULE_XWIKI, XWikiException.ERROR_XWIKI_INIT_FAILED,
"Wiki [" + wikiId + "] initialization was interrupted unexpectedly", e);
}
if (wikiJob.getStatus().getError() != null) {
throw new XWikiException(XWikiException.MODULE_XWIKI, XWikiException.ERROR_XWIKI_INIT_FAILED,
"Wiki [" + wikiId + "] initialization failed", wikiJob.getStatus().getError());
}
return true;
}
// Still initializing
return false;
}
private Job initializeWiki(String wikiId, XWikiContext xcontext) throws JobException
{
synchronized (this.initializedWikis) {
WikiInitializerJob wikiJob = this.initializedWikis.get(wikiId);
if (wikiJob == null) {
WikiInitializerRequest request = new WikiInitializerRequest(wikiId);
JobRequestContext.set(request, xcontext);
wikiJob = (WikiInitializerJob) getJobExecutor().execute(WikiInitializerJob.JOBTYPE, request);
this.initializedWikis.put(wikiId, wikiJob);
}
return wikiJob;
}
}
private static EntityResourceReference initializeResourceFromURL(XWikiContext context) throws XWikiException
{
// Extract the Entity Resource from the URL
// TODO: This code should be put in an ExecutionContextInitializer but we couldn't do yet since this code
// requires that the XWiki object be initialized first (the line above). Thus we'll be able to to move it only
// after the XWiki init is done also in an ExecutionContextInitializer (and with priorities).
@SuppressWarnings("deprecation")
EntityResourceReference entityResourceReference;
URL url = context.getURL();
try {
ExtendedURL extendedURL = new ExtendedURL(url, context.getRequest().getContextPath());
ResourceTypeResolver<ExtendedURL> typeResolver =
Utils.getComponent(new DefaultParameterizedType(null, ResourceTypeResolver.class, ExtendedURL.class));
ResourceType type = typeResolver.resolve(extendedURL, Collections.<String, Object>emptyMap());
ResourceReferenceResolver<ExtendedURL> resourceResolver = Utils
.getComponent(new DefaultParameterizedType(null, ResourceReferenceResolver.class, ExtendedURL.class));
ResourceReference reference =
resourceResolver.resolve(extendedURL, type, Collections.<String, Object>emptyMap());
entityResourceReference =
reference instanceof EntityResourceReference ? (EntityResourceReference) reference : null;
} catch (Exception e) {
throw new XWikiException(XWikiException.MODULE_XWIKI, XWikiException.ERROR_XWIKI_APP_URL_EXCEPTION,
String.format("Failed to extract Entity Resource Reference from URL [%s]", url), e);
}
Utils.getComponent(Execution.class).getContext().setProperty(ResourceReferenceManager.RESOURCE_CONTEXT_PROPERTY,
entityResourceReference);
return entityResourceReference;
}
public static URL getRequestURL(XWikiRequest request) throws XWikiException
{
try {
StringBuffer requestURL = request.getRequestURL();
String qs = request.getQueryString();
if ((qs != null) && (!qs.equals(""))) {
return new URL(requestURL.toString() + "?" + qs);
} else {
return new URL(requestURL.toString());
}
} catch (Exception e) {
throw new XWikiException(XWikiException.MODULE_XWIKI_APP, XWikiException.ERROR_XWIKI_APP_URL_EXCEPTION,
"Exception while getting URL from request", e);
}
}
public static Object callPrivateMethod(Object obj, String methodName)
{
return callPrivateMethod(obj, methodName, null, null);
}
public static Object callPrivateMethod(Object obj, String methodName, Class<?>[] classes, Object[] args)
{
try {
Method method = obj.getClass().getDeclaredMethod(methodName, classes);
method.setAccessible(true);
return method.invoke(obj, args);
} catch (IllegalAccessException e) {
LOGGER.error("Failed to call private method [{}]: [{}]", methodName, e);
return null;
} catch (NoSuchMethodException e) {
return null;
} catch (InvocationTargetException e) {
LOGGER.error("Private method [{}] failed: [{}]", methodName, e);
return null;
}
}
public static HttpClient getHttpClient(int timeout, String userAgent)
{
HttpClient client = new HttpClient();
if (timeout != 0) {
client.getParams().setSoTimeout(timeout);
client.getParams().setParameter("http.connection.timeout", Integer.valueOf(timeout));
}
client.getParams().setParameter("http.useragent", userAgent);
String proxyHost = System.getProperty("http.proxyHost");
String proxyPort = System.getProperty("http.proxyPort");
if ((proxyHost != null) && (!proxyHost.equals(""))) {
int port = 3128;
if ((proxyPort != null) && (!proxyPort.equals(""))) {
port = Integer.parseInt(proxyPort);
}
client.getHostConfiguration().setProxy(proxyHost, port);
}
String proxyUser = System.getProperty("http.proxyUser");
if ((proxyUser != null) && (!proxyUser.equals(""))) {
String proxyPassword = System.getProperty("http.proxyPassword");
Credentials defaultcreds = new UsernamePasswordCredentials(proxyUser, proxyPassword);
client.getState().setProxyCredentials(AuthScope.ANY, defaultcreds);
}
return client;
}
/**
* Using reflection, read the private value of the passed field name for the passed object.
*
* @param obj the java object on which to read the private field value
* @param fieldName the object member field for which to read the value
* @return the private value for the field
* @deprecated use {@link FieldUtils#readDeclaredField(Object, String, boolean)} instead
*/
@Deprecated
public static Object getPrivateField(Object obj, String fieldName)
{
try {
Field field = obj.getClass().getDeclaredField(fieldName);
field.setAccessible(true);
return field.get(obj);
} catch (NoSuchFieldException e) {
return null;
} catch (IllegalAccessException e) {
LOGGER.error("Failed to get private field with name [{}]: [{}]", fieldName, e);
return null;
} finally {
}
}
public static String getServerWikiPage(String servername)
{
return "XWiki.XWikiServer" + StringUtils.capitalize(servername);
}
/**
* @param content the content of the text area
* @param context see {@link XWikiContext}
*/
public static String getTextArea(String content, XWikiContext context)
{
StringBuilder result = new StringBuilder();
// Forcing a new line after the <textarea> tag, as
// http://www.w3.org/TR/html4/appendix/notes.html#h-B.3.1 causes an empty line at the start
// of the document content to be trimmed.
result.append("<textarea name=\"content\" id=\"content\" rows=\"25\" cols=\"80\">\n");
result.append(XMLUtils.escape(content));
result.append("</textarea>");
return result.toString();
}
/**
* This provide a way to create an XWiki object without initializing the whole XWiki (including plugins, storage,
* etc.).
* <p>
* Needed for tools or tests which need XWiki because it is used everywhere in the API.
*/
public XWiki()
{
// Empty voluntarily
}
/**
* Initialize all xwiki subsystems.
*
* @param context see {@link XWikiContext}
* @param engineContext the XWiki object wrapping the {@link javax.servlet.ServletContext} and which allows to set
* data that live on as long as the XWiki webapp is not stopped in the Servlet Container
* @param noupdate true if the whole initialization should be done (create mandatory xlcasses, initialize stats
* service), i.e. if this is not an update, and false otherwise
* @throws XWikiException if an error happened during initialization (failure to initialize some cache for example)
*/
public XWiki(XWikiContext context, XWikiEngineContext engineContext, boolean noupdate) throws XWikiException
{
initXWiki(context, engineContext, noupdate);
}
/**
* Initialize all xwiki subsystems.
*
* @param context see {@link XWikiContext}
* @throws XWikiException if an error happened during initialization (failure to initialize some cache for example)
*/
public XWiki(XWikiContext context) throws XWikiException
{
this(context, null, false);
}
/**
* Initialize all xwiki subsystems.
*
* @param context see {@link XWikiContext}
* @param engineContext the XWiki object wrapping the {@link javax.servlet.ServletContext} and which allows to set
* data that live on as long as the XWiki webapp is not stopped in the Servlet Container
* @param noupdate true if the whole initialization should be done (create mandatory xlcasses, initialize stats
* service), i.e. if this is not an update, and false otherwise
* @throws XWikiException if an error happened during initialization (failure to initialize some cache for example)
*/
public void initXWiki(XWikiContext context, XWikiEngineContext engineContext, boolean noupdate)
throws XWikiException
{
initXWiki(null, context, engineContext, noupdate);
}
/**
* Initialize all xwiki subsystems.
*
* @param config the object holding the XWiki configuration read from {@code xwiki.cfg}
* @param context see {@link XWikiContext}
* @param engineContext the XWiki object wrapping the {@link javax.servlet.ServletContext} and which allows to set
* data that live on as long as the XWiki webapp is not stopped in the Servlet Container
* @param noupdate true if the whole initialization should be done (create mandatory xlcasses, initialize stats
* service), i.e. if this is not an update, and false otherwise
* @throws XWikiException if an error happened during initialization (failure to initialize some cache for example)
* @deprecated since 6.1M2, use {@link #initXWiki(XWikiContext, XWikiEngineContext, boolean)} instead
*/
@Deprecated
public void initXWiki(XWikiConfig config, XWikiContext context, XWikiEngineContext engineContext, boolean noupdate)
throws XWikiException
{
getProgress().pushLevelProgress(4, this);
try {
getProgress().startStep(this);
setDatabase(context.getMainXWiki());
setEngineContext(engineContext);
context.setWiki(this);
// "Pre-initialize" XWikiStubContextProvider with a XWikiContext containing a XWiki instance as soon as
// possible
Utils.<XWikiStubContextProvider>getComponent(XWikiStubContextProvider.class).initialize(context);
// Prepare the store
if (config != null) {
setConfig(config);
}
try {
initializeStores();
} catch (ComponentLookupException e) {
throw new XWikiException(XWikiException.MODULE_XWIKI_STORE, XWikiException.ERROR_XWIKI_UNKNOWN,
"Failed to initialize stores", e);
}
setCriteriaService((XWikiCriteriaService) createClassFromConfig("xwiki.criteria.class",
"com.xpn.xwiki.criteria.impl.XWikiCriteriaServiceImpl", context));
// "Pre-initialize" XWikiStubContextProvider so that rendering engine, plugins or listeners reacting to
// potential document changes can use it
Utils.<XWikiStubContextProvider>getComponent(XWikiStubContextProvider.class).initialize(context);
getProgress().endStep(this);
getProgress().startStep(this);
// Make sure these classes exists
if (noupdate) {
initializeMandatoryDocuments(context);
getStatsService(context);
}
getProgress().endStep(this);
getProgress().startStep(this);
// Prepare the Plugin Engine
preparePlugins(context);
getProgress().endStep(this);
getProgress().startStep(this);
String ro = getConfiguration().getProperty("xwiki.readonly", "no");
this.isReadOnly = ("yes".equalsIgnoreCase(ro) || "true".equalsIgnoreCase(ro) || "1".equalsIgnoreCase(ro));
// Save the configured syntaxes
String syntaxes = getConfiguration().getProperty("xwiki.rendering.syntaxes", "xwiki/1.0");
this.configuredSyntaxes = Arrays.asList(StringUtils.split(syntaxes, " ,"));
getObservationManager().addListener(this);
} finally {
getProgress().popLevelProgress(this);
}
}
private void initializeStores() throws ComponentLookupException
{
XWikiStoreInterface mainStore = getStoreConfiguration().getXWikiStore();
// Check if we need to use the cache store..
if (getStoreConfiguration().isStoreCacheEnabled()) {
XWikiCacheStoreInterface cachestore =
(XWikiCacheStoreInterface) Utils.getComponent(XWikiStoreInterface.class, "cache");
cachestore.setStore(mainStore);
setStore(cachestore);
} else {
setStore(mainStore);
}
setDefaultAttachmentContentStore(getStoreConfiguration().getXWikiAttachmentStore());
setVersioningStore(getStoreConfiguration().getXWikiVersioningStore());
setDefaultAttachmentArchiveStore(getStoreConfiguration().getAttachmentVersioningStore());
setRecycleBinStore(getStoreConfiguration().getXWikiRecycleBinStore());
setAttachmentRecycleBinStore(getStoreConfiguration().getAttachmentRecycleBinStore());
}
/**
* Ensure that mandatory classes (ie classes XWiki needs to work properly) exist and create them if they don't
* exist.
*
* @param context see {@link XWikiContext}
*/
public void initializeMandatoryDocuments(XWikiContext context)
{
if (context.get("initdone") == null) {
@SuppressWarnings("deprecation")
List<MandatoryDocumentInitializer> initializers =
Utils.getComponentList(MandatoryDocumentInitializer.class);
// Sort the initializers based on priority. Lower priority values are first.
Collections.sort(initializers, new Comparator<MandatoryDocumentInitializer>()
{
@Override
public int compare(MandatoryDocumentInitializer left, MandatoryDocumentInitializer right)
{
Priority leftPriority = left.getClass().getAnnotation(Priority.class);
int leftPriorityValue =
leftPriority != null ? leftPriority.value() : MandatoryDocumentInitializer.DEFAULT_PRIORITY;
Priority rightPriority = right.getClass().getAnnotation(Priority.class);
int rightPriorityValue =
rightPriority != null ? rightPriority.value() : MandatoryDocumentInitializer.DEFAULT_PRIORITY;
// Compare the two.
return leftPriorityValue - rightPriorityValue;
}
});
for (MandatoryDocumentInitializer initializer : initializers) {
initializeMandatoryDocument(initializer, context);
}
}
}
private void initializeMandatoryDocument(String wiki, MandatoryDocumentInitializer initializer,
XWikiContext context)
{
String currentWiki = context.getWikiId();
try {
context.setWikiId(wiki);
initializeMandatoryDocument(initializer, context);
} finally {
context.setWikiId(currentWiki);
}
}
private void initializeMandatoryDocument(MandatoryDocumentInitializer initializer, XWikiContext context)
{
try {
DocumentReference documentReference =
getCurrentReferenceDocumentReferenceResolver().resolve(initializer.getDocumentReference());
if (documentReference.getWikiReference().getName().equals(context.getWikiId())) {
XWikiDocument document = context.getWiki().getDocument(documentReference, context);
if (initializer.updateDocument(document)) {
saveDocument(document,
localizePlainOrKey("core.model.xclass.mandatoryUpdateProperty.versionSummary"), context);
}
}
} catch (XWikiException e) {
LOGGER.error("Failed to initialize mandatory document", e);
}
}
public XWikiStoreInterface getNotCacheStore()
{
XWikiStoreInterface store = getStore();
if (store instanceof XWikiCacheStoreInterface) {
store = ((XWikiCacheStoreInterface) store).getStore();
}
return store;
}
public XWikiHibernateStore getHibernateStore()
{
XWikiStoreInterface store = getStore();
if (store instanceof XWikiHibernateStore) {
return (XWikiHibernateStore) store;
} else if (store instanceof XWikiCacheStoreInterface) {
store = ((XWikiCacheStoreInterface) store).getStore();
if (store instanceof XWikiHibernateStore) {
return (XWikiHibernateStore) store;
} else {
return null;
}
} else {
return null;
}
}
/**
* @param wikiId the id of the wiki
* @param context see {@link XWikiContext}
* @deprecated since 8.4RC1, use {@link #initializeWiki(String, boolean, XWikiContext)} instead
*/
@Deprecated
public void updateDatabase(String wikiId, XWikiContext context) throws HibernateException, XWikiException
{
updateDatabase(wikiId, false, context);
}
/**
* @param wikiId the id of the wiki
* @param context see {@link XWikiContext}
* @deprecated since 8.4RC1, use {@link #initializeWiki(String, boolean, XWikiContext)} instead
*/
@Deprecated
public void updateDatabase(String wikiId, boolean force, XWikiContext context)
throws HibernateException, XWikiException
{
updateDatabase(wikiId, force, true, context);
}
/**
* @param wikiId the id of the wiki
* @param force if the update of the databse should be forced
* @param initDocuments if mandatory document and plugin should be initialized for passed wiki
* @param context see {@link XWikiContext}
* @deprecated since 8.4RC1, use {@link #initializeWiki(String, boolean, XWikiContext)} instead
*/
@Deprecated
public void updateDatabase(String wikiId, boolean force, boolean initDocuments, XWikiContext context)
throws HibernateException, XWikiException
{
initializeWiki(wikiId, true, context);
}
/**
* @return a cached list of all active virtual wikis (i.e. wikis who have been hit by a user request). To get a full
* list of all virtual wikis database names use {@link WikiDescriptorManager#getAllIds()}.
* @deprecated
*/
@Deprecated
public List<String> getVirtualWikiList()
{
return new ArrayList<>(this.initializedWikis.keySet());
}
/**
* @param context see {@link XWikiContext}
* @return the full list of all wiki names of all defined wikis. The wiki names are computed from the names of
* documents having a {@code XWiki.XWikiServerClass} object attached to them by removing the
* {@code XWiki.XWikiServer} prefix and making it lower case. For example a page named
* {@code XWiki.XWikiServerMyDatabase} would return {@code mydatabase} as the wiki name. This list will also
* contain the main wiki.
* <p>
* Note: the wiki name is commonly also the name of the database where the wiki's data is stored. However,
* if configured accordingly, the database can be diferent from the wiki name, like for example when setting
* a wiki database prefix.
* @deprecated since 5.3, use {@link WikiDescriptorManager#getAllIds()} instead
*/
@Deprecated
public List<String> getVirtualWikisDatabaseNames(XWikiContext context) throws XWikiException
{
WikiDescriptorManager descriptorManager = Utils.getComponent(WikiDescriptorManager.class);
try {
return new ArrayList<String>(descriptorManager.getAllIds());
} catch (WikiManagerException e) {
throw new XWikiException(XWikiException.MODULE_XWIKI, XWikiException.ERROR_XWIKI_UNKNOWN,
"Failed to get the list of wikis", e);
}
}
/**
* @return the cache containing the names of the wikis already initialized.
* @since 1.5M2.
* @deprecated
*/
@Deprecated
public Cache<DocumentReference> getVirtualWikiCache()
{
return null;
}
/**
* Get the reference of the owner for the provider wiki.
*
* @param wikiName the technical name of the wiki
* @param context see {@link XWikiContext}
* @return the wiki owner or null if none is set
* @throws XWikiException failed to get wiki descriptor document
*/
public String getWikiOwner(String wikiName, XWikiContext context) throws XWikiException
{
String wikiOwner;
String currentdatabase = context.getWikiId();
try {
context.setWikiId(context.getMainXWiki());
String serverwikipage = getServerWikiPage(wikiName);
XWikiDocument doc = getDocument(serverwikipage, context);
if (doc.isNew()) {
if (!context.isMainWiki(wikiName)) {
throw new XWikiException(XWikiException.MODULE_XWIKI, XWikiException.ERROR_XWIKI_DOES_NOT_EXIST,
"The wiki " + wikiName + " does not exist");
} else {
wikiOwner = null;
}
} else {
wikiOwner = doc.getStringValue(VIRTUAL_WIKI_DEFINITION_CLASS_REFERENCE, "owner");
if (wikiOwner.indexOf(':') == -1) {
wikiOwner = context.getMainXWiki() + ":" + wikiOwner;
}
}
} finally {
context.setWikiId(currentdatabase);
}
return wikiOwner;
}
/**
* @param context see {@link XWikiContext}
*/
protected Object createClassFromConfig(String param, String defClass, XWikiContext context) throws XWikiException
{
String storeclass = getConfiguration().getProperty(param, defClass);
try {
Class<?>[] classes = new Class<?>[] { XWikiContext.class };
Object[] args = new Object[] { context };
Object result = Class.forName(storeclass).getConstructor(classes).newInstance(args);
return result;
} catch (Exception e) {
Throwable ecause = e;
if (e instanceof InvocationTargetException) {
ecause = ((InvocationTargetException) e).getTargetException();
}
Object[] args = { param, storeclass };
throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
XWikiException.ERROR_XWIKI_STORE_CLASSINVOCATIONERROR, "Cannot load class {1} from param {0}", ecause,
args);
}
}
private void preparePlugins(XWikiContext context)
{
setPluginManager(new XWikiPluginManager(getXWikiPreference("plugins", context), context));
String plugins = getConfiguration().getProperty("xwiki.plugins", "");
if (!plugins.equals("")) {
getPluginManager().addPlugins(StringUtils.split(plugins, " ,"), context);
}
}
/**
* @return the XWiki core version as specified in the {@link #VERSION_FILE} file
*/
@SuppressWarnings("deprecation")
public String getVersion()
{
if (this.version == null) {
try {
InputStream is = getResourceAsStream(VERSION_FILE);
try {
XWikiConfig properties = new XWikiConfig(is);
this.version = properties.getProperty(VERSION_FILE_PROPERTY);
} finally {
IOUtils.closeQuietly(is);
}
} catch (Exception e) {
// Failed to retrieve the version, log a warning and default to "Unknown"
LOGGER.warn("Failed to retrieve XWiki's version from [" + VERSION_FILE + "], using the ["
+ VERSION_FILE_PROPERTY + "] property.", e);
this.version = "Unknown version";
}
}
return this.version;
}
public URL getResource(String s) throws MalformedURLException
{
return getEngineContext().getResource(s);
}
public InputStream getResourceAsStream(String s) throws MalformedURLException
{
InputStream is = getEngineContext().getResourceAsStream(s);
if (is == null) {
is = getEngineContext().getResourceAsStream("/" + s);
}
return is;
}
public String getResourceContent(String name) throws IOException
{
if (getEngineContext() != null) {
try (InputStream is = getResourceAsStream(name)) {
if (is != null) {
return IOUtils.toString(is, DEFAULT_ENCODING);
}
}
}
// Resources should always be encoded as UTF-8, to reduce the dependency on the system encoding
return FileUtils.readFileToString(new File(name), DEFAULT_ENCODING);
}
public Date getResourceLastModificationDate(String name)
{
try {
if (getEngineContext() != null) {
return Util.getFileLastModificationDate(getEngineContext().getRealPath(name));
}
} catch (Exception ex) {
// Probably a SecurityException or the file is not accessible (inside a war)
LOGGER.info("Failed to get file modification date: " + ex.getMessage());
}
return new Date();
}
public byte[] getResourceContentAsBytes(String name) throws IOException
{
if (getEngineContext() != null) {
try (InputStream is = getResourceAsStream(name)) {
if (is != null) {
return IOUtils.toByteArray(is);
}
} catch (Exception e) {
}
}
return FileUtils.readFileToByteArray(new File(name));
}
public boolean resourceExists(String name)
{
if (getEngineContext() != null) {
try {
if (getResource(name) != null) {
return true;
}
} catch (IOException e) {
}
}
try {
File file = new File(name);
return file.exists();
} catch (Exception e) {
// Could be running under -security, which prevents calling file.exists().
}
return false;
}
public String getRealPath(String path)
{
return getEngineContext().getRealPath(path);
}
public String ParamAsRealPath(String key)
{
String param = getConfiguration().getProperty(key);
try {
return getRealPath(param);
} catch (Exception e) {
return param;
}
}
/**
* @param context see {@link XWikiContext}
*/
public String ParamAsRealPath(String key, XWikiContext context)
{
return ParamAsRealPath(key);
}
public String ParamAsRealPathVerified(String param)
{
String path;
File fpath;
path = getConfiguration().getProperty(param);
if (path == null) {
return null;
}
fpath = new File(path);
if (fpath.exists()) {
return path;
}
path = getRealPath(path);
if (path == null) {
return null;
}
fpath = new File(path);
if (fpath.exists()) {
return path;
} else {
}
return null;
}
public XWikiStoreInterface getStore()
{
return this.store;
}
/**
* @deprecated since 9.9RC1, use {@link #getDefaultAttachmentContentStore()} instead
*/
@Deprecated
public XWikiAttachmentStoreInterface getAttachmentStore()
{
return getDefaultAttachmentContentStore();
}
/**
* @return the store to use by default when saving a new attachment content
* @since 9.10RC1
*/
public XWikiAttachmentStoreInterface getDefaultAttachmentContentStore()
{
return this.defaultAttachmentContentStore;
}
/**
* @return the store to use by default when saving a new attachment archive
* @since 9.10RC1
*/
public AttachmentVersioningStore getDefaultAttachmentArchiveStore()
{
return this.defaultAttachmentArchiveStore;
}
/**
* @deprecated since 9.9RC1, use {@link #getDefaultAttachmentArchiveStore()} instead
*/
@Deprecated
public AttachmentVersioningStore getAttachmentVersioningStore()
{
return getDefaultAttachmentArchiveStore();
}
public XWikiVersioningStoreInterface getVersioningStore()
{
return this.versioningStore;
}
public XWikiRecycleBinStoreInterface getRecycleBinStore()
{
return this.recycleBinStore;
}
public AttachmentRecycleBinStore getAttachmentRecycleBinStore()
{
return this.attachmentRecycleBinStore;
}
/**
* @param doc the document to save
* @param context see {@link XWikiContext}
*/
public void saveDocument(XWikiDocument doc, XWikiContext context) throws XWikiException
{
// If no comment is provided we should use an empty comment
saveDocument(doc, "", context);
}
/**
* @param doc the document to save
* @param comment the comment to associated to the new version of the saved document
* @param context see {@link XWikiContext}
*/
public void saveDocument(XWikiDocument doc, String comment, XWikiContext context) throws XWikiException
{
saveDocument(doc, comment, false, context);
}
/**
* @param document the document to save
* @param comment the comment to associated to the new version of the saved document
* @param isMinorEdit true if the new version is a minor version
* @param context see {@link XWikiContext}
*/
public void saveDocument(XWikiDocument document, String comment, boolean isMinorEdit, XWikiContext context)
throws XWikiException
{
String currentWiki = context.getWikiId();
try {
// Switch to document wiki
context.setWikiId(document.getDocumentReference().getWikiReference().getName());
// Setting comment & minor edit before saving
document.setComment(StringUtils.defaultString(comment));
document.setMinorEdit(isMinorEdit);
// We need to save the original document since saveXWikiDoc() will reset it and we
// need that original document for the notification below.
XWikiDocument originalDocument = document.getOriginalDocument();
// Make sure to always have an original document for listeners that need to compare with it.
// The only case where we have a null original document is supposedly when the document
// instance has been crafted and passed #saveDocument without using #getDocument
// (which is not a good practice)
if (originalDocument == null) {
originalDocument =
getDocument(new DocumentReference(document.getDocumentReference(), document.getLocale()), context);
document.setOriginalDocument(originalDocument);
}
ObservationManager om = getObservationManager();
// Notify listeners about the document about to be created or updated
// Note that for the moment the event being send is a bridge event, as we are still passing around
// an XWikiDocument as source and an XWikiContext as data.
if (om != null) {
CancelableEvent documentEvent;
if (originalDocument.isNew()) {
documentEvent = new DocumentCreatingEvent(document.getDocumentReference());
} else {
documentEvent = new DocumentUpdatingEvent(document.getDocumentReference());
}
om.notify(documentEvent, document, context);
// If the action has been canceled by the user then don't perform any save and throw an exception
if (documentEvent.isCanceled()) {
throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
XWikiException.ERROR_XWIKI_STORE_HIBERNATE_SAVING_DOC,
String.format("An Event Listener has cancelled the document save for [%s]. Reason: [%s]",
document.getDocumentReference(), documentEvent.getReason()));
}
}
// Put attachments to remove in recycle bin
if (hasAttachmentRecycleBin(context)) {
for (XWikiAttachmentToRemove attachment : document.getAttachmentsToRemove()) {
if (attachment.isToRecycleBin()) {
getAttachmentRecycleBinStore().saveToRecycleBin(attachment.getAttachment(), context.getUser(),
new Date(), context, true);
}
}
}
// Actually save the document.
getStore().saveXWikiDoc(document, context);
// Since the store#saveXWikiDoc resets originalDocument, we need to temporarily put it
// back to send notifications.
XWikiDocument newOriginal = document.getOriginalDocument();
try {
document.setOriginalDocument(originalDocument);
// Notify listeners about the document having been created or updated
// First the legacy notification mechanism
// Then the new observation module
// Note that for the moment the event being send is a bridge event, as we are still passing around
// an XWikiDocument as source and an XWikiContext as data.
// The old version is made available using doc.getOriginalDocument()
if (om != null) {
if (originalDocument.isNew()) {
om.notify(new DocumentCreatedEvent(document.getDocumentReference()), document, context);
} else {
om.notify(new DocumentUpdatedEvent(document.getDocumentReference()), document, context);
}
}
} catch (Exception ex) {
LOGGER.error("Failed to send document save notification for document ["
+ getDefaultEntityReferenceSerializer().serialize(document.getDocumentReference()) + "]", ex);
} finally {
document.setOriginalDocument(newOriginal);
}
} finally {
context.setWikiId(currentWiki);
}
}
/**
* Loads a XWikiDocument from the store.
* <p>
* Before 7.2M1 the reference is assumed to be a complete or incomplete document reference.
* <p>
* Since 7.2M1, 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 of teh document
* @param context see {@link XWikiContext}
* @since 5.0M1
*/
public XWikiDocument getDocument(EntityReference reference, XWikiContext context) throws XWikiException
{
XWikiDocument document;
if (reference.getType() == EntityType.PAGE || reference.getType().isAllowedAncestor(EntityType.PAGE)) {
document = getDocument(getCurrentGetPageResolver().resolve(reference), context);
} else {
document = getDocument(getCurrentGetDocumentResolver().resolve(reference), context);
}
return document;
}
/**
* Loads a XWikiDocument from the store.
*
* @param reference the reference of the document to be loaded
* @param type the type of the reference
* @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 10.6RC1
*/
@Unstable
public XWikiDocument getDocument(String reference, EntityType type, XWikiContext xcontext) throws XWikiException
{
return getDocument(getRelativeEntityReferenceResolver().resolve(reference, type), xcontext);
}
/**
* @param doc the document
* @param context see {@link XWikiContext}
*/
public XWikiDocument getDocument(XWikiDocument doc, XWikiContext context) throws XWikiException
{
String currentWiki = context.getWikiId();
try {
context.setWikiId(doc.getDocumentReference().getWikiReference().getName());
return getStore().loadXWikiDoc(doc, context);
} finally {
context.setWikiId(currentWiki);
}
}
/**
* @param reference the reference of the document to load
* @param revision the revision of the document to load
* @param context the XWiki context
* @return the document corresponding to the passed revision or a new XWikiDocument instance if none can be found
* @throws XWikiException when failing to load the document revision
* @since 9.4RC1
* @deprecated sine 9.10RC1, use {@link DocumentRevisionProvider#getRevision(DocumentReference, String)} instead
*/
@Deprecated
public XWikiDocument getDocument(DocumentReference reference, String revision, XWikiContext context)
throws XWikiException
{
XWikiDocument revisionDocument = getDocumentRevisionProvider().getRevision(reference, revision);
if (revisionDocument == null && (revision.equals("1.1") || revision.equals("1.0"))) {
revisionDocument = new XWikiDocument(reference);
}
return revisionDocument;
}
/**
* @param document the reference document
* @param revision the revision of the document to load
* @param context the XWiki context
* @return the document corresponding to the passed revision or a new XWikiDocument instance if none can be found
* @throws XWikiException when failing to load the document revision
* @deprecated sine 9.10RC1, use {@link DocumentRevisionProvider#getRevision(XWikiDocument, String)} instead
*/
@Deprecated
public XWikiDocument getDocument(XWikiDocument document, String revision, XWikiContext context)
throws XWikiException
{
XWikiDocument revisionDocument = getDocumentRevisionProvider().getRevision(document, revision);
if (revisionDocument == null && (revision.equals("1.1") || revision.equals("1.0"))) {
revisionDocument = new XWikiDocument(document.getDocumentReference());
}
return revisionDocument;
}
/**
* @param reference the reference of the document
* @param context see {@link XWikiContext}
* @since 2.2M1
*/
public XWikiDocument getDocument(DocumentReference reference, XWikiContext context) throws XWikiException
{
XWikiDocument doc = new XWikiDocument(
reference.getLocale() != null ? new DocumentReference(reference, (Locale) null) : reference,
reference.getLocale());
doc.setContentDirty(true);
return getDocument(doc, context);
}
/**
* @param reference the reference of the page
* @param context see {@link XWikiContext}
* @since 10.6RC1
*/
@Unstable
public XWikiDocument getDocument(PageReference reference, XWikiContext context) throws XWikiException
{
DocumentReference documentReference = getCurrentReferenceDocumentReferenceResolver().resolve(reference);
XWikiDocument document = getDocument(documentReference, context);
if (document.isNew() && documentReference.getParent().getParent().getType() == EntityType.SPACE) {
// Try final page
XWikiDocument finalDocument = getDocument(new DocumentReference(documentReference.getParent().getName(),
documentReference.getParent().getParent(), documentReference.getParameters()), context);
if (!finalDocument.isNew()) {
document = finalDocument;
}
}
return document;
}
/**
* Find the document reference corresponding to the entity reference based on what exist in the database (page
* reference can means two different documents for example).
*
* @param reference the reference to resolve
* @param context the XWiki context
* @return the document reference
* @since 10.6RC1
*/
@Unstable
public DocumentReference getDocumentReference(EntityReference reference, XWikiContext context)
{
DocumentReference documentReference = getCurrentGetDocumentResolver().resolve(reference);
// If the document has been found or it's top level space, return the reference
if (documentReference.getParent().getParent().getType() != EntityType.SPACE
|| exists(documentReference, context)) {
return documentReference;
}
// Try final page
DocumentReference finalPageReference = new DocumentReference(documentReference.getParent().getName(),
documentReference.getParent().getParent(), documentReference.getParameters());
return exists(finalPageReference, context) ? finalPageReference : documentReference;
}
/**
* @param fullname the reference of the document as String
* @param context see {@link XWikiContext}
* @deprecated since 2.2M1 use {@link #getDocument(DocumentReference, XWikiContext)} instead
*/
@Deprecated
public XWikiDocument getDocument(String fullname, XWikiContext context) throws XWikiException
{
XWikiDocument doc = new XWikiDocument();
doc.setFullName(fullname, context);
return getDocument(doc, context);
}
/**
* @param spaces the reference of the space as String
* @param fullname the reference of the document as String
* @param context see {@link XWikiContext}
* @deprecated since 2.2M1 use {@link #getDocument(DocumentReference, XWikiContext)} instead
*/
@Deprecated
public XWikiDocument getDocument(String spaces, String fullname, XWikiContext context) throws XWikiException
{
int dotPosition = fullname.lastIndexOf('.');
if (dotPosition != -1) {
String spaceFromFullname = fullname.substring(0, dotPosition);
String name = fullname.substring(dotPosition + 1);
if (name.equals("")) {
name = getDefaultPage(context);
}
return getDocument(spaceFromFullname + "." + name, context);
} else {
return getDocument(spaces + "." + fullname, context);
}
}
/**
* @see com.xpn.xwiki.api.XWiki#getDeletedDocuments(String, String)
*/
public XWikiDeletedDocument[] getDeletedDocuments(String fullname, String locale, XWikiContext context)
throws XWikiException
{
if (hasRecycleBin(context)) {
XWikiDocument doc = new XWikiDocument(getCurrentMixedDocumentReferenceResolver().resolve(fullname));
doc.setLanguage(locale);
return getRecycleBinStore().getAllDeletedDocuments(doc, context, true);
} else {
return null;
}
}
/**
* @see com.xpn.xwiki.api.XWiki#getDeletedDocuments(String)
* @since 9.4RC1
*/
public XWikiDeletedDocument[] getDeletedDocuments(String batchId, XWikiContext context) throws XWikiException
{
if (hasRecycleBin(context)) {
return getRecycleBinStore().getAllDeletedDocuments(batchId, context, true);
} else {
return null;
}
}
/**
* @see com.xpn.xwiki.api.XWiki#getDeletedDocument(String, String, String)
* @deprecated since 9.4RC1. Use {@link #getDeletedDocument(long, XWikiContext)} instead.
*/
@Deprecated
public XWikiDeletedDocument getDeletedDocument(String fullname, String locale, int index, XWikiContext context)
throws XWikiException
{
return getDeletedDocument(index, context);
}
/**
* @see com.xpn.xwiki.api.XWiki#getDeletedDocument(String)
* @since 9.4RC1
*/
public XWikiDeletedDocument getDeletedDocument(long index, XWikiContext context) throws XWikiException
{
if (hasRecycleBin(context)) {
return getRecycleBinStore().getDeletedDocument(index, context, true);
} else {
return null;
}
}
/**
* 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
* @param context see {@link XWikiContext}
* @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.
* @throws XWikiException if an error occurs while loading the attachments
*/
public List<DeletedAttachment> getDeletedAttachments(String docName, XWikiContext context) throws XWikiException
{
if (hasAttachmentRecycleBin(context)) {
XWikiDocument doc = new XWikiDocument(getCurrentMixedDocumentReferenceResolver().resolve(docName));
return getAttachmentRecycleBinStore().getAllDeletedAttachments(doc, context, true);
}
return null;
}
/**
* 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
* @param context see {@link XWikiContext}
* @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.
* @throws XWikiException if an error occurs while loading the attachments
*/
public List<DeletedAttachment> getDeletedAttachments(String docName, String filename, XWikiContext context)
throws XWikiException
{
if (hasAttachmentRecycleBin(context)) {
XWikiDocument doc = new XWikiDocument(getCurrentMixedDocumentReferenceResolver().resolve(docName));
XWikiAttachment attachment = new XWikiAttachment(doc, filename);
return getAttachmentRecycleBinStore().getAllDeletedAttachments(attachment, context, true);
}
return null;
}
/**
* Retrieve a specific attachment from the trash.
*
* @param id the unique identifier of the entry in the trash
* @param context the XWiki context
* @return specified attachment from the trash, {@code null} if not found
* @throws XWikiException if an error occurs while loading the attachments
*/
public DeletedAttachment getDeletedAttachment(String id, XWikiContext context) throws XWikiException
{
if (hasAttachmentRecycleBin(context)) {
return getAttachmentRecycleBinStore().getDeletedAttachment(NumberUtils.toLong(id), context, true);
}
return null;
}
public MetaClass getMetaclass()
{
if (this.metaclass == null) {
this.metaclass = MetaClass.getMetaClass();
}
return this.metaclass;
}
public void setMetaclass(MetaClass metaclass)
{
this.metaclass = metaclass;
}
/**
* @param context see {@link XWikiContext}
*/
public List<String> getClassList(XWikiContext context) throws XWikiException
{
List<String> result = getStore().getClassList(context);
Collections.sort(result);
return result;
}
/**
* @param sql the sql query to execute
* @param context see {@link XWikiContext}
*/
public <T> List<T> search(String sql, XWikiContext context) throws XWikiException
{
return getStore().search(sql, 0, 0, context);
}
/**
* @param sql the sql query to execute
* @param nb limit the number of results to return
* @param start the offset from which to start return results
* @param context see {@link XWikiContext}
*/
public <T> List<T> search(String sql, int nb, int start, XWikiContext context) throws XWikiException
{
return getStore().search(sql, nb, start, context);
}
/**
* @param sql the sql query to execute
* @param context see {@link XWikiContext}
*/
public <T> List<T> search(String sql, Object[][] whereParams, XWikiContext context) throws XWikiException
{
return getStore().search(sql, 0, 0, whereParams, context);
}
/**
* @param sql the sql query to execute
* @param nb limit the number of results to return
* @param start the offset from which to start return results
* @param context see {@link XWikiContext}
*/
public <T> List<T> search(String sql, int nb, int start, Object[][] whereParams, XWikiContext context)
throws XWikiException
{
return getStore().search(sql, nb, start, whereParams, context);
}
/**
* @param content the content to parse
* @param context see {@link XWikiContext}
* @deprecated Since 7.2M1. Use specific rendering/parsing options for the content type you want to parse/render.
*/
@Deprecated
public String parseContent(String content, XWikiContext context)
{
return getOldRendering().parseContent(content, context);
}
/**
* @param template the name of the template
* @param context see {@link XWikiContext}
* @deprecated use {@link #evaluateTemplate(String, XWikiContext)} instead
*/
@Deprecated
public String parseTemplate(String template, XWikiContext context)
{
String result = "";
try {
result = evaluateTemplate(template, context);
} catch (Exception e) {
LOGGER.debug("Exception while parsing template [{}] from /templates/", template, e);
}
return result;
}
/**
* Evaluate provided template content using velocity engine.
*
* @param template the template to evaluate
* @param context see {@link XWikiContext}
* @return the return of the velocity script
* @throws IOException failed to get the template content
* @since 2.2.2
* @deprecated since 7.0M1, use {@link TemplateManager#render(String)} instead
*/
@Deprecated
public String evaluateTemplate(String template, XWikiContext context) throws IOException
{
try {
return getTemplateManager().render(template);
} catch (Exception e) {
LOGGER.error("Error while evaluating velocity template [{}]", template, e);
Object[] args = { template };
XWikiException xe = new XWikiException(XWikiException.MODULE_XWIKI_RENDERING,
XWikiException.ERROR_XWIKI_RENDERING_VELOCITY_EXCEPTION, "Error while evaluating velocity template {0}",
e, args);
return Util.getHTMLExceptionMessage(xe, context);
}
}
/**
* @param template the name of the template
* @param skinId the id of the skin from which to load the template
* @param context see {@link XWikiContext}
* @deprecated since 7.0M1, use {@link TemplateManager#renderFromSkin} instead
*/
@Deprecated
public String parseTemplate(String template, String skinId, XWikiContext context)
{
MutableRenderingContext mutableRenderingContext = getMutableRenderingContext();
Syntax currentTargetSyntax = mutableRenderingContext.getTargetSyntax();
try {
// Force rendering with XHTML 1.0 syntax for retro-compatibility
mutableRenderingContext.setTargetSyntax(Syntax.XHTML_1_0);
Skin skin = getInternalSkinManager().getSkin(skinId);
return getTemplateManager().renderFromSkin(template, skin);
} catch (Exception e) {
LOGGER.error("Error while evaluating velocity template [{}] skin [{}]", template, skinId, e);
Object[] args = { template, skinId };
XWikiException xe = new XWikiException(XWikiException.MODULE_XWIKI_RENDERING,
XWikiException.ERROR_XWIKI_RENDERING_VELOCITY_EXCEPTION,
"Error while evaluating velocity template [{0}] from skin [{1}]", e, args);
return Util.getHTMLExceptionMessage(xe, context);
} finally {
mutableRenderingContext.setTargetSyntax(currentTargetSyntax);
}
}
/**
* @param template the name of the template
* @param skin the id of the skin from which to load the template
* @param context see {@link XWikiContext}
*/
public String renderTemplate(String template, String skin, XWikiContext context)
{
try {
return getOldRendering().renderTemplate(template, skin, context);
} catch (Exception ex) {
LOGGER.error("Failed to render template [" + template + "] for skin [" + skin + "]", ex);
return parseTemplate(template, skin, context);
}
}
/**
* @param template the name of the template
* @param context see {@link XWikiContext}
*/
public String renderTemplate(String template, XWikiContext context)
{
try {
return getOldRendering().renderTemplate(template, context);
} catch (Exception ex) {
LOGGER.error("Failed to render template [" + template + "]", ex);
return parseTemplate(template, context);
}
}
/**
* 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.
*/
public String invokeServletAndReturnAsString(String url, XWikiContext xwikiContext)
{
HttpServletRequest servletRequest = xwikiContext.getRequest();
HttpServletResponse servletResponse = xwikiContext.getResponse();
try {
return IncludeServletAsString.invokeServletAndReturnAsString(url, servletRequest, servletResponse);
} catch (Exception e) {
LOGGER.warn("Exception including url: " + url, e);
return "Exception including \"" + url + "\", see logs for details.";
}
}
/**
* @param iconName the standard name of an icon (it's not the name of the file on the filesystem, it's a generic
* name, for example "success" for a success icon
* @param context see {@link XWikiContext}
* @return the URL to the icon resource
* @since 2.6M1
*/
public String getIconURL(String iconName, XWikiContext context)
{
// TODO: Do a better mapping between generic icon name and physical resource name, especially to be independent
// of the underlying icon library. Right now we assume it's the Silk icon library.
return getSkinFile("icons/silk/" + iconName + ".png", context);
}
public String getSkinFile(String filename, XWikiContext context)
{
return getSkinFile(filename, false, context);
}
public String getSkinFile(String filename, boolean forceSkinAction, XWikiContext context)
{
XWikiURLFactory urlf = context.getURLFactory();
try {
// Try in the specified skin
Skin skin = getInternalSkinManager().getCurrentSkin(true);
if (skin != null) {
Resource<?> resource = skin.getResource(filename);
if (resource != null) {
return resource.getURL(forceSkinAction);
}
} else {
// Try in the current parent skin
Skin parentSkin = getInternalSkinManager().getCurrentParentSkin(true);
if (parentSkin != null) {
Resource<?> resource = parentSkin.getResource(filename);
if (resource != null) {
return resource.getURL(forceSkinAction);
}
}
}
// Look for a resource file
if (resourceExists("/resources/" + filename)) {
URL url = urlf.createResourceURL(filename, forceSkinAction, context);
return urlf.getURL(url, context);
}
} catch (Exception e) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Exception while getting skin file [" + filename + "]", e);
}
}
// If all else fails, use the default base skin, even if the URLs could be invalid.
URL url;
if (forceSkinAction) {
url = urlf.createSkinURL(filename, "skins", getDefaultBaseSkin(context), context);
} else {
url = urlf.createSkinURL(filename, getDefaultBaseSkin(context), context);
}
return urlf.getURL(url, context);
}
public String getSkinFile(String filename, String skin, XWikiContext context)
{
return getSkinFile(filename, skin, false, context);
}
public String getSkinFile(String filename, String skinId, boolean forceSkinAction, XWikiContext context)
{
try {
Skin skin = getInternalSkinManager().getSkin(skinId);
Resource<?> resource = skin.getLocalResource(filename);
if (resource != null) {
return resource.getURL(forceSkinAction);
}
// Look for a resource file
if (resourceExists("/resources/" + filename)) {
XWikiURLFactory urlf = context.getURLFactory();
URL url = urlf.createResourceURL(filename, forceSkinAction, context);
return urlf.getURL(url, context);
}
} catch (Exception e) {
if (LOGGER.isDebugEnabled()) {
LOGGER.debug("Exception while getting skin file [{}] from skin [{}]", filename, skinId, e);
}
}
return null;
}
/**
* @deprecated since 7.0M1, use {@link SkinManager#getCurrentSkin(boolean)} instead
*/
@Deprecated
public String getSkin(XWikiContext context)
{
String skin;
try {
skin = getInternalSkinManager().getCurrentSkinId(true);
} catch (Exception e) {
LOGGER.debug("Exception while determining current skin", e);
skin = getDefaultBaseSkin(context);
}
return skin;
}
public String getSkinPreference(String prefname, XWikiContext context)
{
return getSkinPreference(prefname, "", context);
}
public String getSkinPreference(String prefname, String defaultValue, XWikiContext context)
{
for (Skin skin = getInternalSkinManager().getCurrentSkin(true); skin != null; skin = skin.getParent()) {
if (skin instanceof WikiSkin) {
String value = getWikiSkinUtils().getSkinProperty(skin.getId(), prefname);
// TODO: remove the NO_VALUE test when XWIKI-10853 is fixed
if (!StringUtils.isEmpty(value) && !NO_VALUE.equals(value)) {
return value;
}
}
}
return defaultValue;
}
/**
* @deprecated since 7.0M1, use {@link SkinManager#getDefaultParentSkin()} instead
*/
@Deprecated
public String getDefaultBaseSkin(XWikiContext context)
{
return getInternalSkinManager().getDefaultParentSkinId();
}
/**
* @deprecated since 7.0M1
*/
@Deprecated
public String getBaseSkin(XWikiContext context)
{
return getBaseSkin(context, false);
}
/**
* @deprecated since 7.0M1
*/
@Deprecated
public String getBaseSkin(XWikiContext context, boolean fromRenderSkin)
{
String baseskin = "";
try {
return getInternalSkinManager().getCurrentParentSkinId(false);
} catch (Exception e) {
baseskin = getDefaultBaseSkin(context);
LOGGER.debug("Exception while determining base skin", e);
}
return baseskin;
}
/**
* @param skin the name of the skin for which to return the base skin. For example : <tt>XWiki.DefaultSkin</tt>
* @param context see {@link XWikiContext}
* @return if found, the name of the base skin the asked skin inherits from. If not found, returns an empty string.
* @since 2.0.2
* @since 2.1M1
* @deprecated since 7.0M1, use {@link SkinManager#getCurrentSkin(boolean)} and {@link Skin#getParent()} instead
*/
@Deprecated
public String getBaseSkin(String skin, XWikiContext context)
{
String baseSkin = getInternalSkinManager().getParentSkin(skin);
return baseSkin != null ? baseSkin : "";
}
public String getSpaceCopyright(XWikiContext context)
{
return getSpacePreference("webcopyright", "", context);
}
public String getXWikiPreference(String prefname, XWikiContext context)
{
return getXWikiPreference(prefname, "", context);
}
/**
* Obtain a preference value for the wiki, looking up first in the XWiki.XWikiPreferences document, then fallbacking
* on a config parameter when the first lookup gives an empty string, then returning the default value if the config
* parameter returned itself an empty string.
*
* @param prefname the parameter to look for in the XWiki.XWikiPreferences object in the XWiki.XWikiPreferences
* document of the wiki.
* @param fallbackParam the parameter in xwiki.cfg to fallback on, in case the XWiki.XWikiPreferences object gave no
* result
* @param defaultValue the default value to fallback on, in case both XWiki.XWikiPreferences and the fallback
* xwiki.cfg parameter gave no result
*/
public String getXWikiPreference(String prefname, String fallbackParam, String defaultValue, XWikiContext context)
{
String result = getWikiConfiguration().getProperty(prefname, String.class);
if (StringUtils.isEmpty(result)) {
result = getConfiguration().getProperty(fallbackParam, defaultValue);
}
return result != null ? result : "";
}
/**
* Obtain a preference value for the wiki, looking up first in the XWiki.XWikiPreferences document, then fallbacking
* on a config parameter when the first lookup gives an empty string, then returning the default value if the config
* parameter returned itself an empty string.
*
* @param prefname the parameter to look for in the XWiki.XWikiPreferences object in the XWiki.XWikiPreferences
* document of the wiki.
* @param wiki the wiki to get preference from
* @param fallbackParam the parameter in xwiki.cfg to fallback on, in case the XWiki.XWikiPreferences object gave no
* result
* @param defaultValue the default value to fallback on, in case both XWiki.XWikiPreferences and the fallback
* xwiki.cfg parameter gave no result
* @since 7.4M1
*/
public String getXWikiPreference(String prefname, String wiki, String fallbackParam, String defaultValue,
XWikiContext xcontext)
{
String currentWiki = xcontext.getWikiId();
try {
xcontext.setWikiId(wiki);
return getXWikiPreference(prefname, fallbackParam, defaultValue, xcontext);
} finally {
xcontext.setWikiId(currentWiki);
}
}
public String getXWikiPreference(String prefname, String defaultValue, XWikiContext context)
{
return getXWikiPreference(prefname, "", defaultValue, context);
}
public String getSpacePreference(String preference, XWikiContext context)
{
return getSpacePreference(preference, "", context);
}
public String getSpacePreference(String preference, String defaultValue, XWikiContext context)
{
return getSpacePreference(preference, (SpaceReference) null, defaultValue, context);
}
/**
* @deprecated since 7.4M1, use {@link #getSpacePreference(String, SpaceReference, String, XWikiContext)} instead
*/
@Deprecated
public String getSpacePreference(String preference, String space, String defaultValue, XWikiContext context)
{
return getSpacePreference(preference, new SpaceReference(space, context.getWikiReference()), defaultValue,
context);
}
/**
* 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 preferenceKey the name of the preference key
* @param spaceReference the reference of the space
* @param context see {@link XWikiContext}
* @return the value of the preference or empty String if it could not be found
* @since 7.4M1
*/
public String getSpacePreference(String preferenceKey, SpaceReference spaceReference, XWikiContext context)
{
return getSpacePreference(preferenceKey, spaceReference, "", context);
}
/**
* 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 preferenceKey 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
* @param context see {@link XWikiContext}
* @return the value of the preference or <code>defaultValue</code> if it could not be found
* @since 7.4M1
*/
public String getSpacePreference(String preferenceKey, SpaceReference spaceReference, String defaultValue,
XWikiContext context)
{
XWikiDocument currentDocument = context.getDoc();
try {
if (spaceReference != null) {
context.setDoc(new XWikiDocument(new DocumentReference("WebPreferences", spaceReference)));
} else if (currentDocument != null) {
spaceReference = currentDocument.getDocumentReference().getLastSpaceReference();
}
String result = getSpaceConfiguration().getProperty(preferenceKey, String.class);
if (StringUtils.isEmpty(result)) {
if (spaceReference == null) {
result = getXWikiPreference(preferenceKey, defaultValue, context);
} else if (spaceReference.getParent() instanceof SpaceReference) {
result = getSpacePreference(preferenceKey, (SpaceReference) spaceReference.getParent(),
defaultValue, context);
} else if (spaceReference.getParent() instanceof WikiReference) {
result =
getXWikiPreference(preferenceKey, spaceReference.getParent().getName(), defaultValue, context);
}
}
return result != null ? result : defaultValue;
} finally {
context.setDoc(currentDocument);
}
}
public String getUserPreference(String prefname, XWikiContext context)
{
String result = getUserConfiguration().getProperty(prefname, String.class);
if (StringUtils.isEmpty(result)) {
result = getSpacePreference(prefname, context);
}
return result != null ? result : "";
}
public String getUserPreferenceFromCookie(String prefname, XWikiContext context)
{
Cookie[] cookies = context.getRequest().getCookies();
if (cookies == null) {
return null;
}
for (Cookie cookie : cookies) {
String name = cookie.getName();
if (name.equals(prefname)) {
String value = cookie.getValue();
if (!value.trim().equals("")) {
return value;
} else {
break;
}
}
}
return null;
}
public String getUserPreference(String prefname, boolean useCookie, XWikiContext context)
{
// First we look in the cookies
if (useCookie) {
String result = Util.normalizeLanguage(getUserPreferenceFromCookie(prefname, context));
if (result != null) {
return result;
}
}
return getUserPreference(prefname, context);
}
/**
* 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(XWikiContext context)
{
String language = getLanguagePreference(context);
return LocaleUtils.toLocale(language);
}
/**
* 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
* @deprecated since 8.0M1, use {@link #getLocalePreference(XWikiContext)} instead
*/
@Deprecated
// TODO: move implementation to #getLocalePreference
public String getLanguagePreference(XWikiContext context)
{
// First we try to get the language from the XWiki Context. This is the current language
// being used.
String language = context.getLanguage();
if (language != null) {
return language;
}
String defaultLanguage = getDefaultLanguage(context);
// If the wiki is non multilingual then the language is the default language.
if (!context.getWiki().isMultiLingual(context)) {
language = defaultLanguage;
context.setLanguage(language);
return language;
}
// As the wiki is multilingual try to find the language to use from the request by looking
// for a language parameter. If the language value is "default" use the default language
// from the XWiki preferences settings. Otherwise set a cookie to remember the language
// in use.
try {
language = Util.normalizeLanguage(context.getRequest().getParameter("language"));
if ((language != null) && (!language.equals(""))) {
if (language.equals("default")) {
// forgetting language cookie
Cookie cookie = new Cookie("language", "");
cookie.setMaxAge(0);
cookie.setPath("/");
context.getResponse().addCookie(cookie);
language = defaultLanguage;
} else {
// setting language cookie
Cookie cookie = new Cookie("language", language);
cookie.setMaxAge(60 * 60 * 24 * 365 * 10);
cookie.setPath("/");
context.getResponse().addCookie(cookie);
}
context.setLanguage(language);
return language;
}
} catch (Exception e) {
}
// As no language parameter was passed in the request, try to get the language to use
// from a cookie.
try {
// First we get the language from the cookie
language = Util.normalizeLanguage(getUserPreferenceFromCookie("language", context));
if ((language != null) && (!language.equals(""))) {
context.setLanguage(language);
return language;
}
} catch (Exception e) {
}
// Next from the default user preference
try {
String user = context.getUser();
XWikiDocument userdoc = null;
userdoc = getDocument(user, context);
if (userdoc != null) {
language = Util.normalizeLanguage(userdoc.getStringValue("XWiki.XWikiUsers", "default_language"));
if (!language.equals("")) {
context.setLanguage(language);
return language;
}
}
} catch (XWikiException e) {
}
// If the default language is preferred, and since the user didn't explicitly ask for a
// language already, then use the default wiki language.
if (getConfiguration().getProperty("xwiki.language.preferDefault", "0").equals("1")
|| getSpacePreference("preferDefaultLanguage", "0", context).equals("1")) {
language = defaultLanguage;
context.setLanguage(language);
return language;
}
// Then from the navigator language setting
if (context.getRequest() != null) {
String acceptHeader = context.getRequest().getHeader("Accept-Language");
// If the client didn't specify some languages, skip this phase
if ((acceptHeader != null) && (!acceptHeader.equals(""))) {
List<String> acceptedLanguages = getAcceptedLanguages(context.getRequest());
// We can force one of the configured languages to be accepted
if (getConfiguration().getProperty("xwiki.language.forceSupported", "0").equals("1")) {
List<String> available = Arrays.asList(getXWikiPreference("languages", context).split("[, |]"));
// Filter only configured languages
acceptedLanguages.retainAll(available);
}
if (acceptedLanguages.size() > 0) {
// Use the "most-preferred" language, as requested by the client.
context.setLanguage(acceptedLanguages.get(0));
return acceptedLanguages.get(0);
}
// If none of the languages requested by the client is acceptable, skip to next
// phase (use default language).
}
}
// Finally, use the default language from the global preferences.
context.setLanguage(defaultLanguage);
return defaultLanguage;
}
/**
* Construct a list of language codes (ISO 639-1) from the Accept-Languages header. This method filters out some
* bugs in different browsers or containers, like returning '*' as a language (Jetty) or using '_' as a
* language--country delimiter (some versions of Opera).
*
* @param request The client request.
* @return A list of language codes, in the client preference order; might be empty if the header is not well
* formed.
*/
private List<String> getAcceptedLanguages(XWikiRequest request)
{
List<String> result = new ArrayList<String>();
Enumeration<Locale> e = request.getLocales();
while (e.hasMoreElements()) {
String language = e.nextElement().getLanguage().toLowerCase();
// All language codes should have 2 letters.
if (StringUtils.isAlpha(language)) {
result.add(language);
}
}
return result;
}
/**
* @deprecated since 5.1M2 use {@link #getDefaultLocale(XWikiContext)} instead
*/
@Deprecated
public String getDefaultLanguage(XWikiContext xcontext)
{
return getDefaultLocale(xcontext).toString();
}
/**
* The default locale in the preferences.
*
* @param xcontext the XWiki context.
* @return the default locale
* @since 5.1M2
*/
public Locale getDefaultLocale(XWikiContext xcontext)
{
// Find out what is the default language from the XWiki preferences settings.
String defaultLanguage = xcontext.getWiki().getXWikiPreference("default_language", "", xcontext);
Locale defaultLocale;
if (StringUtils.isBlank(defaultLanguage)) {
defaultLocale = Locale.ENGLISH;
} else {
try {
defaultLocale = LocaleUtils.toLocale(Util.normalizeLanguage(defaultLanguage));
} catch (Exception e) {
LOGGER.warn("Invalid locale [{}] set as default locale in the preferences", defaultLanguage);
defaultLocale = Locale.ENGLISH;
}
}
return defaultLocale;
}
/**
* Get the available locales according to the preferences.
*
* @param xcontext the XWiki context
* @return all the available locales
* @since 5.1M2
*/
public List<Locale> getAvailableLocales(XWikiContext xcontext)
{
String[] languages = StringUtils.split(xcontext.getWiki().getXWikiPreference("languages", xcontext), ", |");
List<Locale> locales = new ArrayList<Locale>(languages.length);
for (String language : languages) {
if (StringUtils.isNotBlank(language)) {
try {
locales.add(LocaleUtils.toLocale(language));
} catch (Exception e) {
LOGGER.warn("Invalid locale [{}] listed as available in the preferences", language);
}
}
}
// Add default language in case it's not listed as available (which is wrong but it happen)
Locale defaultocale = getDefaultLocale(xcontext);
if (!locales.contains(defaultocale)) {
locales.add(defaultocale);
}
return locales;
}
/**
* @since 8.0M1
*/
public Locale getDocLocalePreferenceNew(XWikiContext context)
{
String language = getDocLanguagePreferenceNew(context);
return LocaleUtils.toLocale(language);
}
/**
* @deprecated since 8.0M1, use {@link #getDocLocalePreferenceNew(XWikiContext)} instead
*/
@Deprecated
// TODO: move implementation to #getDocLocalePreferenceNew
public String getDocLanguagePreferenceNew(XWikiContext context)
{
// Get context language
String contextLanguage = context.getLanguage();
// If the language exists in the context, it was previously set by another call
if (contextLanguage != null && contextLanguage != "") {
return contextLanguage;
}
String language = "", requestLanguage = "", userPreferenceLanguage = "", navigatorLanguage = "",
cookieLanguage = "";
boolean setCookie = false;
if (!context.getWiki().isMultiLingual(context)) {
language = context.getWiki().getXWikiPreference("default_language", "", context);
context.setLanguage(language);
return language;
}
// Get request language
try {
requestLanguage = Util.normalizeLanguage(context.getRequest().getParameter("language"));
} catch (Exception ex) {
}
// Get user preference
try {
String user = context.getUser();
XWikiDocument userdoc = getDocument(user, context);
if (userdoc != null) {
userPreferenceLanguage = userdoc.getStringValue("XWiki.XWikiUsers", "default_language");
}
} catch (XWikiException e) {
}
// Get navigator language setting
if (context.getRequest() != null) {
String accept = context.getRequest().getHeader("Accept-Language");
if ((accept != null) && (!accept.equals(""))) {
String[] alist = StringUtils.split(accept, ",;-");
if ((alist != null) && !(alist.length == 0)) {
context.setLanguage(alist[0]);
navigatorLanguage = alist[0];
}
}
}
// Get language from cookie
try {
cookieLanguage = Util.normalizeLanguage(getUserPreferenceFromCookie("language", context));
} catch (Exception e) {
}
// Determine which language to use
// First we get the language from the request
if (StringUtils.isNotEmpty(requestLanguage)) {
if (requestLanguage.equals("default")) {
setCookie = true;
} else {
language = requestLanguage;
context.setLanguage(language);
Cookie cookie = new Cookie("language", language);
cookie.setMaxAge(60 * 60 * 24 * 365 * 10);
cookie.setPath("/");
context.getResponse().addCookie(cookie);
return language;
}
}
// Next we get the language from the cookie
if (StringUtils.isNotEmpty(cookieLanguage)) {
language = cookieLanguage;
}
// Next from the default user preference
else if (StringUtils.isNotEmpty(userPreferenceLanguage)) {
language = userPreferenceLanguage;
}
// Then from the navigator language setting
else if (StringUtils.isNotEmpty(navigatorLanguage)) {
language = navigatorLanguage;
}
context.setLanguage(language);
if (setCookie) {
Cookie cookie = new Cookie("language", language);
cookie.setMaxAge(60 * 60 * 24 * 365 * 10);
cookie.setPath("/");
context.getResponse().addCookie(cookie);
}
return language;
}
/**
* @since 8.0M1
*/
public Locale getInterfaceLocalePreference(XWikiContext context)
{
String language = getInterfaceLanguagePreference(context);
return LocaleUtils.toLocale(language);
}
/**
* @deprecated since 8.0M1, use {@link #getInterfaceLocalePreference(XWikiContext)} instead
*/
@Deprecated
// TODO: move implementation to #getInterfaceLocalePreference
public String getInterfaceLanguagePreference(XWikiContext context)
{
String language = "", requestLanguage = "", userPreferenceLanguage = "", navigatorLanguage = "",
cookieLanguage = "", contextLanguage = "";
boolean setCookie = false;
if (!context.getWiki().isMultiLingual(context)) {
language = Util.normalizeLanguage(context.getWiki().getXWikiPreference("default_language", "", context));
context.setInterfaceLanguage(language);
return language;
}
// Get request language
try {
requestLanguage = Util.normalizeLanguage(context.getRequest().getParameter("interfacelanguage"));
} catch (Exception ex) {
}
// Get context language
contextLanguage = context.getInterfaceLanguage();
// Get user preference
try {
String user = context.getUser();
XWikiDocument userdoc = null;
userdoc = getDocument(user, context);
if (userdoc != null) {
userPreferenceLanguage = userdoc.getStringValue("XWiki.XWikiUsers", "default_interface_language");
}
} catch (XWikiException e) {
}
// Get navigator language setting
if (context.getRequest() != null) {
String accept = context.getRequest().getHeader("Accept-Language");
if ((accept != null) && (!accept.equals(""))) {
String[] alist = StringUtils.split(accept, ",;-");
if ((alist != null) && !(alist.length == 0)) {
context.setLanguage(alist[0]);
navigatorLanguage = alist[0];
}
}
}
// Get language from cookie
try {
cookieLanguage = Util.normalizeLanguage(getUserPreferenceFromCookie("interfacelanguage", context));
} catch (Exception e) {
}
// Determine which language to use
// First we get the language from the request
if ((requestLanguage != null) && (!requestLanguage.equals(""))) {
if (requestLanguage.equals("default")) {
setCookie = true;
} else {
language = requestLanguage;
context.se