1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package com.xpn.xwiki

File XWiki.java

 

Coverage histogram

../../../img/srcFileCovDistChart6.png
69% of files have more coverage

Code metrics

852
2,274
389
1
7,103
4,748
955
0.42
5.85
389
2.46

Classes

Class Line # Actions
XWiki 237 2,274 0% 955 1,652
0.530014253%
 

Contributing tests

This file is covered by 131 tests. .

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package com.xpn.xwiki;
21   
22    import java.io.ByteArrayInputStream;
23    import java.io.File;
24    import java.io.FileInputStream;
25    import java.io.FileNotFoundException;
26    import java.io.IOException;
27    import java.io.InputStream;
28    import java.io.PrintWriter;
29    import java.io.StringWriter;
30    import java.lang.reflect.Field;
31    import java.lang.reflect.InvocationTargetException;
32    import java.lang.reflect.Method;
33    import java.lang.reflect.Type;
34    import java.net.MalformedURLException;
35    import java.net.URL;
36    import java.text.DateFormatSymbols;
37    import java.text.SimpleDateFormat;
38    import java.util.ArrayList;
39    import java.util.Arrays;
40    import java.util.Collections;
41    import java.util.Comparator;
42    import java.util.Date;
43    import java.util.Enumeration;
44    import java.util.HashMap;
45    import java.util.HashSet;
46    import java.util.List;
47    import java.util.ListIterator;
48    import java.util.Locale;
49    import java.util.Map;
50    import java.util.Set;
51    import java.util.TimeZone;
52    import java.util.Vector;
53    import java.util.concurrent.ConcurrentHashMap;
54    import java.util.regex.Pattern;
55    import java.util.zip.ZipOutputStream;
56   
57    import javax.annotation.Priority;
58    import javax.inject.Provider;
59    import javax.mail.Message;
60    import javax.mail.Session;
61    import javax.mail.internet.InternetAddress;
62    import javax.mail.internet.MimeMessage;
63    import javax.naming.NamingException;
64    import javax.script.ScriptContext;
65    import javax.servlet.http.Cookie;
66    import javax.servlet.http.HttpServletRequest;
67    import javax.servlet.http.HttpServletResponse;
68   
69    import org.apache.commons.httpclient.Credentials;
70    import org.apache.commons.httpclient.HttpClient;
71    import org.apache.commons.httpclient.URIException;
72    import org.apache.commons.httpclient.UsernamePasswordCredentials;
73    import org.apache.commons.httpclient.auth.AuthScope;
74    import org.apache.commons.httpclient.methods.GetMethod;
75    import org.apache.commons.httpclient.util.URIUtil;
76    import org.apache.commons.io.FileUtils;
77    import org.apache.commons.io.IOUtils;
78    import org.apache.commons.lang3.ArrayUtils;
79    import org.apache.commons.lang3.LocaleUtils;
80    import org.apache.commons.lang3.RandomStringUtils;
81    import org.apache.commons.lang3.StringUtils;
82    import org.apache.commons.lang3.exception.ExceptionUtils;
83    import org.apache.commons.lang3.math.NumberUtils;
84    import org.apache.commons.lang3.reflect.FieldUtils;
85    import org.apache.velocity.VelocityContext;
86    import org.hibernate.HibernateException;
87    import org.slf4j.Logger;
88    import org.slf4j.LoggerFactory;
89    import org.xwiki.bridge.event.DocumentCreatedEvent;
90    import org.xwiki.bridge.event.DocumentCreatingEvent;
91    import org.xwiki.bridge.event.DocumentDeletedEvent;
92    import org.xwiki.bridge.event.DocumentDeletingEvent;
93    import org.xwiki.bridge.event.DocumentRolledBackEvent;
94    import org.xwiki.bridge.event.DocumentRollingBackEvent;
95    import org.xwiki.bridge.event.DocumentUpdatedEvent;
96    import org.xwiki.bridge.event.DocumentUpdatingEvent;
97    import org.xwiki.bridge.event.WikiCopiedEvent;
98    import org.xwiki.bridge.event.WikiDeletedEvent;
99    import org.xwiki.cache.Cache;
100    import org.xwiki.classloader.ClassLoaderManager;
101    import org.xwiki.component.event.ComponentDescriptorAddedEvent;
102    import org.xwiki.component.manager.ComponentLookupException;
103    import org.xwiki.component.manager.ComponentManager;
104    import org.xwiki.component.manager.NamespacedComponentManager;
105    import org.xwiki.component.util.DefaultParameterizedType;
106    import org.xwiki.configuration.ConfigurationSource;
107    import org.xwiki.context.Execution;
108    import org.xwiki.edit.EditConfiguration;
109    import org.xwiki.job.Job;
110    import org.xwiki.job.JobException;
111    import org.xwiki.job.JobExecutor;
112    import org.xwiki.job.annotation.Serializable;
113    import org.xwiki.job.event.status.JobProgressManager;
114    import org.xwiki.job.event.status.JobStatus.State;
115    import org.xwiki.localization.ContextualLocalizationManager;
116    import org.xwiki.mail.MailListener;
117    import org.xwiki.mail.MailSender;
118    import org.xwiki.mail.MailSenderConfiguration;
119    import org.xwiki.mail.MailStatusResultSerializer;
120    import org.xwiki.mail.XWikiAuthenticator;
121    import org.xwiki.model.EntityType;
122    import org.xwiki.model.reference.AttachmentReference;
123    import org.xwiki.model.reference.AttachmentReferenceResolver;
124    import org.xwiki.model.reference.DocumentReference;
125    import org.xwiki.model.reference.DocumentReferenceResolver;
126    import org.xwiki.model.reference.EntityReference;
127    import org.xwiki.model.reference.EntityReferenceResolver;
128    import org.xwiki.model.reference.EntityReferenceSerializer;
129    import org.xwiki.model.reference.LocalDocumentReference;
130    import org.xwiki.model.reference.ObjectReference;
131    import org.xwiki.model.reference.RegexEntityReference;
132    import org.xwiki.model.reference.SpaceReference;
133    import org.xwiki.model.reference.WikiReference;
134    import org.xwiki.observation.EventListener;
135    import org.xwiki.observation.ObservationManager;
136    import org.xwiki.observation.event.CancelableEvent;
137    import org.xwiki.observation.event.Event;
138    import org.xwiki.query.QueryException;
139    import org.xwiki.query.QueryFilter;
140    import org.xwiki.rendering.block.Block;
141    import org.xwiki.rendering.block.Block.Axes;
142    import org.xwiki.rendering.block.MetaDataBlock;
143    import org.xwiki.rendering.block.match.MetadataBlockMatcher;
144    import org.xwiki.rendering.internal.transformation.MutableRenderingContext;
145    import org.xwiki.rendering.listener.MetaData;
146    import org.xwiki.rendering.parser.ParseException;
147    import org.xwiki.rendering.syntax.Syntax;
148    import org.xwiki.rendering.syntax.SyntaxContent;
149    import org.xwiki.rendering.syntax.SyntaxFactory;
150    import org.xwiki.rendering.transformation.RenderingContext;
151    import org.xwiki.resource.ResourceReference;
152    import org.xwiki.resource.ResourceReferenceManager;
153    import org.xwiki.resource.ResourceReferenceResolver;
154    import org.xwiki.resource.ResourceType;
155    import org.xwiki.resource.ResourceTypeResolver;
156    import org.xwiki.resource.entity.EntityResourceReference;
157    import org.xwiki.script.ScriptContextManager;
158    import org.xwiki.skin.Resource;
159    import org.xwiki.skin.Skin;
160    import org.xwiki.skin.SkinManager;
161    import org.xwiki.template.TemplateManager;
162    import org.xwiki.url.ExtendedURL;
163    import org.xwiki.velocity.VelocityManager;
164    import org.xwiki.wiki.descriptor.WikiDescriptor;
165    import org.xwiki.wiki.descriptor.WikiDescriptorManager;
166    import org.xwiki.wiki.manager.WikiManager;
167    import org.xwiki.wiki.manager.WikiManagerException;
168    import org.xwiki.xml.XMLUtils;
169   
170    import com.xpn.xwiki.api.Api;
171    import com.xpn.xwiki.api.Document;
172    import com.xpn.xwiki.api.User;
173    import com.xpn.xwiki.criteria.api.XWikiCriteriaService;
174    import com.xpn.xwiki.doc.DeletedAttachment;
175    import com.xpn.xwiki.doc.MandatoryDocumentInitializer;
176    import com.xpn.xwiki.doc.XWikiAttachment;
177    import com.xpn.xwiki.doc.XWikiDeletedDocument;
178    import com.xpn.xwiki.doc.XWikiDocument;
179    import com.xpn.xwiki.doc.XWikiDocument.XWikiAttachmentToRemove;
180    import com.xpn.xwiki.doc.XWikiDocumentArchive;
181    import com.xpn.xwiki.internal.WikiInitializerJob;
182    import com.xpn.xwiki.internal.WikiInitializerRequest;
183    import com.xpn.xwiki.internal.XWikiCfgConfigurationSource;
184    import com.xpn.xwiki.internal.XWikiConfigDelegate;
185    import com.xpn.xwiki.internal.XWikiInitializerJob;
186    import com.xpn.xwiki.internal.event.XObjectPropertyAddedEvent;
187    import com.xpn.xwiki.internal.event.XObjectPropertyDeletedEvent;
188    import com.xpn.xwiki.internal.event.XObjectPropertyEvent;
189    import com.xpn.xwiki.internal.event.XObjectPropertyUpdatedEvent;
190    import com.xpn.xwiki.internal.render.OldRendering;
191    import com.xpn.xwiki.internal.render.groovy.ParseGroovyFromString;
192    import com.xpn.xwiki.internal.skin.InternalSkinConfiguration;
193    import com.xpn.xwiki.internal.skin.InternalSkinManager;
194    import com.xpn.xwiki.internal.skin.WikiSkin;
195    import com.xpn.xwiki.internal.skin.WikiSkinUtils;
196    import com.xpn.xwiki.job.JobRequestContext;
197    import com.xpn.xwiki.objects.BaseObject;
198    import com.xpn.xwiki.objects.PropertyInterface;
199    import com.xpn.xwiki.objects.classes.BaseClass;
200    import com.xpn.xwiki.objects.classes.PasswordClass;
201    import com.xpn.xwiki.objects.classes.PropertyClass;
202    import com.xpn.xwiki.objects.meta.MetaClass;
203    import com.xpn.xwiki.plugin.XWikiPluginInterface;
204    import com.xpn.xwiki.plugin.XWikiPluginManager;
205    import com.xpn.xwiki.render.groovy.XWikiPageClassLoader;
206    import com.xpn.xwiki.stats.api.XWikiStatsService;
207    import com.xpn.xwiki.stats.impl.SearchEngineRule;
208    import com.xpn.xwiki.stats.impl.XWikiStatsServiceImpl;
209    import com.xpn.xwiki.store.AttachmentRecycleBinStore;
210    import com.xpn.xwiki.store.AttachmentVersioningStore;
211    import com.xpn.xwiki.store.XWikiAttachmentStoreInterface;
212    import com.xpn.xwiki.store.XWikiCacheStore;
213    import com.xpn.xwiki.store.XWikiCacheStoreInterface;
214    import com.xpn.xwiki.store.XWikiHibernateStore;
215    import com.xpn.xwiki.store.XWikiRecycleBinStoreInterface;
216    import com.xpn.xwiki.store.XWikiStoreInterface;
217    import com.xpn.xwiki.store.XWikiVersioningStoreInterface;
218    import com.xpn.xwiki.user.api.XWikiAuthService;
219    import com.xpn.xwiki.user.api.XWikiGroupService;
220    import com.xpn.xwiki.user.api.XWikiRightService;
221    import com.xpn.xwiki.user.api.XWikiUser;
222    import com.xpn.xwiki.user.impl.xwiki.XWikiAuthServiceImpl;
223    import com.xpn.xwiki.user.impl.xwiki.XWikiGroupServiceImpl;
224    import com.xpn.xwiki.user.impl.xwiki.XWikiRightServiceImpl;
225    import com.xpn.xwiki.util.Util;
226    import com.xpn.xwiki.util.XWikiStubContextProvider;
227    import com.xpn.xwiki.web.Utils;
228    import com.xpn.xwiki.web.XWikiEngineContext;
229    import com.xpn.xwiki.web.XWikiMessageTool;
230    import com.xpn.xwiki.web.XWikiRequest;
231    import com.xpn.xwiki.web.XWikiURLFactory;
232    import com.xpn.xwiki.web.XWikiURLFactoryService;
233    import com.xpn.xwiki.web.XWikiURLFactoryServiceImpl;
234    import com.xpn.xwiki.web.includeservletasstring.IncludeServletAsString;
235   
236    @Serializable(false)
 
237    public class XWiki implements EventListener
238    {
239    /** Name of the default wiki. */
240    public static final String DEFAULT_MAIN_WIKI = "xwiki";
241   
242    /** Name of the default home space. */
243    public static final String DEFAULT_HOME_SPACE = "Main";
244   
245    /** Name of the default system space. */
246    public static final String SYSTEM_SPACE = "XWiki";
247   
248    /** Name of the default space homepage. */
249    public static final String DEFAULT_SPACE_HOMEPAGE = "WebHome";
250   
251    public static final String CKEY_SKIN = InternalSkinManager.CKEY_SKIN;
252   
253    public static final String CKEY_BASESKIN = InternalSkinManager.CKEY_PARENTSKIN;
254   
255    public static final String DEFAULT_SKIN = InternalSkinConfiguration.DEFAULT_SKIN;
256   
257    /** Logging helper object. */
258    protected static final Logger LOGGER = LoggerFactory.getLogger(XWiki.class);
259   
260    /** Frequently used Document reference, the class which holds virtual wiki definitions. */
261    private static final DocumentReference VIRTUAL_WIKI_DEFINITION_CLASS_REFERENCE =
262    new DocumentReference(DEFAULT_MAIN_WIKI, SYSTEM_SPACE, "XWikiServerClass");
263   
264    /** The default encoding, and the internally used encoding when dealing with byte representation of strings. */
265    public static final String DEFAULT_ENCODING = "UTF-8";
266   
267    /** Represents no value (ie the default value will be used) in xproperties */
268    private static final String NO_VALUE = "---";
269   
270    /** The main document storage. */
271    private XWikiStoreInterface store;
272   
273    /** The attachment storage (excluding attachment history). */
274    private XWikiAttachmentStoreInterface attachmentStore;
275   
276    /** Store for attachment archives. */
277    private AttachmentVersioningStore attachmentVersioningStore;
278   
279    /** Document versioning storage. */
280    private XWikiVersioningStoreInterface versioningStore;
281   
282    /** Deleted documents storage. */
283    private XWikiRecycleBinStoreInterface recycleBinStore;
284   
285    /**
286    * Storage for deleted attachment.
287    *
288    * @since 1.4M1
289    */
290    private AttachmentRecycleBinStore attachmentRecycleBinStore;
291   
292    private XWikiPluginManager pluginManager;
293   
294    private XWikiAuthService authService;
295   
296    private XWikiRightService rightService;
297   
298    private XWikiGroupService groupService;
299   
300    private XWikiStatsService statsService;
301   
302    private XWikiURLFactoryService urlFactoryService;
303   
304    private XWikiCriteriaService criteriaService;
305   
306    /** Lock object used for the lazy initialization of the authentication service. */
307    private final Object AUTH_SERVICE_LOCK = new Object();
308   
309    /** Lock object used for the lazy initialization of the authorization service. */
310    private final Object RIGHT_SERVICE_LOCK = new Object();
311   
312    /** Lock object used for the lazy initialization of the group management service. */
313    private final Object GROUP_SERVICE_LOCK = new Object();
314   
315    /** Lock object used for the lazy initialization of the statistics service. */
316    private final Object STATS_SERVICE_LOCK = new Object();
317   
318    /** Lock object used for the lazy initialization of the URL Factory service. */
319    private final Object URLFACTORY_SERVICE_LOCK = new Object();
320   
321    private MetaClass metaclass;
322   
323    private String version;
324   
325    private XWikiEngineContext engine_context;
326   
327    private String database;
328   
329    private String fullNameSQL;
330   
331    /**
332    * The list of initialized wikis.
333    */
334    private Map<String, WikiInitializerJob> initializedWikis = new ConcurrentHashMap<>();
335   
336    private boolean isReadOnly = false;
337   
338    /**
339    * @deprecated since 6.1M2, use {@link XWikiCfgConfigurationSource#CFG_ENV_NAME} instead
340    */
341    @Deprecated
342    public static final String CFG_ENV_NAME = XWikiCfgConfigurationSource.CFG_ENV_NAME;
343   
344    public static final String MACROS_FILE = "/templates/macros.txt";
345   
346    /**
347    * File containing XWiki's version, in the format: <version name>.<SVN revision number>.
348    */
349    private static final String VERSION_FILE = "/WEB-INF/version.properties";
350   
351    /**
352    * Property containing the version value in the {@link #VERSION_FILE} file.
353    */
354    private static final String VERSION_FILE_PROPERTY = "version";
355   
356    private static XWikiInitializerJob job;
357   
358    /** List of configured syntax ids. */
359    private List<String> configuredSyntaxes;
360   
361    /** Used to convert a proper Document Reference to string (standard form). */
362    private EntityReferenceSerializer<String> defaultEntityReferenceSerializer;
363   
364    /**
365    * Used to resolve a string into a proper Document Reference using the current document's reference to fill the
366    * blanks, except for the page name for which the default page name is used instead.
367    */
368    private DocumentReferenceResolver<String> currentMixedDocumentReferenceResolver;
369   
370    private DocumentReferenceResolver<EntityReference> currentReferenceDocumentReferenceResolver;
371   
372    private EntityReferenceResolver<String> currentMixedEntityReferenceResolver;
373   
374    private EntityReferenceResolver<String> relativeEntityReferenceResolver;
375   
376    private EntityReferenceSerializer<String> localStringEntityReferenceSerializer;
377   
378    private SyntaxFactory syntaxFactory;
379   
380    private ResourceReferenceManager resourceReferenceManager;
381   
382    private JobExecutor jobExecutor;
383   
384    private InternalSkinManager internalSkinManager;
385   
386    private TemplateManager templateManager;
387   
388    private RenderingContext renderingContext;
389   
390    /**
391    * Whether backlinks are enabled or not (cached for performance).
392    *
393    * @since 3.2M2
394    */
395    private Boolean hasBacklinks;
396   
397    private ConfigurationSource xwikicfg;
398   
399    private ConfigurationSource wikiConfiguration;
400   
401    private ConfigurationSource userConfiguration;
402   
403    private ConfigurationSource spaceConfiguration;
404   
405    private EditConfiguration editConfiguration;
406   
407    private ObservationManager observationManager;
408   
409    private Provider<XWikiContext> xcontextProvider;
410   
411    private ContextualLocalizationManager localization;
412   
413    private Provider<OldRendering> oldRenderingProvider;
414   
415    private ParseGroovyFromString parseGroovyFromString;
416   
417    private JobProgressManager progress;
418   
419    private Provider<DocumentReference> defaultDocumentReferenceProvider;
420   
421    private DocumentReferenceResolver<EntityReference> currentgetdocumentResolver;
422   
423    private AttachmentReferenceResolver<EntityReference> currentAttachmentReferenceResolver;
424   
425    private WikiSkinUtils wikiSkinUtils;
426   
427    /**
428    * List of top level space names that can be used in the fake context document created when accessing a resource
429    * with the 'skin' action.
430    */
431    private List<String> SKIN_RESOURCE_SPACE_NAMES = Arrays.asList("skins", "resources");
432   
 
433  1285888 toggle private ConfigurationSource getConfiguration()
434    {
435  1285893 if (this.xwikicfg == null) {
436  156 this.xwikicfg = Utils.getComponent(ConfigurationSource.class, XWikiCfgConfigurationSource.ROLEHINT);
437    }
438   
439  1285885 return this.xwikicfg;
440    }
441   
 
442  467106 toggle private ConfigurationSource getWikiConfiguration()
443    {
444  467102 if (this.wikiConfiguration == null) {
445  95 this.wikiConfiguration = Utils.getComponent(ConfigurationSource.class, "wiki");
446    }
447   
448  467088 return this.wikiConfiguration;
449    }
450   
 
451  76029 toggle private ConfigurationSource getSpaceConfiguration()
452    {
453  76029 if (this.spaceConfiguration == null) {
454  34 this.spaceConfiguration = Utils.getComponent(ConfigurationSource.class, "space");
455    }
456   
457  76024 return this.spaceConfiguration;
458    }
459   
 
460  7930 toggle private ConfigurationSource getUserConfiguration()
461    {
462  7928 if (this.userConfiguration == null) {
463  29 this.userConfiguration = Utils.getComponent(ConfigurationSource.class, "user");
464    }
465   
466  7928 return this.userConfiguration;
467    }
468   
 
469  92 toggle private EditConfiguration getEditConfiguration()
470    {
471  92 if (this.editConfiguration == null) {
472  12 this.editConfiguration = Utils.getComponent(EditConfiguration.class);
473    }
474   
475  92 return this.editConfiguration;
476    }
477   
 
478  50810 toggle private InternalSkinManager getInternalSkinManager()
479    {
480  50811 if (this.internalSkinManager == null) {
481  36 this.internalSkinManager = Utils.getComponent(InternalSkinManager.class);
482    }
483   
484  50807 return this.internalSkinManager;
485    }
486   
 
487  78482 toggle private TemplateManager getTemplateManager()
488    {
489  78479 if (this.templateManager == null) {
490  35 this.templateManager = Utils.getComponent(TemplateManager.class);
491    }
492   
493  78471 return this.templateManager;
494    }
495   
 
496  12149 toggle private RenderingContext getRenderingContext()
497    {
498  12193 if (this.renderingContext == null) {
499  33 this.renderingContext = Utils.getComponent(RenderingContext.class);
500    }
501   
502  12182 return this.renderingContext;
503    }
504   
 
505  0 toggle private MutableRenderingContext getMutableRenderingContext()
506    {
507  0 return getRenderingContext() instanceof MutableRenderingContext
508    ? (MutableRenderingContext) getRenderingContext() : null;
509    }
510   
 
511  4145 toggle private ObservationManager getObservationManager()
512    {
513  4145 if (this.observationManager == null) {
514  103 this.observationManager = Utils.getComponent(ObservationManager.class);
515    }
516   
517  4145 return this.observationManager;
518    }
519   
 
520  0 toggle private XWikiContext getXWikiContext()
521    {
522  0 if (this.xcontextProvider == null) {
523  0 this.xcontextProvider = Utils.getComponent(XWikiContext.TYPE_PROVIDER);
524    }
525   
526  0 return this.xcontextProvider.get();
527    }
528   
 
529  1069 toggle private ContextualLocalizationManager getLocalization()
530    {
531  1069 if (this.localization == null) {
532  66 this.localization = Utils.getComponent(ContextualLocalizationManager.class);
533    }
534   
535  1069 return this.localization;
536    }
537   
 
538  54 toggle private OldRendering getOldRendering()
539    {
540  54 if (this.oldRenderingProvider == null) {
541  8 this.oldRenderingProvider = Utils.getComponent(OldRendering.TYPE_PROVIDER);
542    }
543   
544  54 return this.oldRenderingProvider.get();
545    }
546   
 
547  0 toggle private ParseGroovyFromString getParseGroovyFromString()
548    {
549  0 if (this.parseGroovyFromString == null) {
550  0 this.parseGroovyFromString = Utils.getComponent(ParseGroovyFromString.class);
551    }
552   
553  0 return this.parseGroovyFromString;
554    }
555   
 
556  522 toggle private JobProgressManager getProgress()
557    {
558  522 if (this.progress == null) {
559  87 this.progress = Utils.getComponent(JobProgressManager.class);
560    }
561   
562  522 return this.progress;
563    }
564   
 
565  0 toggle private Provider<DocumentReference> getDefaultDocumentReferenceProvider()
566    {
567  0 if (this.defaultDocumentReferenceProvider == null) {
568  0 this.defaultDocumentReferenceProvider = Utils.getComponent(DocumentReference.TYPE_PROVIDER);
569    }
570   
571  0 return this.defaultDocumentReferenceProvider;
572    }
573   
 
574  3052 toggle private DocumentReferenceResolver<EntityReference> getCurrentGetDocumentResolver()
575    {
576  3052 if (this.currentgetdocumentResolver == null) {
577  65 this.currentgetdocumentResolver =
578    Utils.getComponent(DocumentReferenceResolver.TYPE_REFERENCE, "currentgetdocument");
579    }
580   
581  3052 return this.currentgetdocumentResolver;
582    }
583   
 
584  1 toggle private AttachmentReferenceResolver<EntityReference> getCurrentAttachmentResolver()
585    {
586  1 if (this.currentAttachmentReferenceResolver == null) {
587  1 this.currentAttachmentReferenceResolver =
588    Utils.getComponent(AttachmentReferenceResolver.TYPE_REFERENCE, "current");
589    }
590   
591  1 return this.currentAttachmentReferenceResolver;
592    }
593   
 
594  87 toggle private EntityReferenceSerializer<String> getDefaultEntityReferenceSerializer()
595    {
596  87 if (this.defaultEntityReferenceSerializer == null) {
597  11 this.defaultEntityReferenceSerializer = Utils.getComponent(EntityReferenceSerializer.TYPE_STRING);
598    }
599   
600  87 return this.defaultEntityReferenceSerializer;
601    }
602   
 
603  53798 toggle private DocumentReferenceResolver<String> getCurrentMixedDocumentReferenceResolver()
604    {
605  53798 if (this.currentMixedDocumentReferenceResolver == null) {
606  41 this.currentMixedDocumentReferenceResolver =
607    Utils.getComponent(DocumentReferenceResolver.TYPE_STRING, "currentmixed");
608    }
609   
610  53790 return this.currentMixedDocumentReferenceResolver;
611    }
612   
 
613  2107 toggle private DocumentReferenceResolver<EntityReference> getCurrentReferenceDocumentReferenceResolver()
614    {
615  2107 if (this.currentReferenceDocumentReferenceResolver == null) {
616  60 this.currentReferenceDocumentReferenceResolver =
617    Utils.getComponent(DocumentReferenceResolver.TYPE_REFERENCE, "current");
618    }
619   
620  2107 return this.currentReferenceDocumentReferenceResolver;
621    }
622   
 
623  0 toggle private EntityReferenceResolver<String> getCurrentMixedEntityReferenceResolver()
624    {
625  0 if (this.currentMixedEntityReferenceResolver == null) {
626  0 this.currentMixedEntityReferenceResolver =
627    Utils.getComponent(EntityReferenceResolver.TYPE_STRING, "currentmixed");
628    }
629   
630  0 return this.currentMixedEntityReferenceResolver;
631    }
632   
 
633  29 toggle private EntityReferenceResolver<String> getRelativeEntityReferenceResolver()
634    {
635  29 if (this.relativeEntityReferenceResolver == null) {
636  10 this.relativeEntityReferenceResolver = Utils.getComponent(EntityReferenceResolver.TYPE_STRING, "relative");
637    }
638   
639  29 return this.relativeEntityReferenceResolver;
640    }
641   
 
642  44315 toggle private EntityReferenceSerializer<String> getLocalStringEntityReferenceSerializer()
643    {
644  44315 if (this.localStringEntityReferenceSerializer == null) {
645  32 this.localStringEntityReferenceSerializer =
646    Utils.getComponent(EntityReferenceSerializer.TYPE_STRING, "local");
647    }
648   
649  44313 return this.localStringEntityReferenceSerializer;
650    }
651   
 
652  0 toggle private SyntaxFactory getSyntaxFactory()
653    {
654  0 if (this.syntaxFactory == null) {
655  0 this.syntaxFactory = Utils.getComponent(SyntaxFactory.class);
656    }
657   
658  0 return this.syntaxFactory;
659    }
660   
 
661  10251 toggle private ResourceReferenceManager getResourceReferenceManager()
662    {
663  10241 if (this.resourceReferenceManager == null) {
664  34 this.resourceReferenceManager = Utils.getComponent(ResourceReferenceManager.class);
665    }
666   
667  10199 return this.resourceReferenceManager;
668    }
669   
 
670  32 toggle private JobExecutor getJobExecutor()
671    {
672  32 if (this.jobExecutor == null) {
673  29 this.jobExecutor = Utils.getComponent(JobExecutor.class);
674    }
675   
676  32 return this.jobExecutor;
677    }
678   
 
679  0 toggle private DocumentReference getDefaultDocumentReference()
680    {
681  0 return getDefaultDocumentReferenceProvider().get();
682    }
683   
 
684  0 toggle private WikiSkinUtils getWikiSkinUtils()
685    {
686  0 if (this.wikiSkinUtils == null) {
687  0 this.wikiSkinUtils = Utils.getComponent(WikiSkinUtils.class);
688    }
689   
690  0 return this.wikiSkinUtils;
691    }
692   
 
693  1069 toggle private String localizePlainOrKey(String key, Object... parameters)
694    {
695  1069 return StringUtils.defaultString(getLocalization().getTranslationPlain(key, parameters), key);
696    }
697   
698    /**
699    * @param context see {@link XWikiContext}
700    */
 
701  0 toggle public static XWiki getMainXWiki(XWikiContext context) throws XWikiException
702    {
703  0 return getMainXWiki(true, context);
704    }
705   
706    /**
707    * @param wait true if the method should way for {@link XWiki} instance to be initialized
708    * @param context see {@link XWikiContext}
709    */
 
710  11433 toggle public static XWiki getMainXWiki(boolean wait, XWikiContext context) throws XWikiException
711    {
712  11436 String xwikiname = DEFAULT_MAIN_WIKI;
713   
714  11413 context.setMainXWiki(xwikiname);
715   
716  11419 XWiki xwiki;
717   
718  11427 try {
719  11427 XWikiEngineContext econtext = context.getEngineContext();
720   
721  11404 xwiki = (XWiki) econtext.getAttribute(xwikiname);
722  11449 if (xwiki == null) {
723    // Start XWiki initialization
724  36 synchronized (XWiki.class) {
725  36 xwiki = (XWiki) econtext.getAttribute(xwikiname);
726  36 if (xwiki == null && job == null) {
727  32 job = Utils.getComponent((Type) Job.class, XWikiInitializerJob.JOBTYPE);
728   
729  32 if (job.getStatus() == null) {
730    // "Pre-initialize" XWikiStubContextProvider so that XWiki initializer can find one
731  32 Utils.<XWikiStubContextProvider>getComponent(XWikiStubContextProvider.class)
732    .initialize(context);
733   
734  32 job.startAsync();
735    }
736    }
737    }
738   
739    // Wait until XWiki is initialized
740  36 if (wait) {
741  36 job.join();
742  36 xwiki = (XWiki) econtext.getAttribute(xwikiname);
743    }
744    }
745   
746  11449 context.setWiki(xwiki);
747   
748  11448 return xwiki;
749    } catch (Exception e) {
750  0 throw new XWikiException(XWikiException.MODULE_XWIKI, XWikiException.ERROR_XWIKI_INIT_FAILED,
751    "Could not initialize main XWiki instance", e);
752    }
753    }
754   
 
755  0 toggle public static boolean isInitializing(XWikiContext xcontext)
756    {
757  0 return Boolean.TRUE.equals(xcontext.getEngineContext().getAttribute("xwiki.init"));
758    }
759   
760    /**
761    * Return the XWiki object (as in "the Wiki API") corresponding to the requested wiki.
762    *
763    * @param context see {@link XWikiContext}
764    * @return an XWiki object configured for the wiki corresponding to the current request
765    * @throws XWikiException if the requested URL does not correspond to a real wiki, or if there's an error in the
766    * storage
767    */
 
768  1796 toggle public static XWiki getXWiki(XWikiContext context) throws XWikiException
769    {
770  1796 return getXWiki(true, context);
771    }
772   
773    /**
774    * Return the XWiki object (as in "the Wiki API") corresponding to the requested wiki.
775    * <p>
776    * Unless <code>wait</code> is false the method return right away null if XWiki is not yet initialized.
777    *
778    * @param wait wait until XWiki is initialized
779    * @param xcontext see {@link XWikiContext}
780    * @return an XWiki object configured for the wiki corresponding to the current request
781    * @throws XWikiException if the requested URL does not correspond to a real wiki, or if there's an error in the
782    * storage
783    */
 
784  11445 toggle public static XWiki getXWiki(boolean wait, XWikiContext xcontext) throws XWikiException
785    {
786  11442 XWiki xwiki = getMainXWiki(wait, xcontext);
787   
788  11449 if (xwiki == null) {
789  0 return null;
790    }
791   
792    // Extract Entity Resource from URL and put it in the Execution Context
793  11449 EntityResourceReference entityResourceReference = initializeResourceFromURL(xcontext);
794   
795    // Get the wiki id
796  11449 String wikiId = entityResourceReference.getEntityReference().extractReference(EntityType.WIKI).getName();
797  11442 if (wikiId.equals(xcontext.getMainXWiki())) {
798    // The main wiki was requested.
799  11371 return xwiki;
800    }
801   
802    // Check if the wiki exists by checking if a descriptor exists for the wiki id.
803  65 WikiDescriptorManager wikiDescriptorManager = Utils.getComponent(WikiDescriptorManager.class);
804  65 WikiDescriptor descriptor;
805  65 try {
806  65 descriptor = wikiDescriptorManager.getById(wikiId);
807    } catch (WikiManagerException e) {
808  0 throw new XWikiException(XWikiException.MODULE_XWIKI, XWikiException.ERROR_XWIKI_STORE_MISC,
809    String.format("Failed find wiki descriptor for wiki id [%s]", wikiId), e);
810    }
811  65 if (descriptor == null) {
812  0 throw new XWikiException(XWikiException.MODULE_XWIKI, XWikiException.ERROR_XWIKI_DOES_NOT_EXIST,
813    String.format("The wiki [%s] does not exist", wikiId));
814    }
815   
816    // Initialize wiki
817   
818  65 xcontext.setWikiId(wikiId);
819  65 xcontext.setOriginalWikiId(wikiId);
820   
821  64 if (!xwiki.initializeWiki(wikiId, wait, xcontext)) {
822    // The wiki is still initializing
823  0 return null;
824    }
825   
826  65 return xwiki;
827    }
828   
829    /**
830    * @param wikiId the identifier of the wiki
831    * @return the current {@link WikiInitializerJob} associated to the passed wiki or null if there is none
832    */
 
833  0 toggle public Job getWikiInitializerJob(String wikiId)
834    {
835  0 return this.initializedWikis.get(wikiId);
836    }
837   
838    /**
839    * Make sure the wiki is initializing or wait for it.
840    *
841    * @param wikiId the identifier of the wiki to initialize
842    * @param wait true if the method should return only when the wiki is fully initialized
843    * @return true if the wiki is fully initialized
844    * @param xcontext the XWiki context
845    * @throws XWikiException when the initialization failed
846    * @since 8.4RC1
847    */
 
848  96 toggle public boolean initializeWiki(String wikiId, boolean wait, XWikiContext xcontext) throws XWikiException
849    {
850  96 Job wikiJob = this.initializedWikis.get(wikiId);
851   
852    // Create and start the job if it does not exist
853  97 if (wikiJob == null) {
854  32 try {
855  32 wikiJob = initializeWiki(wikiId, xcontext);
856    } catch (JobException e) {
857  0 throw new XWikiException(XWikiException.MODULE_XWIKI, XWikiException.ERROR_XWIKI_INIT_FAILED,
858    "Could not start [" + wikiId + "] wiki initialization", e);
859    }
860    }
861   
862    // Check if the job is done
863  97 if (wikiJob.getStatus().getState() == State.FINISHED) {
864  64 return true;
865    }
866   
867    // Wait until the job is finished if asked to
868  32 if (wait) {
869  32 try {
870  32 wikiJob.join();
871    } catch (InterruptedException e) {
872  0 throw new XWikiException(XWikiException.MODULE_XWIKI, XWikiException.ERROR_XWIKI_INIT_FAILED,
873    "Wiki [" + wikiId + "] initialization was interrupted unexpectedly", e);
874    }
875   
876  32 if (wikiJob.getStatus().getError() != null) {
877  0 throw new XWikiException(XWikiException.MODULE_XWIKI, XWikiException.ERROR_XWIKI_INIT_FAILED,
878    "Wiki [" + wikiId + "] initialization failed", wikiJob.getStatus().getError());
879    }
880   
881  32 return true;
882    }
883   
884    // Still initializing
885  0 return false;
886    }
887   
 
888  32 toggle private Job initializeWiki(String wikiId, XWikiContext xcontext) throws JobException
889    {
890  32 synchronized (this.initializedWikis) {
891  32 WikiInitializerJob wikiJob = this.initializedWikis.get(wikiId);
892   
893  32 if (wikiJob == null) {
894  32 WikiInitializerRequest request = new WikiInitializerRequest(wikiId);
895   
896  32 JobRequestContext.set(request, xcontext);
897   
898  32 wikiJob = (WikiInitializerJob) getJobExecutor().execute(WikiInitializerJob.JOBTYPE, request);
899  32 this.initializedWikis.put(wikiId, wikiJob);
900    }
901   
902  32 return wikiJob;
903    }
904    }
905   
 
906  11446 toggle private static EntityResourceReference initializeResourceFromURL(XWikiContext context) throws XWikiException
907    {
908    // Extract the Entity Resource from the URL
909    // TODO: This code should be put in an ExecutionContextInitializer but we couldn't do yet since this code
910    // requires that the XWiki object be initialized first (the line above). Thus we'll be able to to move it only
911    // after the XWiki init is done also in an ExecutionContextInitializer (and with priorities).
912  11445 @SuppressWarnings("deprecation")
913    EntityResourceReference entityResourceReference;
914  11447 URL url = context.getURL();
915  11438 try {
916  11436 ExtendedURL extendedURL = new ExtendedURL(url, context.getRequest().getContextPath());
917  11447 ResourceTypeResolver<ExtendedURL> typeResolver =
918    Utils.getComponent(new DefaultParameterizedType(null, ResourceTypeResolver.class, ExtendedURL.class));
919  11449 ResourceType type = typeResolver.resolve(extendedURL, Collections.<String, Object>emptyMap());
920  11449 ResourceReferenceResolver<ExtendedURL> resourceResolver = Utils
921    .getComponent(new DefaultParameterizedType(null, ResourceReferenceResolver.class, ExtendedURL.class));
922  11449 entityResourceReference = (EntityResourceReference) resourceResolver.resolve(extendedURL, type,
923    Collections.<String, Object>emptyMap());
924    } catch (Exception e) {
925  0 throw new XWikiException(XWikiException.MODULE_XWIKI, XWikiException.ERROR_XWIKI_APP_URL_EXCEPTION,
926    String.format("Failed to extract Entity Resource Reference from URL [%s]", url), e);
927    }
928  11448 Utils.getComponent(Execution.class).getContext().setProperty(ResourceReferenceManager.RESOURCE_CONTEXT_PROPERTY,
929    entityResourceReference);
930   
931  11449 return entityResourceReference;
932    }
933   
 
934  11438 toggle public static URL getRequestURL(XWikiRequest request) throws XWikiException
935    {
936  11438 try {
937  11439 StringBuffer requestURL = request.getRequestURL();
938  11435 String qs = request.getQueryString();
939  11437 if ((qs != null) && (!qs.equals(""))) {
940  8081 return new URL(requestURL.toString() + "?" + qs);
941    } else {
942  3340 return new URL(requestURL.toString());
943    }
944    } catch (Exception e) {
945  0 throw new XWikiException(XWikiException.MODULE_XWIKI_APP, XWikiException.ERROR_XWIKI_APP_URL_EXCEPTION,
946    "Exception while getting URL from request", e);
947    }
948    }
949   
 
950  0 toggle public static Object callPrivateMethod(Object obj, String methodName)
951    {
952  0 return callPrivateMethod(obj, methodName, null, null);
953    }
954   
 
955  0 toggle public static Object callPrivateMethod(Object obj, String methodName, Class<?>[] classes, Object[] args)
956    {
957  0 try {
958  0 Method method = obj.getClass().getDeclaredMethod(methodName, classes);
959  0 method.setAccessible(true);
960  0 return method.invoke(obj, args);
961    } catch (IllegalAccessException e) {
962  0 LOGGER.error("Failed to call private method [{}]: [{}]", methodName, e);
963   
964  0 return null;
965    } catch (NoSuchMethodException e) {
966  0 return null;
967    } catch (InvocationTargetException e) {
968  0 LOGGER.error("Private method [{}] failed: [{}]", methodName, e);
969   
970  0 return null;
971    }
972    }
973   
 
974  0 toggle public static HttpClient getHttpClient(int timeout, String userAgent)
975    {
976  0 HttpClient client = new HttpClient();
977   
978  0 if (timeout != 0) {
979  0 client.getParams().setSoTimeout(timeout);
980  0 client.getParams().setParameter("http.connection.timeout", Integer.valueOf(timeout));
981    }
982   
983  0 client.getParams().setParameter("http.useragent", userAgent);
984   
985  0 String proxyHost = System.getProperty("http.proxyHost");
986  0 String proxyPort = System.getProperty("http.proxyPort");
987  0 if ((proxyHost != null) && (!proxyHost.equals(""))) {
988  0 int port = 3128;
989  0 if ((proxyPort != null) && (!proxyPort.equals(""))) {
990  0 port = Integer.parseInt(proxyPort);
991    }
992  0 client.getHostConfiguration().setProxy(proxyHost, port);
993    }
994   
995  0 String proxyUser = System.getProperty("http.proxyUser");
996  0 if ((proxyUser != null) && (!proxyUser.equals(""))) {
997  0 String proxyPassword = System.getProperty("http.proxyPassword");
998  0 Credentials defaultcreds = new UsernamePasswordCredentials(proxyUser, proxyPassword);
999  0 client.getState().setProxyCredentials(AuthScope.ANY, defaultcreds);
1000    }
1001   
1002  0 return client;
1003    }
1004   
1005    /**
1006    * Using reflection, read the private value of the passed field name for the passed object.
1007    *
1008    * @param obj the java object on which to read the private field value
1009    * @param fieldName the object member field for which to read the value
1010    * @return the private value for the field
1011    * @deprecated use {@link FieldUtils#readDeclaredField(Object, String, boolean)} instead
1012    */
 
1013  0 toggle @Deprecated
1014    public static Object getPrivateField(Object obj, String fieldName)
1015    {
1016  0 try {
1017  0 Field field = obj.getClass().getDeclaredField(fieldName);
1018  0 field.setAccessible(true);
1019  0 return field.get(obj);
1020    } catch (NoSuchFieldException e) {
1021  0 return null;
1022    } catch (IllegalAccessException e) {
1023  0 LOGGER.error("Failed to get private field with name [{}]: [{}]", fieldName, e);
1024   
1025  0 return null;
1026    } finally {
1027    }
1028    }
1029   
 
1030  10631 toggle public static String getServerWikiPage(String servername)
1031    {
1032  10631 return "XWiki.XWikiServer" + StringUtils.capitalize(servername);
1033    }
1034   
1035    /**
1036    * @param content the content of the text area
1037    * @param context see {@link XWikiContext}
1038    */
 
1039  0 toggle public static String getTextArea(String content, XWikiContext context)
1040    {
1041  0 StringBuilder result = new StringBuilder();
1042   
1043    // Forcing a new line after the <textarea> tag, as
1044    // http://www.w3.org/TR/html4/appendix/notes.html#h-B.3.1 causes an empty line at the start
1045    // of the document content to be trimmed.
1046  0 result.append("<textarea name=\"content\" id=\"content\" rows=\"25\" cols=\"80\">\n");
1047  0 result.append(XMLUtils.escape(content));
1048  0 result.append("</textarea>");
1049   
1050  0 return result.toString();
1051    }
1052   
1053    /**
1054    * This provide a way to create an XWiki object without initializing the whole XWiki (including plugins, storage,
1055    * etc.).
1056    * <p>
1057    * Needed for tools or tests which need XWiki because it is used everywhere in the API.
1058    */
 
1059  483 toggle public XWiki()
1060    {
1061    // Empty voluntarily
1062    }
1063   
1064    /**
1065    * Initialize all xwiki subsystems.
1066    *
1067    * @param context see {@link XWikiContext}
1068    * @param engineContext the XWiki object wrapping the {@link javax.servlet.ServletContext} and which allows to set
1069    * data that live on as long as the XWiki webapp is not stopped in the Servlet Container
1070    * @param noupdate true if the whole initialization should be done (create mandatory xlcasses, initialize stats
1071    * service), i.e. if this is not an update, and false otherwise
1072    * @throws XWikiException if an error happened during initialization (failure to initialize some cache for example)
1073    */
 
1074  32 toggle public XWiki(XWikiContext context, XWikiEngineContext engineContext, boolean noupdate) throws XWikiException
1075    {
1076  32 initXWiki(context, engineContext, noupdate);
1077    }
1078   
1079    /**
1080    * Initialize all xwiki subsystems.
1081    *
1082    * @param context see {@link XWikiContext}
1083    * @throws XWikiException if an error happened during initialization (failure to initialize some cache for example)
1084    */
 
1085  0 toggle public XWiki(XWikiContext context) throws XWikiException
1086    {
1087  0 this(context, null, false);
1088    }
1089   
1090    /**
1091    * Initialize all xwiki subsystems.
1092    *
1093    * @param context see {@link XWikiContext}
1094    * @param engineContext the XWiki object wrapping the {@link javax.servlet.ServletContext} and which allows to set
1095    * data that live on as long as the XWiki webapp is not stopped in the Servlet Container
1096    * @param noupdate true if the whole initialization should be done (create mandatory xlcasses, initialize stats
1097    * service), i.e. if this is not an update, and false otherwise
1098    * @throws XWikiException if an error happened during initialization (failure to initialize some cache for example)
1099    */
 
1100  32 toggle public void initXWiki(XWikiContext context, XWikiEngineContext engineContext, boolean noupdate)
1101    throws XWikiException
1102    {
1103  32 initXWiki(null, context, engineContext, noupdate);
1104    }
1105   
1106    /**
1107    * Initialize all xwiki subsystems.
1108    *
1109    * @param config the object holding the XWiki configuration read from {@code xwiki.cfg}
1110    * @param context see {@link XWikiContext}
1111    * @param engineContext the XWiki object wrapping the {@link javax.servlet.ServletContext} and which allows to set
1112    * data that live on as long as the XWiki webapp is not stopped in the Servlet Container
1113    * @param noupdate true if the whole initialization should be done (create mandatory xlcasses, initialize stats
1114    * service), i.e. if this is not an update, and false otherwise
1115    * @throws XWikiException if an error happened during initialization (failure to initialize some cache for example)
1116    * @deprecated since 6.1M2, use {@link #initXWiki(XWikiContext, XWikiEngineContext, boolean)} instead
1117    */
 
1118  87 toggle @Deprecated
1119    public void initXWiki(XWikiConfig config, XWikiContext context, XWikiEngineContext engineContext, boolean noupdate)
1120    throws XWikiException
1121    {
1122  87 getProgress().pushLevelProgress(4, this);
1123   
1124  87 try {
1125  87 getProgress().startStep(this);
1126   
1127  87 setDatabase(context.getMainXWiki());
1128   
1129  87 setEngineContext(engineContext);
1130  87 context.setWiki(this);
1131   
1132    // "Pre-initialize" XWikiStubContextProvider with a XWikiContext containing a XWiki instance as soon as
1133    // possible
1134  87 Utils.<XWikiStubContextProvider>getComponent(XWikiStubContextProvider.class).initialize(context);
1135   
1136    // Prepare the store
1137  87 if (config != null) {
1138  55 setConfig(config);
1139    }
1140   
1141  87 XWikiStoreInterface mainStore = Utils.getComponent(XWikiStoreInterface.class,
1142    getConfiguration().getProperty("xwiki.store.main.hint", "hibernate"));
1143   
1144    // Check if we need to use the cache store..
1145  87 boolean nocache = "0".equals(getConfiguration().getProperty("xwiki.store.cache", "1"));
1146  87 if (!nocache) {
1147  87 XWikiCacheStoreInterface cachestore = new XWikiCacheStore(mainStore, context);
1148  87 setStore(cachestore);
1149    } else {
1150  0 setStore(mainStore);
1151    }
1152   
1153  87 setCriteriaService((XWikiCriteriaService) createClassFromConfig("xwiki.criteria.class",
1154    "com.xpn.xwiki.criteria.impl.XWikiCriteriaServiceImpl", context));
1155   
1156  87 setAttachmentStore(Utils.<XWikiAttachmentStoreInterface>getComponent(XWikiAttachmentStoreInterface.class,
1157    getConfiguration().getProperty("xwiki.store.attachment.hint", "hibernate")));
1158   
1159  87 setVersioningStore(Utils.<XWikiVersioningStoreInterface>getComponent(XWikiVersioningStoreInterface.class,
1160    getConfiguration().getProperty("xwiki.store.versioning.hint", "hibernate")));
1161   
1162  87 setAttachmentVersioningStore(Utils.<AttachmentVersioningStore>getComponent(AttachmentVersioningStore.class,
1163  87 hasAttachmentVersioning(context)
1164    ? getConfiguration().getProperty("xwiki.store.attachment.versioning.hint", "hibernate") : "void"));
1165   
1166  87 if (hasRecycleBin(context)) {
1167  87 setRecycleBinStore(
1168    Utils.<XWikiRecycleBinStoreInterface>getComponent(XWikiRecycleBinStoreInterface.class,
1169    getConfiguration().getProperty("xwiki.store.recyclebin.hint", "hibernate")));
1170    }
1171   
1172  87 if (hasAttachmentRecycleBin(context)) {
1173  87 setAttachmentRecycleBinStore(
1174    Utils.<AttachmentRecycleBinStore>getComponent(AttachmentRecycleBinStore.class,
1175    getConfiguration().getProperty("xwiki.store.attachment.recyclebin.hint", "hibernate")));
1176    }
1177   
1178    // "Pre-initialize" XWikiStubContextProvider so that rendering engine, plugins or listeners reacting to
1179    // potential document changes can use it
1180  87 Utils.<XWikiStubContextProvider>getComponent(XWikiStubContextProvider.class).initialize(context);
1181   
1182  87 getProgress().startStep(this);
1183   
1184    // Make sure these classes exists
1185  87 if (noupdate) {
1186  60 initializeMandatoryDocuments(context);
1187  60 getStatsService(context);
1188    }
1189   
1190  87 getProgress().startStep(this);
1191   
1192    // Prepare the Plugin Engine
1193  87 preparePlugins(context);
1194   
1195  87 getProgress().startStep(this);
1196   
1197  87 String ro = getConfiguration().getProperty("xwiki.readonly", "no");
1198  87 this.isReadOnly = ("yes".equalsIgnoreCase(ro) || "true".equalsIgnoreCase(ro) || "1".equalsIgnoreCase(ro));
1199   
1200    // Save the configured syntaxes
1201  87 String syntaxes = getConfiguration().getProperty("xwiki.rendering.syntaxes", "xwiki/1.0");
1202  87 this.configuredSyntaxes = Arrays.asList(StringUtils.split(syntaxes, " ,"));
1203   
1204  87 getObservationManager().addListener(this);
1205    } finally {
1206  87 getProgress().popLevelProgress(this);
1207    }
1208    }
1209   
1210    /**
1211    * Ensure that mandatory classes (ie classes XWiki needs to work properly) exist and create them if they don't
1212    * exist.
1213    *
1214    * @param context see {@link XWikiContext}
1215    */
 
1216  92 toggle public void initializeMandatoryDocuments(XWikiContext context)
1217    {
1218  92 if (context.get("initdone") == null) {
1219  92 @SuppressWarnings("deprecation")
1220    List<MandatoryDocumentInitializer> initializers =
1221    Utils.getComponentList(MandatoryDocumentInitializer.class);
1222   
1223    // Sort the initializers based on priority. Lower priority values are first.
1224  92 Collections.sort(initializers, new Comparator<MandatoryDocumentInitializer>()
1225    {
 
1226  2103 toggle @Override
1227    public int compare(MandatoryDocumentInitializer left, MandatoryDocumentInitializer right)
1228    {
1229  2103 Priority leftPriority = left.getClass().getAnnotation(Priority.class);
1230  2103 int leftPriorityValue =
1231  2103 leftPriority != null ? leftPriority.value() : MandatoryDocumentInitializer.DEFAULT_PRIORITY;
1232   
1233  2103 Priority rightPriority = right.getClass().getAnnotation(Priority.class);
1234  2103 int rightPriorityValue =
1235  2103 rightPriority != null ? rightPriority.value() : MandatoryDocumentInitializer.DEFAULT_PRIORITY;
1236   
1237    // Compare the two.
1238  2103 return leftPriorityValue - rightPriorityValue;
1239    }
1240    });
1241   
1242  92 for (MandatoryDocumentInitializer initializer : initializers) {
1243  2107 initializeMandatoryDocument(initializer, context);
1244    }
1245    }
1246    }
1247   
 
1248  0 toggle private void initializeMandatoryDocument(String wiki, MandatoryDocumentInitializer initializer,
1249    XWikiContext context)
1250    {
1251  0 String currentWiki = context.getWikiId();
1252   
1253  0 try {
1254  0 context.setWikiId(wiki);
1255   
1256  0 initializeMandatoryDocument(initializer, context);
1257    } finally {
1258  0 context.setWikiId(currentWiki);
1259    }
1260    }
1261   
 
1262  2107 toggle private void initializeMandatoryDocument(MandatoryDocumentInitializer initializer, XWikiContext context)
1263    {
1264  2107 try {
1265  2107 DocumentReference documentReference =
1266    getCurrentReferenceDocumentReferenceResolver().resolve(initializer.getDocumentReference());
1267   
1268  2107 if (documentReference.getWikiReference().getName().equals(context.getWikiId())) {
1269  2095 XWikiDocument document = context.getWiki().getDocument(documentReference, context);
1270   
1271  2095 if (initializer.updateDocument(document)) {
1272  914 saveDocument(document,
1273    localizePlainOrKey("core.model.xclass.mandatoryUpdateProperty.versionSummary"), context);
1274    }
1275    }
1276    } catch (XWikiException e) {
1277  0 LOGGER.error("Failed to initialize mandatory document", e);
1278    }
1279    }
1280   
 
1281  12 toggle public XWikiStoreInterface getNotCacheStore()
1282    {
1283  12 XWikiStoreInterface store = getStore();
1284  12 if (store instanceof XWikiCacheStoreInterface) {
1285  12 store = ((XWikiCacheStoreInterface) store).getStore();
1286    }
1287  12 return store;
1288    }
1289   
 
1290  11297 toggle public XWikiHibernateStore getHibernateStore()
1291    {
1292  11296 XWikiStoreInterface store = getStore();
1293  11298 if (store instanceof XWikiHibernateStore) {
1294  0 return (XWikiHibernateStore) store;
1295  11294 } else if (store instanceof XWikiCacheStoreInterface) {
1296  11295 store = ((XWikiCacheStoreInterface) store).getStore();
1297  11295 if (store instanceof XWikiHibernateStore) {
1298  11293 return (XWikiHibernateStore) store;
1299    } else {
1300  0 return null;
1301    }
1302    } else {
1303  0 return null;
1304    }
1305    }
1306   
1307    /**
1308    * @param wikiId the id of the wiki
1309    * @param context see {@link XWikiContext}
1310    * @deprecated since 8.4RC1, use {@link #initializeWiki(String, boolean, XWikiContext)} instead
1311    */
 
1312  0 toggle @Deprecated
1313    public void updateDatabase(String wikiId, XWikiContext context) throws HibernateException, XWikiException
1314    {
1315  0 updateDatabase(wikiId, false, context);
1316    }
1317   
1318    /**
1319    * @param wikiId the id of the wiki
1320    * @param context see {@link XWikiContext}
1321    * @deprecated since 8.4RC1, use {@link #initializeWiki(String, boolean, XWikiContext)} instead
1322    */
 
1323  0 toggle @Deprecated
1324    public void updateDatabase(String wikiId, boolean force, XWikiContext context)
1325    throws HibernateException, XWikiException
1326    {
1327  0 updateDatabase(wikiId, force, true, context);
1328    }
1329   
1330    /**
1331    * @param wikiId the id of the wiki
1332    * @param force if the update of the databse should be forced
1333    * @param initDocuments if mandatory document and plugin should be initialized for passed wiki
1334    * @param context see {@link XWikiContext}
1335    * @deprecated since 8.4RC1, use {@link #initializeWiki(String, boolean, XWikiContext)} instead
1336    */
 
1337  0 toggle @Deprecated
1338    public void updateDatabase(String wikiId, boolean force, boolean initDocuments, XWikiContext context)
1339    throws HibernateException, XWikiException
1340    {
1341  0 initializeWiki(wikiId, true, context);
1342    }
1343   
1344    /**
1345    * @return a cached list of all active virtual wikis (i.e. wikis who have been hit by a user request). To get a full
1346    * list of all virtual wikis database names use {@link WikiDescriptorManager#getAllIds()}.
1347    */
 
1348  0 toggle @Deprecated
1349    public List<String> getVirtualWikiList()
1350    {
1351  0 return new ArrayList<>(this.initializedWikis.keySet());
1352    }
1353   
1354    /**
1355    * @param context see {@link XWikiContext}
1356    * @return the full list of all wiki names of all defined wikis. The wiki names are computed from the names of
1357    * documents having a {@code XWiki.XWikiServerClass} object attached to them by removing the
1358    * {@code XWiki.XWikiServer} prefix and making it lower case. For example a page named
1359    * {@code XWiki.XWikiServerMyDatabase} would return {@code mydatabase} as the wiki name. This list will also
1360    * contain the main wiki.
1361    * <p>
1362    * Note: the wiki name is commonly also the name of the database where the wiki's data is stored. However,
1363    * if configured accordingly, the database can be diferent from the wiki name, like for example when setting
1364    * a wiki database prefix.
1365    * @deprecated since 5.3, use {@link WikiDescriptorManager#getAllIds()} instead
1366    */
 
1367  93 toggle @Deprecated
1368    public List<String> getVirtualWikisDatabaseNames(XWikiContext context) throws XWikiException
1369    {
1370  93 WikiDescriptorManager descriptorManager = Utils.getComponent(WikiDescriptorManager.class);
1371   
1372  93 try {
1373  93 return new ArrayList<String>(descriptorManager.getAllIds());
1374    } catch (WikiManagerException e) {
1375  0 throw new XWikiException(XWikiException.MODULE_XWIKI, XWikiException.ERROR_XWIKI_UNKNOWN,
1376    "Failed to get the list of wikis", e);
1377    }
1378    }
1379   
1380    /**
1381    * @return the cache containing the names of the wikis already initialized.
1382    * @since 1.5M2.
1383    */
 
1384  0 toggle @Deprecated
1385    public Cache<DocumentReference> getVirtualWikiCache()
1386    {
1387  0 return null;
1388    }
1389   
1390    /**
1391    * Get the reference of the owner for the provider wiki.
1392    *
1393    * @param wikiName the technical name of the wiki
1394    * @param context see {@link XWikiContext}
1395    * @return the wiki owner or null if none is set
1396    * @throws XWikiException failed to get wiki descriptor document
1397    */
 
1398  582 toggle public String getWikiOwner(String wikiName, XWikiContext context) throws XWikiException
1399    {
1400  582 String wikiOwner;
1401   
1402  582 String currentdatabase = context.getWikiId();
1403  582 try {
1404  582 context.setWikiId(context.getMainXWiki());
1405   
1406  582 String serverwikipage = getServerWikiPage(wikiName);
1407  582 XWikiDocument doc = getDocument(serverwikipage, context);
1408   
1409  582 if (doc.isNew()) {
1410  0 if (!context.isMainWiki(wikiName)) {
1411  0 throw new XWikiException(XWikiException.MODULE_XWIKI, XWikiException.ERROR_XWIKI_DOES_NOT_EXIST,
1412    "The wiki " + wikiName + " does not exist");
1413    } else {
1414  0 wikiOwner = null;
1415    }
1416    } else {
1417  582 wikiOwner = doc.getStringValue(VIRTUAL_WIKI_DEFINITION_CLASS_REFERENCE, "owner");
1418  580 if (wikiOwner.indexOf(':') == -1) {
1419  580 wikiOwner = context.getMainXWiki() + ":" + wikiOwner;
1420    }
1421    }
1422    } finally {
1423  582 context.setWikiId(currentdatabase);
1424    }
1425   
1426  582 return wikiOwner;
1427    }
1428   
1429    /**
1430    * @param context see {@link XWikiContext}
1431    */
 
1432  87 toggle protected Object createClassFromConfig(String param, String defClass, XWikiContext context) throws XWikiException
1433    {
1434  87 String storeclass = getConfiguration().getProperty(param, defClass);
1435  87 try {
1436  87 Class<?>[] classes = new Class<?>[] { XWikiContext.class };
1437  87 Object[] args = new Object[] { context };
1438  87 Object result = Class.forName(storeclass).getConstructor(classes).newInstance(args);
1439  87 return result;
1440    } catch (Exception e) {
1441  0 Throwable ecause = e;
1442  0 if (e instanceof InvocationTargetException) {
1443  0 ecause = ((InvocationTargetException) e).getTargetException();
1444    }
1445  0 Object[] args = { param, storeclass };
1446  0 throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
1447    XWikiException.ERROR_XWIKI_STORE_CLASSINVOCATIONERROR, "Cannot load class {1} from param {0}", ecause,
1448    args);
1449    }
1450    }
1451   
 
1452  87 toggle private void preparePlugins(XWikiContext context)
1453    {
1454  87 setPluginManager(new XWikiPluginManager(getXWikiPreference("plugins", context), context));
1455  87 String plugins = getConfiguration().getProperty("xwiki.plugins", "");
1456  87 if (!plugins.equals("")) {
1457  32 getPluginManager().addPlugins(StringUtils.split(plugins, " ,"), context);
1458    }
1459    }
1460   
1461    /**
1462    * @return the XWiki core version as specified in the {@link #VERSION_FILE} file
1463    */
 
1464  2772 toggle @SuppressWarnings("deprecation")
1465    public String getVersion()
1466    {
1467  2772 if (this.version == null) {
1468  30 try {
1469  30 InputStream is = getResourceAsStream(VERSION_FILE);
1470  30 try {
1471  30 XWikiConfig properties = new XWikiConfig(is);
1472  30 this.version = properties.getProperty(VERSION_FILE_PROPERTY);
1473    } finally {
1474  30 IOUtils.closeQuietly(is);
1475    }
1476    } catch (Exception e) {
1477    // Failed to retrieve the version, log a warning and default to "Unknown"
1478  0 LOGGER.warn("Failed to retrieve XWiki's version from [" + VERSION_FILE + "], using the ["
1479    + VERSION_FILE_PROPERTY + "] property.", e);
1480  0 this.version = "Unknown version";
1481    }
1482    }
1483  2768 return this.version;
1484    }
1485   
 
1486  30972 toggle public URL getResource(String s) throws MalformedURLException
1487    {
1488  30972 return getEngineContext().getResource(s);
1489    }
1490   
 
1491  9551 toggle public InputStream getResourceAsStream(String s) throws MalformedURLException
1492    {
1493  9550 InputStream is = getEngineContext().getResourceAsStream(s);
1494  9558 if (is == null) {
1495  8387 is = getEngineContext().getResourceAsStream("/" + s);
1496    }
1497  9558 return is;
1498    }
1499   
 
1500  0 toggle public String getResourceContent(String name) throws IOException
1501    {
1502  0 InputStream is = null;
1503  0 if (getEngineContext() != null) {
1504   
1505  0 try {
1506  0 is = getResourceAsStream(name);
1507    } catch (Exception e) {
1508    }
1509    }
1510   
1511  0 if (is == null) {
1512    // Resources should always be encoded as UTF-8, to reduce the dependency on the system encoding
1513  0 return FileUtils.readFileToString(new File(name), DEFAULT_ENCODING);
1514    }
1515   
1516  0 try {
1517  0 return IOUtils.toString(is, DEFAULT_ENCODING);
1518    } finally {
1519  0 IOUtils.closeQuietly(is);
1520    }
1521    }
1522   
 
1523  318 toggle public Date getResourceLastModificationDate(String name)
1524    {
1525  318 try {
1526  318 if (getEngineContext() != null) {
1527  318 return Util.getFileLastModificationDate(getEngineContext().getRealPath(name));
1528    }
1529    } catch (Exception ex) {
1530    // Probably a SecurityException or the file is not accessible (inside a war)
1531  0 LOGGER.info("Failed to get file modification date: " + ex.getMessage());
1532    }
1533  0 return new Date();
1534    }
1535   
 
1536  9494 toggle public byte[] getResourceContentAsBytes(String name) throws IOException
1537    {
1538  9494 InputStream is = null;
1539  9484 if (getEngineContext() != null) {
1540   
1541  9487 try {
1542  9486 is = getResourceAsStream(name);
1543    } catch (Exception e) {
1544    }
1545    }
1546   
1547  9500 if (is == null) {
1548  8387 return FileUtils.readFileToByteArray(new File(name));
1549    }
1550   
1551  1113 try {
1552  1113 return IOUtils.toByteArray(is);
1553    } finally {
1554  1112 IOUtils.closeQuietly(is);
1555    }
1556    }
1557   
 
1558  30973 toggle public boolean resourceExists(String name)
1559    {
1560  30971 if (getEngineContext() != null) {
1561  30972 try {
1562  30973 if (getResource(name) != null) {
1563  30972 return true;
1564    }
1565    } catch (IOException e) {
1566    }
1567    }
1568  1 try {
1569  1 File file = new File(name);
1570  1 return file.exists();
1571    } catch (Exception e) {
1572    // Could be running under -security, which prevents calling file.exists().
1573    }
1574  0 return false;
1575    }
1576   
 
1577  0 toggle public String getRealPath(String path)
1578    {
1579  0 return getEngineContext().getRealPath(path);
1580    }
1581   
 
1582  0 toggle public String ParamAsRealPath(String key)
1583    {
1584  0 String param = getConfiguration().getProperty(key);
1585  0 try {
1586  0 return getRealPath(param);
1587    } catch (Exception e) {
1588  0 return param;
1589    }
1590    }
1591   
1592    /**
1593    * @param context see {@link XWikiContext}
1594    */
 
1595  0 toggle public String ParamAsRealPath(String key, XWikiContext context)
1596    {
1597  0 return ParamAsRealPath(key);
1598    }
1599   
 
1600  0 toggle public String ParamAsRealPathVerified(String param)
1601    {
1602  0 String path;
1603  0 File fpath;
1604   
1605  0 path = getConfiguration().getProperty(param);
1606  0 if (path == null) {
1607  0 return null;
1608    }
1609   
1610  0 fpath = new File(path);
1611  0 if (fpath.exists()) {
1612  0 return path;
1613    }
1614   
1615  0 path = getRealPath(path);
1616  0 if (path == null) {
1617  0 return null;
1618    }
1619   
1620  0 fpath = new File(path);
1621  0 if (fpath.exists()) {
1622  0 return path;
1623    } else {
1624    }
1625  0 return null;
1626    }
1627   
 
1628  985334 toggle public XWikiStoreInterface getStore()
1629    {
1630  985319 return this.store;
1631    }
1632   
 
1633  726 toggle public XWikiAttachmentStoreInterface getAttachmentStore()
1634    {
1635  726 return this.attachmentStore;
1636    }
1637   
 
1638  903 toggle public AttachmentVersioningStore getAttachmentVersioningStore()
1639    {
1640  903 return this.attachmentVersioningStore;
1641    }
1642   
 
1643  11133 toggle public XWikiVersioningStoreInterface getVersioningStore()
1644    {
1645  11133 return this.versioningStore;
1646    }
1647   
 
1648  467 toggle public XWikiRecycleBinStoreInterface getRecycleBinStore()
1649    {
1650  468 return this.recycleBinStore;
1651    }
1652   
 
1653  5 toggle public AttachmentRecycleBinStore getAttachmentRecycleBinStore()
1654    {
1655  5 return this.attachmentRecycleBinStore;
1656    }
1657   
1658    /**
1659    * @param doc the document to save
1660    * @param context see {@link XWikiContext}
1661    */
 
1662  387 toggle public void saveDocument(XWikiDocument doc, XWikiContext context) throws XWikiException
1663    {
1664    // If no comment is provided we should use an empty comment
1665  387 saveDocument(doc, "", context);
1666    }
1667   
1668    /**
1669    * @param doc the document to save
1670    * @param comment the comment to associated to the new version of the saved document
1671    * @param context see {@link XWikiContext}
1672    */
 
1673  3564 toggle public void saveDocument(XWikiDocument doc, String comment, XWikiContext context) throws XWikiException
1674    {
1675  3564 saveDocument(doc, comment, false, context);
1676    }
1677   
1678    /**
1679    * @param document the document to save
1680    * @param comment the comment to associated to the new version of the saved document
1681    * @param isMinorEdit true if the new version is a minor version
1682    * @param context see {@link XWikiContext}
1683    */
 
1684  3900 toggle public void saveDocument(XWikiDocument document, String comment, boolean isMinorEdit, XWikiContext context)
1685    throws XWikiException
1686    {
1687  3900 String currentWiki = context.getWikiId();
1688   
1689  3900 try {
1690    // Switch to document wiki
1691  3900 context.setWikiId(document.getDocumentReference().getWikiReference().getName());
1692   
1693    // Setting comment & minor edit before saving
1694  3900 document.setComment(StringUtils.defaultString(comment));
1695  3900 document.setMinorEdit(isMinorEdit);
1696   
1697    // We need to save the original document since saveXWikiDoc() will reset it and we
1698    // need that original document for the notification below.
1699  3900 XWikiDocument originalDocument = document.getOriginalDocument();
1700   
1701    // Make sure to always have an original document for listeners that need to compare with it.
1702    // The only case where we have a null original document is supposedly when the document
1703    // instance has been crafted and passed #saveDocument without using #getDocument
1704    // (which is not a good practice)
1705  3900 if (originalDocument == null) {
1706  2190 originalDocument =
1707    getDocument(new DocumentReference(document.getDocumentReference(), document.getLocale()), context);
1708  2190 document.setOriginalDocument(originalDocument);
1709    }
1710   
1711  3900 ObservationManager om = getObservationManager();
1712   
1713    // Notify listeners about the document about to be created or updated
1714   
1715    // Note that for the moment the event being send is a bridge event, as we are still passing around
1716    // an XWikiDocument as source and an XWikiContext as data.
1717   
1718  3900 if (om != null) {
1719  3900 CancelableEvent documentEvent;
1720  3900 if (originalDocument.isNew()) {
1721  3472 documentEvent = new DocumentCreatingEvent(document.getDocumentReference());
1722    } else {
1723  428 documentEvent = new DocumentUpdatingEvent(document.getDocumentReference());
1724    }
1725  3900 om.notify(documentEvent, document, context);
1726   
1727    // If the action has been canceled by the user then don't perform any save and throw an exception
1728  3900 if (documentEvent.isCanceled()) {
1729  0 throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
1730    XWikiException.ERROR_XWIKI_STORE_HIBERNATE_SAVING_DOC,
1731    String.format("An Event Listener has cancelled the document save for [%s]. Reason: [%s]",
1732    document.getDocumentReference(), documentEvent.getReason()));
1733    }
1734    }
1735   
1736    // Put attachments to remove in recycle bin
1737  3900 if (hasAttachmentRecycleBin(context)) {
1738  3897 for (XWikiAttachmentToRemove attachment : document.getAttachmentsToRemove()) {
1739  5 if (attachment.isToRecycleBin()) {
1740  5 getAttachmentRecycleBinStore().saveToRecycleBin(attachment.getAttachment(), context.getUser(),
1741    new Date(), context, true);
1742    }
1743    }
1744    }
1745   
1746    // Actually save the document.
1747  3900 getStore().saveXWikiDoc(document, context);
1748   
1749    // Since the store#saveXWikiDoc resets originalDocument, we need to temporarily put it
1750    // back to send notifications.
1751  3900 XWikiDocument newOriginal = document.getOriginalDocument();
1752   
1753  3900 try {
1754  3900 document.setOriginalDocument(originalDocument);
1755   
1756    // Notify listeners about the document having been created or updated
1757   
1758    // First the legacy notification mechanism
1759   
1760    // Then the new observation module
1761    // Note that for the moment the event being send is a bridge event, as we are still passing around
1762    // an XWikiDocument as source and an XWikiContext as data.
1763    // The old version is made available using doc.getOriginalDocument()
1764   
1765  3900 if (om != null) {
1766  3900 if (originalDocument.isNew()) {
1767  3472 om.notify(new DocumentCreatedEvent(document.getDocumentReference()), document, context);
1768    } else {
1769  428 om.notify(new DocumentUpdatedEvent(document.getDocumentReference()), document, context);
1770    }
1771    }
1772    } catch (Exception ex) {
1773  0 LOGGER.error("Failed to send document save notification for document ["
1774    + getDefaultEntityReferenceSerializer().serialize(document.getDocumentReference()) + "]", ex);
1775    } finally {
1776  3900 document.setOriginalDocument(newOriginal);
1777    }
1778    } finally {
1779  3900 context.setWikiId(currentWiki);
1780    }
1781    }
1782   
1783    /**
1784    * Loads a XWikiDocument from the store.
1785    * <p>
1786    * Before 7.2M1 the reference is assumed to be a complete or incomplete document reference.
1787    * <p>
1788    * Since 7.2M1, the passed reference can be anything. If if a document child, the document reference will be
1789    * extracted from it. If it's a document parent it will be completed with the necessary default references (for
1790    * example if it's a space reference it will load the space home page).
1791    *
1792    * @param reference the reference of teh document
1793    * @param context see {@link XWikiContext}
1794    * @since 5.0M1
1795    */
 
1796  601 toggle public XWikiDocument getDocument(EntityReference reference, XWikiContext context) throws XWikiException
1797    {
1798  601 return getDocument(getCurrentGetDocumentResolver().resolve(reference), context);
1799    }
1800   
1801    /**
1802    * @param doc the document
1803    * @param context see {@link XWikiContext}
1804    */
 
1805  586150 toggle public XWikiDocument getDocument(XWikiDocument doc, XWikiContext context) throws XWikiException
1806    {
1807  586136 String currentWiki = context.getWikiId();
1808  586103 try {
1809  586122 context.setWikiId(doc.getDocumentReference().getWikiReference().getName());
1810   
1811  586148 return getStore().loadXWikiDoc(doc, context);
1812    } finally {
1813  586156 context.setWikiId(currentWiki);
1814    }
1815    }
1816   
1817    /**
1818    * @param doc the document
1819    * @param revision the version of the document
1820    * @param context see {@link XWikiContext}
1821    */
 
1822  46 toggle public XWikiDocument getDocument(XWikiDocument doc, String revision, XWikiContext context) throws XWikiException
1823    {
1824  46 XWikiDocument newdoc;
1825   
1826  46 String database = context.getWikiId();
1827  46 try {
1828  46 if (doc.getDocumentReference().getWikiReference().getName() != null) {
1829  46 context.setWikiId(doc.getDocumentReference().getWikiReference().getName());
1830    }
1831   
1832  46 if ((revision == null) || revision.equals("")) {
1833  0 newdoc = new XWikiDocument(doc.getDocumentReference());
1834  46 } else if (revision.equals(doc.getVersion())) {
1835  16 newdoc = doc;
1836    } else {
1837  30 newdoc = getVersioningStore().loadXWikiDoc(doc, revision, context);
1838    }
1839    } catch (XWikiException e) {
1840  2 if (revision.equals("1.1") || revision.equals("1.0")) {
1841  2 newdoc = new XWikiDocument(doc.getDocumentReference());
1842    } else {
1843  0 throw e;
1844    }
1845    } finally {
1846  46 context.setWikiId(database);
1847    }
1848   
1849  46 return newdoc;
1850    }
1851   
1852    /**
1853    * @param reference the reference of the document
1854    * @param context see {@link XWikiContext}
1855    * @since 2.2M1
1856    */
 
1857  566495 toggle public XWikiDocument getDocument(DocumentReference reference, XWikiContext context) throws XWikiException
1858    {
1859  566476 XWikiDocument doc = new XWikiDocument(
1860  566425 reference.getLocale() != null ? new DocumentReference(reference, null) : reference, reference.getLocale());
1861   
1862  566458 doc.setContentDirty(true);
1863   
1864  566450 return getDocument(doc, context);
1865    }
1866   
1867    /**
1868    * @param fullname the reference of the document as String
1869    * @param context see {@link XWikiContext}
1870    * @deprecated since 2.2M1 use {@link #getDocument(DocumentReference, XWikiContext)} instead
1871    */
 
1872  19682 toggle @Deprecated
1873    public XWikiDocument getDocument(String fullname, XWikiContext context) throws XWikiException
1874    {
1875  19677 XWikiDocument doc = new XWikiDocument();
1876  19679 doc.setFullName(fullname, context);
1877  19683 return getDocument(doc, context);
1878    }
1879   
1880    /**
1881    * @param spaces the reference of the space as String
1882    * @param fullname the reference of the document as String
1883    * @param context see {@link XWikiContext}
1884    * @deprecated since 2.2M1 use {@link #getDocument(DocumentReference, XWikiContext)} instead
1885    */
 
1886  0 toggle @Deprecated
1887    public XWikiDocument getDocument(String spaces, String fullname, XWikiContext context) throws XWikiException
1888    {
1889  0 int dotPosition = fullname.lastIndexOf('.');
1890  0 if (dotPosition != -1) {
1891  0 String spaceFromFullname = fullname.substring(0, dotPosition);
1892  0 String name = fullname.substring(dotPosition + 1);
1893  0 if (name.equals("")) {
1894  0 name = getDefaultPage(context);
1895    }
1896  0 return getDocument(spaceFromFullname + "." + name, context);
1897    } else {
1898  0 return getDocument(spaces + "." + fullname, context);
1899    }
1900    }
1901   
1902    /**
1903    * @see com.xpn.xwiki.api.XWiki#getDeletedDocuments(String, String)
1904    */
 
1905  304 toggle public XWikiDeletedDocument[] getDeletedDocuments(String fullname, String locale, XWikiContext context)
1906    throws XWikiException
1907    {
1908  303 if (hasRecycleBin(context)) {
1909  303 XWikiDocument doc = new XWikiDocument(getCurrentMixedDocumentReferenceResolver().resolve(fullname));
1910  304 doc.setLanguage(locale);
1911  304 return getRecycleBinStore().getAllDeletedDocuments(doc, context, true);
1912    } else {
1913  0 return null;
1914    }
1915    }
1916   
1917    /**
1918    * @see com.xpn.xwiki.api.XWiki#getDeletedDocument(String, String, String)
1919    */
 
1920  2 toggle public XWikiDeletedDocument getDeletedDocument(String fullname, String locale, int index, XWikiContext context)
1921    throws XWikiException
1922    {
1923  2 if (hasRecycleBin(context)) {
1924  2 XWikiDocument doc = new XWikiDocument(getCurrentMixedDocumentReferenceResolver().resolve(fullname));
1925  2 doc.setLanguage(locale);
1926  2 return getRecycleBinStore().getDeletedDocument(doc, index, context, true);
1927    } else {
1928  0 return null;
1929    }
1930    }
1931   
1932    /**
1933    * Retrieve all the deleted attachments that belonged to a certain document. Note that this does not distinguish
1934    * between different incarnations of a document name, and it does not require that the document still exists, it
1935    * returns all the attachments that at the time of their deletion had a document with the specified name as their
1936    * owner.
1937    *
1938    * @param docName the {@link XWikiDocument#getFullName() name} of the owner document
1939    * @param context see {@link XWikiContext}
1940    * @return A list with all the deleted attachments which belonged to the specified document. If no such attachments
1941    * are found in the trash, an empty list is returned.
1942    * @throws XWikiException if an error occurs while loading the attachments
1943    */
 
1944  0 toggle public List<DeletedAttachment> getDeletedAttachments(String docName, XWikiContext context) throws XWikiException
1945    {
1946  0 if (hasAttachmentRecycleBin(context)) {
1947  0 XWikiDocument doc = new XWikiDocument(getCurrentMixedDocumentReferenceResolver().resolve(docName));
1948  0 return getAttachmentRecycleBinStore().getAllDeletedAttachments(doc, context, true);
1949    }
1950  0 return null;
1951    }
1952   
1953    /**
1954    * Retrieve all the deleted attachments that belonged to a certain document and had the specified name. Multiple
1955    * versions can be returned since the same file can be uploaded and deleted several times, creating different
1956    * instances in the trash. Note that this does not distinguish between different incarnations of a document name,
1957    * and it does not require that the document still exists, it returns all the attachments that at the time of their
1958    * deletion had a document with the specified name as their owner.
1959    *
1960    * @param docName the {@link DeletedAttachment#getDocName() name of the document} the attachment belonged to
1961    * @param filename the {@link DeletedAttachment#getFilename() name} of the attachment to search for
1962    * @param context see {@link XWikiContext}
1963    * @return A list with all the deleted attachments which belonged to the specified document and had the specified
1964    * filename. If no such attachments are found in the trash, an empty list is returned.
1965    * @throws XWikiException if an error occurs while loading the attachments
1966    */
 
1967  0 toggle public List<DeletedAttachment> getDeletedAttachments(String docName, String filename, XWikiContext context)
1968    throws XWikiException
1969    {
1970  0 if (hasAttachmentRecycleBin(context)) {
1971  0 XWikiDocument doc = new XWikiDocument(getCurrentMixedDocumentReferenceResolver().resolve(docName));
1972  0 XWikiAttachment attachment = new XWikiAttachment(doc, filename);
1973  0 return getAttachmentRecycleBinStore().getAllDeletedAttachments(attachment, context, true);
1974    }
1975  0 return null;
1976    }
1977   
1978    /**
1979    * Retrieve a specific attachment from the trash.
1980    *
1981    * @param id the unique identifier of the entry in the trash
1982    * @param context the XWiki context
1983    * @return specified attachment from the trash, {@code null} if not found
1984    * @throws XWikiException if an error occurs while loading the attachments
1985    */
 
1986  0 toggle public DeletedAttachment getDeletedAttachment(String id, XWikiContext context) throws XWikiException
1987    {
1988  0 if (hasAttachmentRecycleBin(context)) {
1989  0 return getAttachmentRecycleBinStore().getDeletedAttachment(NumberUtils.toLong(id), context, true);
1990    }
1991  0 return null;
1992    }
1993   
 
1994  188 toggle public MetaClass getMetaclass()
1995    {
1996  188 if (this.metaclass == null) {
1997  2 this.metaclass = MetaClass.getMetaClass();
1998    }
1999  188 return this.metaclass;
2000    }
2001   
 
2002  0 toggle public void setMetaclass(MetaClass metaclass)
2003    {
2004  0 this.metaclass = metaclass;
2005    }
2006   
2007    /**
2008    * @param context see {@link XWikiContext}
2009    */
 
2010  28 toggle public List<String> getClassList(XWikiContext context) throws XWikiException
2011    {
2012  28 List<String> result = getStore().getClassList(context);
2013  28 Collections.sort(result);
2014  28 return result;
2015    }
2016   
2017    /**
2018    * @param sql the sql query to execute
2019    * @param context see {@link XWikiContext}
2020    */
 
2021  0 toggle public <T> List<T> search(String sql, XWikiContext context) throws XWikiException
2022    {
2023  0 return getStore().search(sql, 0, 0, context);
2024    }
2025   
2026    /**
2027    * @param sql the sql query to execute
2028    * @param nb limit the number of results to return
2029    * @param start the offset from which to start return results
2030    * @param context see {@link XWikiContext}
2031    */
 
2032  0 toggle public <T> List<T> search(String sql, int nb, int start, XWikiContext context) throws XWikiException
2033    {
2034  0 return getStore().search(sql, nb, start, context);
2035    }
2036   
2037    /**
2038    * @param sql the sql query to execute
2039    * @param context see {@link XWikiContext}
2040    */
 
2041  1 toggle public <T> List<T> search(String sql, Object[][] whereParams, XWikiContext context) throws XWikiException
2042    {
2043  1 return getStore().search(sql, 0, 0, whereParams, context);
2044    }
2045   
2046    /**
2047    * @param sql the sql query to execute
2048    * @param nb limit the number of results to return
2049    * @param start the offset from which to start return results
2050    * @param context see {@link XWikiContext}
2051    */
 
2052  0 toggle public <T> List<T> search(String sql, int nb, int start, Object[][] whereParams, XWikiContext context)
2053    throws XWikiException
2054    {
2055  0 return getStore().search(sql, nb, start, whereParams, context);
2056    }
2057   
2058    /**
2059    * @param content the content to parse
2060    * @param context see {@link XWikiContext}
2061    * @deprecated Since 7.2M1. Use specific rendering/parsing options for the content type you want to parse/render.
2062    */
 
2063  46 toggle @Deprecated
2064    public String parseContent(String content, XWikiContext context)
2065    {
2066  46 return getOldRendering().parseContent(content, context);
2067    }
2068   
2069    /**
2070    * @param template the name of the template
2071    * @param context see {@link XWikiContext}
2072    * @deprecated use {@link #evaluateTemplate(String, XWikiContext)} instead
2073    */
 
2074  71467 toggle @Deprecated
2075    public String parseTemplate(String template, XWikiContext context)
2076    {
2077  71467 String result = "";
2078   
2079  71459 try {
2080  71463 result = evaluateTemplate(template, context);
2081    } catch (Exception e) {
2082  0 LOGGER.debug("Exception while parsing template [{}] from /templates/", template, e);
2083    }
2084   
2085  71460 return result;
2086    }
2087   
2088    /**
2089    * Evaluate provided template content using velocity engine.
2090    *
2091    * @param template the template to evaluate
2092    * @param context see {@link XWikiContext}
2093    * @return the return of the velocity script
2094    * @throws IOException failed to get the template content
2095    * @since 2.2.2
2096    * @deprecated since 7.0M1, use {@link TemplateManager#render(String)} instead
2097    */
 
2098  78475 toggle @Deprecated
2099    public String evaluateTemplate(String template, XWikiContext context) throws IOException
2100    {
2101  78473 try {
2102  78471 return getTemplateManager().render(template);
2103    } catch (Exception e) {
2104  0 LOGGER.error("Error while evaluating velocity template [{}]", template, e);
2105   
2106  0 Object[] args = { template };
2107  0 XWikiException xe = new XWikiException(XWikiException.MODULE_XWIKI_RENDERING,
2108    XWikiException.ERROR_XWIKI_RENDERING_VELOCITY_EXCEPTION, "Error while evaluating velocity template {0}",
2109    e, args);
2110   
2111  0 return Util.getHTMLExceptionMessage(xe, context);
2112    }
2113    }
2114   
2115    /**
2116    * @param template the name of the template
2117    * @param skinId the id of the skin from which to load the template
2118    * @param context see {@link XWikiContext}
2119    * @deprecated since 7.0M1, use {@link TemplateManager#renderFromSkin(String, Skin)} instead
2120    */
 
2121  0 toggle @Deprecated
2122    public String parseTemplate(String template, String skinId, XWikiContext context)
2123    {
2124  0 MutableRenderingContext mutableRenderingContext = getMutableRenderingContext();
2125   
2126  0 Syntax currentTargetSyntax = mutableRenderingContext.getTargetSyntax();
2127  0 try {
2128    // Force rendering with XHTML 1.0 syntax for retro-compatibility
2129  0 mutableRenderingContext.setTargetSyntax(Syntax.XHTML_1_0);
2130   
2131  0 Skin skin = getInternalSkinManager().getSkin(skinId);
2132  0 return getTemplateManager().renderFromSkin(template, skin);
2133    } catch (Exception e) {
2134  0 LOGGER.error("Error while evaluating velocity template [{}] skin [{}]", template, skinId, e);
2135   
2136  0 Object[] args = { template, skinId };
2137  0 XWikiException xe = new XWikiException(XWikiException.MODULE_XWIKI_RENDERING,
2138    XWikiException.ERROR_XWIKI_RENDERING_VELOCITY_EXCEPTION,
2139    "Error while evaluating velocity template [{0}] from skin [{1}]", e, args);
2140   
2141  0 return Util.getHTMLExceptionMessage(xe, context);
2142    } finally {
2143  0 mutableRenderingContext.setTargetSyntax(currentTargetSyntax);
2144    }
2145    }
2146   
2147    /**
2148    * @param template the name of the template
2149    * @param skin the id of the skin from which to load the template
2150    * @param context see {@link XWikiContext}
2151    */
 
2152  0 toggle public String renderTemplate(String template, String skin, XWikiContext context)
2153    {
2154  0 try {
2155  0 return getOldRendering().renderTemplate(template, skin, context);
2156    } catch (Exception ex) {
2157  0 LOGGER.error("Failed to render template [" + template + "] for skin [" + skin + "]", ex);
2158  0 return parseTemplate(template, skin, context);
2159    }
2160    }
2161   
2162    /**
2163    * @param template the name of the template
2164    * @param context see {@link XWikiContext}
2165    */
 
2166  8 toggle public String renderTemplate(String template, XWikiContext context)
2167    {
2168  8 try {
2169  8 return getOldRendering().renderTemplate(template, context);
2170    } catch (Exception ex) {
2171  0 LOGGER.error("Failed to render template [" + template + "]", ex);
2172  0 return parseTemplate(template, context);
2173    }
2174    }
2175   
2176    /**
2177    * Designed to include dynamic content, such as Servlets or JSPs, inside Velocity templates; works by creating a
2178    * RequestDispatcher, buffering the output, then returning it as a string.
2179    */
 
2180  0 toggle public String invokeServletAndReturnAsString(String url, XWikiContext xwikiContext)
2181    {
2182   
2183  0 HttpServletRequest servletRequest = xwikiContext.getRequest();
2184  0 HttpServletResponse servletResponse = xwikiContext.getResponse();
2185   
2186  0 try {
2187  0 return IncludeServletAsString.invokeServletAndReturnAsString(url, servletRequest, servletResponse);
2188    } catch (Exception e) {
2189  0 LOGGER.warn("Exception including url: " + url, e);
2190  0 return "Exception including \"" + url + "\", see logs for details.";
2191    }
2192   
2193    }
2194   
2195    /**
2196    * @param iconName the standard name of an icon (it's not the name of the file on the filesystem, it's a generic
2197    * name, for example "success" for a success icon
2198    * @param context see {@link XWikiContext}
2199    * @return the URL to the icon resource
2200    * @since 2.6M1
2201    */
 
2202  19 toggle public String getIconURL(String iconName, XWikiContext context)
2203    {
2204    // TODO: Do a better mapping between generic icon name and physical resource name, especially to be independent
2205    // of the underlying icon library. Right now we assume it's the Silk icon library.
2206  19 return getSkinFile("icons/silk/" + iconName + ".png", context);
2207    }
2208   
 
2209  14444 toggle public String getSkinFile(String filename, XWikiContext context)
2210    {
2211  14444 return getSkinFile(filename, false, context);
2212    }
2213   
 
2214  36364 toggle public String getSkinFile(String filename, boolean forceSkinAction, XWikiContext context)
2215    {
2216  36362 XWikiURLFactory urlf = context.getURLFactory();
2217   
2218  36360 try {
2219    // Try in the specified skin
2220  36361 Skin skin = getInternalSkinManager().getCurrentSkin(true);
2221  36367 if (skin != null) {
2222  36367 Resource<?> resource = skin.getResource(filename);
2223  36367 if (resource != null) {
2224  5394 return resource.getURL(forceSkinAction);
2225    }
2226    } else {
2227    // Try in the current parent skin
2228  0 Skin parentSkin = getInternalSkinManager().getCurrentParentSkin(true);
2229  0 if (parentSkin != null) {
2230  0 Resource<?> resource = parentSkin.getResource(filename);
2231  0 if (resource != null) {
2232  0 return resource.getURL(forceSkinAction);
2233    }
2234    }
2235    }
2236   
2237    // Look for a resource file
2238  30973 if (resourceExists("/resources/" + filename)) {
2239  30972 URL url = urlf.createResourceURL(filename, forceSkinAction, context);
2240  30971 return urlf.getURL(url, context);
2241    }
2242    } catch (Exception e) {
2243  0 if (LOGGER.isDebugEnabled()) {
2244  0 LOGGER.debug("Exception while getting skin file [" + filename + "]", e);
2245    }
2246    }
2247   
2248    // If all else fails, use the default base skin, even if the URLs could be invalid.
2249  1 URL url;
2250  1 if (forceSkinAction) {
2251  1 url = urlf.createSkinURL(filename, "skins", getDefaultBaseSkin(context), context);
2252    } else {
2253  0 url = urlf.createSkinURL(filename, getDefaultBaseSkin(context), context);
2254    }
2255  1 return urlf.getURL(url, context);
2256    }
2257   
 
2258  0 toggle public String getSkinFile(String filename, String skin, XWikiContext context)
2259    {
2260  0 return getSkinFile(filename, skin, false, context);
2261    }
2262   
 
2263  0 toggle public String getSkinFile(String filename, String skinId, boolean forceSkinAction, XWikiContext context)
2264    {
2265  0 try {
2266  0 Skin skin = getInternalSkinManager().getSkin(skinId);
2267   
2268  0 Resource<?> resource = skin.getLocalResource(filename);
2269   
2270  0 if (resource != null) {
2271  0 return resource.getURL(forceSkinAction);
2272    }
2273   
2274    // Look for a resource file
2275  0 if (resourceExists("/resources/" + filename)) {
2276  0 XWikiURLFactory urlf = context.getURLFactory();
2277   
2278  0 URL url = urlf.createResourceURL(filename, forceSkinAction, context);
2279  0 return urlf.getURL(url, context);
2280    }
2281    } catch (Exception e) {
2282  0 if (LOGGER.isDebugEnabled()) {
2283  0 LOGGER.debug("Exception while getting skin file [{}] from skin [{}]", filename, skinId, e);
2284    }
2285    }
2286   
2287  0 return null;
2288    }
2289   
2290    /**
2291    * @deprecated since 7.0M1, use {@link SkinManager#getCurrentSkin(boolean)} instead
2292    */
 
2293  11169 toggle @Deprecated
2294    public String getSkin(XWikiContext context)
2295    {
2296  11168 String skin;
2297   
2298  11168 try {
2299  11167 skin = getInternalSkinManager().getCurrentSkinId(true);
2300    } catch (Exception e) {
2301  0 LOGGER.debug("Exception while determining current skin", e);
2302  0 skin = getDefaultBaseSkin(context);
2303    }
2304   
2305  11167 return skin;
2306    }
2307   
 
2308  0 toggle public String getSkinPreference(String prefname, XWikiContext context)
2309    {
2310  0 return getSkinPreference(prefname, "", context);
2311    }
2312   
 
2313  1063 toggle public String getSkinPreference(String prefname, String defaultValue, XWikiContext context)
2314    {
2315  3189 for (Skin skin = getInternalSkinManager().getCurrentSkin(true); skin != null; skin = skin.getParent()) {
2316  2126 if (skin instanceof WikiSkin) {
2317  0 String value = getWikiSkinUtils().getSkinProperty(skin.getId(), prefname);
2318   
2319    // TODO: remove the NO_VALUE test when XWIKI-10853 is fixed
2320  0 if (!StringUtils.isEmpty(value) && !NO_VALUE.equals(value)) {
2321  0 return value;
2322    }
2323    }
2324    }
2325   
2326  1062 return defaultValue;
2327    }
2328   
2329    /**
2330    * @deprecated since 7.0M1, use {@link SkinManager#getDefaultParentSkin()} instead
2331    */
 
2332  1115 toggle @Deprecated
2333    public String getDefaultBaseSkin(XWikiContext context)
2334    {
2335  1115 return getInternalSkinManager().getDefaultParentSkinId();
2336    }
2337   
2338    /**
2339    * @deprecated since 7.0M1
2340    */
 
2341  0 toggle @Deprecated
2342    public String getBaseSkin(XWikiContext context)
2343    {
2344  0 return getBaseSkin(context, false);
2345    }
2346   
2347    /**
2348    * @deprecated since 7.0M1
2349    */
 
2350  1113 toggle @Deprecated
2351    public String getBaseSkin(XWikiContext context, boolean fromRenderSkin)
2352    {
2353  1113 String baseskin = "";
2354  1107 try {
2355  1110 return getInternalSkinManager().getCurrentParentSkinId(false);
2356    } catch (Exception e) {
2357  0 baseskin = getDefaultBaseSkin(context);
2358   
2359  0 LOGGER.debug("Exception while determining base skin", e);
2360    }
2361   
2362  0 return baseskin;
2363    }
2364   
2365    /**
2366    * @param skin the name of the skin for which to return the base skin. For example : <tt>XWiki.DefaultSkin</tt>
2367    * @param context see {@link XWikiContext}
2368    * @return if found, the name of the base skin the asked skin inherits from. If not found, returns an empty string.
2369    * @since 2.0.2
2370    * @since 2.1M1
2371    * @deprecated since 7.0M1, use {@link SkinManager#getCurrentSkin(boolean)} and {@link Skin#getParent()} instead
2372    */
 
2373  0 toggle @Deprecated
2374    public String getBaseSkin(String skin, XWikiContext context)
2375    {
2376  0 String baseSkin = getInternalSkinManager().getParentSkin(skin);
2377   
2378  0 return baseSkin != null ? baseSkin : "";
2379    }
2380   
 
2381  6824 toggle public String getSpaceCopyright(XWikiContext context)
2382    {
2383  6827 return getSpacePreference("webcopyright", "", context);
2384    }
2385   
 
2386  44330 toggle public String getXWikiPreference(String prefname, XWikiContext context)
2387    {
2388  44329 return getXWikiPreference(prefname, "", context);
2389    }
2390   
2391    /**
2392    * Obtain a preference value for the wiki, looking up first in the XWiki.XWikiPreferences document, then fallbacking
2393    * on a config parameter when the first lookup gives an empty string, then returning the default value if the config
2394    * parameter returned itself an empty string.
2395    *
2396    * @param prefname the parameter to look for in the XWiki.XWikiPreferences object in the XWiki.XWikiPreferences
2397    * document of the wiki.
2398    * @param fallbackParam the parameter in xwiki.cfg to fallback on, in case the XWiki.XWikiPreferences object gave no
2399    * result
2400    * @param defaultValue the default value to fallback on, in case both XWiki.XWikiPreferences and the fallback
2401    * xwiki.cfg parameter gave no result
2402    */
 
2403  467122 toggle public String getXWikiPreference(String prefname, String fallbackParam, String defaultValue, XWikiContext context)
2404    {
2405  467107 String result = getWikiConfiguration().getProperty(prefname, String.class);
2406   
2407  467141 if (StringUtils.isEmpty(result)) {
2408  467104 result = getConfiguration().getProperty(fallbackParam, defaultValue);
2409    }
2410   
2411  467182 return result != null ? result : "";
2412    }
2413   
2414    /**
2415    * Obtain a preference value for the wiki, looking up first in the XWiki.XWikiPreferences document, then fallbacking
2416    * on a config parameter when the first lookup gives an empty string, then returning the default value if the config
2417    * parameter returned itself an empty string.
2418    *
2419    * @param prefname the parameter to look for in the XWiki.XWikiPreferences object in the XWiki.XWikiPreferences
2420    * document of the wiki.
2421    * @param wiki the wiki to get preference from
2422    * @param fallbackParam the parameter in xwiki.cfg to fallback on, in case the XWiki.XWikiPreferences object gave no
2423    * result
2424    * @param defaultValue the default value to fallback on, in case both XWiki.XWikiPreferences and the fallback
2425    * xwiki.cfg parameter gave no result
2426    * @since 7.4M1
2427    */
 
2428  0 toggle public String getXWikiPreference(String prefname, String wiki, String fallbackParam, String defaultValue,
2429    XWikiContext xcontext)
2430    {
2431  0 String currentWiki = xcontext.getWikiId();
2432   
2433  0 try {
2434  0 xcontext.setWikiId(wiki);
2435   
2436  0 return getXWikiPreference(prefname, fallbackParam, defaultValue, xcontext);
2437    } finally {
2438  0 xcontext.setWikiId(currentWiki);
2439    }
2440    }
2441   
 
2442  401603 toggle public String getXWikiPreference(String prefname, String defaultValue, XWikiContext context)
2443    {
2444  401590 return getXWikiPreference(prefname, "", defaultValue, context);
2445    }
2446   
 
2447  53345 toggle public String getSpacePreference(String preference, XWikiContext context)
2448    {
2449  53345 return getSpacePreference(preference, "", context);
2450    }
2451   
 
2452  66593 toggle public String getSpacePreference(String preference, String defaultValue, XWikiContext context)
2453    {
2454  66590 return getSpacePreference(preference, (SpaceReference) null, defaultValue, context);
2455    }
2456   
2457    /**
2458    * @deprecated since 7.4M1, use {@link #getSpacePreference(String, SpaceReference, String, XWikiContext)} instead
2459    */
 
2460  0 toggle @Deprecated
2461    public String getSpacePreference(String preference, String space, String defaultValue, XWikiContext context)
2462    {
2463  0 return getSpacePreference(preference, new SpaceReference(space, context.getWikiReference()), defaultValue,
2464    context);
2465    }
2466   
2467    /**
2468    * Get the reference of the space and fallback on parent space or wiki in case nothing is found.
2469    * <p>
2470    * If the property is not set on any level then empty String is returned.
2471    *
2472    * @param preferenceKey the name of the preference key
2473    * @param spaceReference the reference of the space
2474    * @param context see {@link XWikiContext}
2475    * @return the value of the preference or empty String if it could not be found
2476    * @since 7.4M1
2477    */
 
2478  10 toggle public String getSpacePreference(String preferenceKey, SpaceReference spaceReference, XWikiContext context)
2479    {
2480  10 return getSpacePreference(preferenceKey, spaceReference, "", context);
2481    }
2482   
2483    /**
2484    * Get the reference of the space and fallback on parent space or wiki in case nothing is found.
2485    * <p>
2486    * If the property is not set on any level then <code>defaultValue</code> is returned.
2487    *
2488    * @param preferenceKey the name of the preference key
2489    * @param spaceReference the reference of the space
2490    * @param defaultValue the value to return if the preference can't be found
2491    * @param context see {@link XWikiContext}
2492    * @return the value of the preference or <code>defaultValue</code> if it could not be found
2493    * @since 7.4M1
2494    */
 
2495  76023 toggle public String getSpacePreference(String preferenceKey, SpaceReference spaceReference, String defaultValue,
2496    XWikiContext context)
2497    {
2498  76024 XWikiDocument currentDocument = context.getDoc();
2499   
2500  76036 try {
2501  76029 if (spaceReference != null) {
2502  9436 context.setDoc(new XWikiDocument(new DocumentReference("WebPreferences", spaceReference)));
2503  66596 } else if (currentDocument != null) {
2504  65496 spaceReference = currentDocument.getDocumentReference().getLastSpaceReference();
2505    }
2506   
2507  76030 String result = getSpaceConfiguration().getProperty(preferenceKey, String.class);
2508   
2509  76030 if (StringUtils.isEmpty(result)) {
2510  75961 if (spaceReference == null) {
2511  1094 result = getXWikiPreference(preferenceKey, defaultValue, context);
2512  74869 } else if (spaceReference.getParent() instanceof SpaceReference) {
2513  9420 result = getSpacePreference(preferenceKey, (SpaceReference) spaceReference.getParent(),
2514    defaultValue, context);
2515  65448 } else if (spaceReference.getParent() instanceof WikiReference) {
2516  65449 result =
2517    getXWikiPreference(preferenceKey, spaceReference.getParent().getName(), defaultValue, context);
2518    }
2519    }
2520   
2521  76034 return result != null ? result : defaultValue;
2522    } finally {
2523  76033 context.setDoc(currentDocument);
2524    }
2525    }
2526   
 
2527  7929 toggle public String getUserPreference(String prefname, XWikiContext context)
2528    {
2529  7928 String result = getUserConfiguration().getProperty(prefname, String.class);
2530   
2531  7931 if (StringUtils.isEmpty(result)) {
2532  7925 result = getSpacePreference(prefname, context);
2533    }
2534   
2535  7931 return result != null ? result : "";
2536    }
2537   
 
2538  1 toggle public String getUserPreferenceFromCookie(String prefname, XWikiContext context)
2539    {
2540  1 Cookie[] cookies = context.getRequest().getCookies();
2541  1 if (cookies == null) {
2542  0 return null;
2543    }
2544  1 for (Cookie cookie : cookies) {
2545  0 String name = cookie.getName();
2546  0 if (name.equals(prefname)) {
2547  0 String value = cookie.getValue();
2548  0 if (!value.trim().equals("")) {
2549  0 return value;
2550    } else {
2551  0 break;
2552    }
2553    }
2554    }
2555  1 return null;
2556    }
2557   
 
2558  0 toggle public String getUserPreference(String prefname, boolean useCookie, XWikiContext context)
2559    {
2560    // First we look in the cookies
2561  0 if (useCookie) {
2562  0 String result = Util.normalizeLanguage(getUserPreferenceFromCookie(prefname, context));
2563  0 if (result != null) {
2564  0 return result;
2565    }
2566    }
2567  0 return getUserPreference(prefname, context);
2568    }
2569   
2570    /**
2571    * First try to find the current locale in use from the XWiki context. If none is used and if the wiki is not
2572    * multilingual use the default locale defined in the XWiki preferences. If the wiki is multilingual try to get the
2573    * locale passed in the request. If none was passed try to get it from a cookie. If no locale cookie exists then use
2574    * the user default locale and barring that use the browser's "Accept-Language" header sent in HTTP request. If none
2575    * is defined use the default locale.
2576    *
2577    * @return the locale to use
2578    * @since 8.0M1
2579    */
 
2580  11331 toggle public Locale getLocalePreference(XWikiContext context)
2581    {
2582  11335 String language = getLanguagePreference(context);
2583   
2584  11333 return LocaleUtils.toLocale(language);
2585    }
2586   
2587    /**
2588    * First try to find the current locale in use from the XWiki context. If none is used and if the wiki is not
2589    * multilingual use the default locale defined in the XWiki preferences. If the wiki is multilingual try to get the
2590    * locale passed in the request. If none was passed try to get it from a cookie. If no locale cookie exists then use
2591    * the user default locale and barring that use the browser's "Accept-Language" header sent in HTTP request. If none
2592    * is defined use the default locale.
2593    *
2594    * @return the locale to use
2595    * @deprecated since 8.0M1, use {@link #getLocalePreference(XWikiContext)} instead
2596    */
 
2597  157386 toggle @Deprecated
2598    // TODO: move implementation to #getLocalePreference
2599    public String getLanguagePreference(XWikiContext context)
2600    {
2601    // First we try to get the language from the XWiki Context. This is the current language
2602    // being used.
2603  157401 String language = context.getLanguage();
2604  157384 if (language != null) {
2605  144054 return language;
2606    }
2607   
2608  13333 String defaultLanguage = getDefaultLanguage(context);
2609   
2610    // If the wiki is non multilingual then the language is the default language.
2611  13373 if (!context.getWiki().isMultiLingual(context)) {
2612  13368 language = defaultLanguage;
2613  13368 context.setLanguage(language);
2614  13364 return language;
2615    }
2616   
2617    // As the wiki is multilingual try to find the language to use from the request by looking
2618    // for a language parameter. If the language value is "default" use the default language
2619    // from the XWiki preferences settings. Otherwise set a cookie to remember the language
2620    // in use.
2621  1 try {
2622  1 language = Util.normalizeLanguage(context.getRequest().getParameter("language"));
2623  1 if ((language != null) && (!language.equals(""))) {
2624  0 if (language.equals("default")) {
2625    // forgetting language cookie
2626  0 Cookie cookie = new Cookie("language", "");
2627  0 cookie.setMaxAge(0);
2628  0 cookie.setPath("/");
2629  0 context.getResponse().addCookie(cookie);
2630  0 language = defaultLanguage;
2631    } else {
2632    // setting language cookie
2633  0 Cookie cookie = new Cookie("language", language);
2634  0 cookie.setMaxAge(60 * 60 * 24 * 365 * 10);
2635  0 cookie.setPath("/");
2636  0 context.getResponse().addCookie(cookie);
2637    }
2638  0 context.setLanguage(language);
2639  0 return language;
2640    }
2641    } catch (Exception e) {
2642    }
2643   
2644    // As no language parameter was passed in the request, try to get the language to use
2645    // from a cookie.
2646  1 try {
2647    // First we get the language from the cookie
2648  1 language = Util.normalizeLanguage(getUserPreferenceFromCookie("language", context));
2649  1 if ((language != null) && (!language.equals(""))) {
2650  0 context.setLanguage(language);
2651  0 return language;
2652    }
2653    } catch (Exception e) {
2654    }
2655   
2656    // Next from the default user preference
2657  1 try {
2658  1 String user = context.getUser();
2659  1 XWikiDocument userdoc = null;
2660  1 userdoc = getDocument(user, context);
2661  1 if (userdoc != null) {
2662  1 language = Util.normalizeLanguage(userdoc.getStringValue("XWiki.XWikiUsers", "default_language"));
2663  1 if (!language.equals("")) {
2664  0 context.setLanguage(language);
2665  0 return language;
2666    }
2667    }
2668    } catch (XWikiException e) {
2669    }
2670   
2671    // If the default language is preferred, and since the user didn't explicitly ask for a
2672    // language already, then use the default wiki language.
2673  1 if (getConfiguration().getProperty("xwiki.language.preferDefault", "0").equals("1")
2674    || getSpacePreference("preferDefaultLanguage", "0", context).equals("1")) {
2675  0 language = defaultLanguage;
2676  0 context.setLanguage(language);
2677  0 return language;
2678    }
2679   
2680    // Then from the navigator language setting
2681  1 if (context.getRequest() != null) {
2682  1 String acceptHeader = context.getRequest().getHeader("Accept-Language");
2683    // If the client didn't specify some languages, skip this phase
2684  1 if ((acceptHeader != null) && (!acceptHeader.equals(""))) {
2685  1 List<String> acceptedLanguages = getAcceptedLanguages(context.getRequest());
2686    // We can force one of the configured languages to be accepted
2687  1 if (getConfiguration().getProperty("xwiki.language.forceSupported", "0").equals("1")) {
2688  0 List<String> available = Arrays.asList(getXWikiPreference("languages", context).split("[, |]"));
2689    // Filter only configured languages
2690  0 acceptedLanguages.retainAll(available);
2691    }
2692  1 if (acceptedLanguages.size() > 0) {
2693    // Use the "most-preferred" language, as requested by the client.
2694  1 context.setLanguage(acceptedLanguages.get(0));
2695  1 return acceptedLanguages.get(0);
2696    }
2697    // If none of the languages requested by the client is acceptable, skip to next
2698    // phase (use default language).
2699    }
2700    }
2701   
2702    // Finally, use the default language from the global preferences.
2703  0 context.setLanguage(defaultLanguage);
2704  0 return defaultLanguage;
2705    }
2706   
2707    /**
2708    * Construct a list of language codes (ISO 639-1) from the Accept-Languages header. This method filters out some
2709    * bugs in different browsers or containers, like returning '*' as a language (Jetty) or using '_' as a
2710    * language--country delimiter (some versions of Opera).
2711    *
2712    * @param request The client request.
2713    * @return A list of language codes, in the client preference order; might be empty if the header is not well
2714    * formed.
2715    */
 
2716  1 toggle private List<String> getAcceptedLanguages(XWikiRequest request)
2717    {
2718  1 List<String> result = new ArrayList<String>();
2719  1 Enumeration<Locale> e = request.getLocales();
2720  5 while (e.hasMoreElements()) {
2721  4 String language = e.nextElement().getLanguage().toLowerCase();
2722    // All language codes should have 2 letters.
2723  4 if (StringUtils.isAlpha(language)) {
2724  2 result.add(language);
2725    }
2726    }
2727  1 return result;
2728    }
2729   
2730    /**
2731    * @deprecated since 5.1M2 use {@link #getDefaultLocale(XWikiContext)} instead
2732    */
 
2733  13338 toggle @Deprecated
2734    public String getDefaultLanguage(XWikiContext xcontext)
2735    {
2736  13327 return getDefaultLocale(xcontext).toString();
2737    }
2738   
2739    /**
2740    * The default locale in the preferences.
2741    *
2742    * @param xcontext the XWiki context.
2743    * @return the default locale
2744    * @since 5.1M2
2745    */
 
2746  17558 toggle public Locale getDefaultLocale(XWikiContext xcontext)
2747    {
2748    // Find out what is the default language from the XWiki preferences settings.
2749  17570 String defaultLanguage = xcontext.getWiki().getXWikiPreference("default_language", "", xcontext);
2750   
2751  17641 Locale defaultLocale;
2752   
2753  17624 if (StringUtils.isBlank(defaultLanguage)) {
2754  17619 defaultLocale = Locale.ENGLISH;
2755    } else {
2756  0 try {
2757  0 defaultLocale = LocaleUtils.toLocale(Util.normalizeLanguage(defaultLanguage));
2758    } catch (Exception e) {
2759  0 LOGGER.warn("Invalid locale [{}] set as default locale in the preferences", defaultLanguage);
2760  0 defaultLocale = Locale.ENGLISH;
2761    }
2762    }
2763   
2764  17629 return defaultLocale;
2765    }
2766   
2767    /**
2768    * Get the available locales according to the preferences.
2769    *
2770    * @param xcontext the XWiki context
2771    * @return all the available locales
2772    * @since 5.1M2
2773    */
 
2774  4158 toggle public List<Locale> getAvailableLocales(XWikiContext xcontext)
2775    {
2776  4158 String[] languages = StringUtils.split(xcontext.getWiki().getXWikiPreference("languages", xcontext), ", |");
2777   
2778  4158 List<Locale> locales = new ArrayList<Locale>(languages.length);
2779   
2780  4158 for (String language : languages) {
2781  0 if (StringUtils.isNotBlank(language)) {
2782  0 try {
2783  0 locales.add(LocaleUtils.toLocale(language));
2784    } catch (Exception e) {
2785  0 LOGGER.warn("Invalid locale [{}] listed as available in the preferences", language);
2786    }
2787    }
2788    }
2789   
2790    // Add default language in case it's not listed as available (which is wrong but it happen)
2791  4158 Locale defaultocale = getDefaultLocale(xcontext);
2792  4158 if (!locales.contains(defaultocale)) {
2793  4158 locales.add(defaultocale);
2794    }
2795   
2796  4158 return locales;
2797    }
2798   
2799    /**
2800    * @since 8.0M1
2801    */
 
2802  0 toggle public Locale getDocLocalePreferenceNew(XWikiContext context)
2803    {
2804  0 String language = getDocLanguagePreferenceNew(context);
2805   
2806  0 return LocaleUtils.toLocale(language);
2807    }
2808   
2809    /**
2810    * @deprecated since 8.0M1, use {@link #getDocLocalePreferenceNew(XWikiContext)} instead
2811    */
 
2812  0 toggle @Deprecated
2813    // TODO: move implementation to #getDocLocalePreferenceNew
2814    public String getDocLanguagePreferenceNew(XWikiContext context)
2815    {
2816    // Get context language
2817  0 String contextLanguage = context.getLanguage();
2818    // If the language exists in the context, it was previously set by another call
2819  0 if (contextLanguage != null && contextLanguage != "") {
2820  0 return contextLanguage;
2821    }
2822   
2823  0 String language = "", requestLanguage = "", userPreferenceLanguage = "", navigatorLanguage = "",
2824    cookieLanguage = "";
2825  0 boolean setCookie = false;
2826   
2827  0 if (!context.getWiki().isMultiLingual(context)) {
2828  0 language = context.getWiki().getXWikiPreference("default_language", "", context);
2829  0 context.setLanguage(language);
2830  0 return language;
2831    }
2832   
2833    // Get request language
2834  0 try {
2835  0 requestLanguage = Util.normalizeLanguage(context.getRequest().getParameter("language"));
2836    } catch (Exception ex) {
2837    }
2838   
2839    // Get user preference
2840  0 try {
2841  0 String user = context.getUser();
2842  0 XWikiDocument userdoc = getDocument(user, context);
2843  0 if (userdoc != null) {
2844  0 userPreferenceLanguage = userdoc.getStringValue("XWiki.XWikiUsers", "default_language");
2845    }
2846    } catch (XWikiException e) {
2847    }
2848   
2849    // Get navigator language setting
2850  0 if (context.getRequest() != null) {
2851  0 String accept = context.getRequest().getHeader("Accept-Language");
2852  0 if ((accept != null) && (!accept.equals(""))) {
2853  0 String[] alist = StringUtils.split(accept, ",;-");
2854  0 if ((alist != null) && !(alist.length == 0)) {
2855  0 context.setLanguage(alist[0]);
2856  0 navigatorLanguage = alist[0];
2857    }
2858    }
2859    }
2860   
2861    // Get language from cookie
2862  0 try {
2863  0 cookieLanguage = Util.normalizeLanguage(getUserPreferenceFromCookie("language", context));
2864    } catch (Exception e) {
2865    }
2866   
2867    // Determine which language to use
2868    // First we get the language from the request
2869  0 if (StringUtils.isNotEmpty(requestLanguage)) {
2870  0 if (requestLanguage.equals("default")) {
2871  0 setCookie = true;
2872    } else {
2873  0 language = requestLanguage;
2874  0 context.setLanguage(language);
2875  0 Cookie cookie = new Cookie("language", language);
2876  0 cookie.setMaxAge(60 * 60 * 24 * 365 * 10);
2877  0 cookie.setPath("/");
2878  0 context.getResponse().addCookie(cookie);
2879  0 return language;
2880    }
2881    }
2882    // Next we get the language from the cookie
2883  0 if (StringUtils.isNotEmpty(cookieLanguage)) {
2884  0 language = cookieLanguage;
2885    }
2886    // Next from the default user preference
2887  0 else if (StringUtils.isNotEmpty(userPreferenceLanguage)) {
2888  0 language = userPreferenceLanguage;
2889    }
2890    // Then from the navigator language setting
2891  0 else if (StringUtils.isNotEmpty(navigatorLanguage)) {
2892  0 language = navigatorLanguage;
2893    }
2894  0 context.setLanguage(language);
2895  0 if (setCookie) {
2896  0 Cookie cookie = new Cookie("language", language);
2897  0 cookie.setMaxAge(60 * 60 * 24 * 365 * 10);
2898  0 cookie.setPath("/");
2899  0 context.getResponse().addCookie(cookie);
2900    }
2901  0 return language;
2902    }
2903   
2904    /**
2905    * @since 8.0M1
2906    */
 
2907  0 toggle public Locale getInterfaceLocalePreference(XWikiContext context)
2908    {
2909  0 String language = getInterfaceLanguagePreference(context);
2910   
2911  0 return LocaleUtils.toLocale(language);
2912    }
2913   
2914    /**
2915    * @deprecated since 8.0M1, use {@link #getInterfaceLocalePreference(XWikiContext)} instead
2916    */
 
2917  0 toggle @Deprecated
2918    // TODO: move implementation to #getInterfaceLocalePreference
2919    public String getInterfaceLanguagePreference(XWikiContext context)
2920    {
2921  0 String language = "", requestLanguage = "", userPreferenceLanguage = "", navigatorLanguage = "",
2922    cookieLanguage = "", contextLanguage = "";
2923  0 boolean setCookie = false;
2924   
2925  0 if (!context.getWiki().isMultiLingual(context)) {
2926  0 language = Util.normalizeLanguage(context.getWiki().getXWikiPreference("default_language", "", context));
2927  0 context.setInterfaceLanguage(language);
2928  0 return language;
2929    }
2930   
2931    // Get request language
2932  0 try {
2933  0 requestLanguage = Util.normalizeLanguage(context.getRequest().getParameter("interfacelanguage"));
2934    } catch (Exception ex) {
2935    }
2936   
2937    // Get context language
2938  0 contextLanguage = context.getInterfaceLanguage();
2939   
2940    // Get user preference
2941  0 try {
2942  0 String user = context.getUser();
2943  0 XWikiDocument userdoc = null;
2944  0 userdoc = getDocument(user, context);
2945  0 if (userdoc != null) {
2946  0 userPreferenceLanguage = userdoc.getStringValue("XWiki.XWikiUsers", "default_interface_language");
2947    }
2948    } catch (XWikiException e) {
2949    }
2950   
2951    // Get navigator language setting
2952  0 if (context.getRequest() != null) {
2953  0 String accept = context.getRequest().getHeader("Accept-Language");
2954  0 if ((accept != null) && (!accept.equals(""))) {
2955  0 String[] alist = StringUtils.split(accept, ",;-");
2956  0 if ((alist != null) && !(alist.length == 0)) {
2957  0 context.setLanguage(alist[0]);
2958  0 navigatorLanguage = alist[0];
2959    }
2960    }
2961    }
2962   
2963    // Get language from cookie
2964  0 try {
2965  0 cookieLanguage = Util.normalizeLanguage(getUserPreferenceFromCookie("interfacelanguage", context));
2966    } catch (Exception e) {
2967    }
2968   
2969    // Determine which language to use
2970    // First we get the language from the request
2971  0 if ((requestLanguage != null) && (!requestLanguage.equals(""))) {
2972  0 if (requestLanguage.equals("default")) {
2973  0 setCookie = true;
2974    } else {
2975  0 language = requestLanguage;
2976  0 context.setLanguage(language);
2977  0 Cookie cookie = new Cookie("interfacelanguage", language);
2978  0 cookie.setMaxAge(60 * 60 * 24 * 365 * 10);
2979  0 cookie.setPath("/");
2980  0 context.getResponse().addCookie(cookie);
2981  0 return language;
2982    }
2983    }
2984    // Next we get the language from the context
2985  0 if (contextLanguage != null && contextLanguage != "") {
2986  0 language = contextLanguage;
2987    }
2988    // Next we get the language from the cookie
2989  0 else if (StringUtils.isNotEmpty(cookieLanguage)) {
2990  0 language = cookieLanguage;
2991    }
2992    // Next from the default user preference
2993  0 else if (StringUtils.isNotEmpty(userPreferenceLanguage)) {
2994  0 language = userPreferenceLanguage;
2995    }
2996    // Then from the navigator language setting
2997  0 else if (StringUtils.isNotEmpty(navigatorLanguage)) {
2998  0 language = navigatorLanguage;
2999    }
3000  0 context.setLanguage(language);
3001  0 if (setCookie) {
3002  0 Cookie cookie = new Cookie("interfacelanguage", language);
3003  0 cookie.setMaxAge(60 * 60 * 24 * 365 * 10);
3004  0 cookie.setPath("/");
3005  0 context.getResponse().addCookie(cookie);
3006    }
3007  0 return language;
3008    }
3009   
 
3010  0 toggle public long getXWikiPreferenceAsLong(String preference, XWikiContext context)
3011    {
3012  0 return Long.parseLong(getXWikiPreference(preference, context));
3013    }
3014   
 
3015  0 toggle public long getSpacePreferenceAsLong(String preference, XWikiContext context)
3016    {
3017  0 return Long.parseLong(getSpacePreference(preference, context));
3018    }
3019   
 
3020  20677 toggle public long getXWikiPreferenceAsLong(String preference, long defaultValue, XWikiContext context)
3021    {
3022  20677 return NumberUtils.toLong((getXWikiPreference(preference, context)), defaultValue);
3023    }
3024   
 
3025  0 toggle public long getXWikiPreferenceAsLong(String preference, String fallbackParameter, long defaultValue,
3026    XWikiContext context)
3027    {
3028  0 return NumberUtils.toLong(getXWikiPreference(preference, fallbackParameter, "", context), defaultValue);
3029    }
3030   
 
3031  20 toggle public long getSpacePreferenceAsLong(String preference, long defaultValue, XWikiContext context)
3032    {
3033  20 return NumberUtils.toLong(getSpacePreference(preference, context), defaultValue);
3034    }
3035   
 
3036  0 toggle public long getUserPreferenceAsLong(String preference, XWikiContext context)
3037    {
3038  0 return Long.parseLong(getUserPreference(preference, context));
3039    }
3040   
 
3041  0 toggle public int getXWikiPreferenceAsInt(String preference, XWikiContext context)
3042    {
3043  0 return Integer.parseInt(getXWikiPreference(preference, context));
3044    }
3045   
 
3046  0 toggle public int getSpacePreferenceAsInt(String preference, XWikiContext context)
3047    {
3048  0 return Integer.parseInt(getSpacePreference(preference, context));
3049    }
3050   
 
3051  1119 toggle public int getXWikiPreferenceAsInt(String preference, int defaultValue, XWikiContext context)
3052    {
3053  1119 return NumberUtils.toInt(getXWikiPreference(preference, context), defaultValue);
3054    }
3055   
 
3056  0 toggle public int getXWikiPreferenceAsInt(String preference, String fallbackParameter, int defaultValue,
3057    XWikiContext context)
3058    {
3059  0 return NumberUtils.toInt(getXWikiPreference(preference, fallbackParameter, "", context), defaultValue);
3060    }
3061   
 
3062  572 toggle public int getSpacePreferenceAsInt(String preference, int defaultValue, XWikiContext context)
3063    {
3064  572 return NumberUtils.toInt(getSpacePreference(preference, context), defaultValue);
3065    }
3066   
 
3067  0 toggle public int getUserPreferenceAsInt(String prefname, XWikiContext context)
3068    {
3069  0 return Integer.parseInt(getUserPreference(prefname, context));
3070    }
3071   
 
3072  0 toggle public void flushCache(XWikiContext context)
3073    {
3074    // We need to flush the virtual wiki list
3075  0 this.initializedWikis = new ConcurrentHashMap<>();
3076   
3077    // We need to flush the group service cache
3078  0 if (this.groupService != null) {
3079  0 this.groupService.flushCache();
3080    }
3081   
3082    // If we use the Cache Store layer.. we need to flush it
3083  0 XWikiStoreInterface store = getStore();
3084  0 if ((store != null) && (store instanceof XWikiCacheStoreInterface)) {
3085  0 ((XWikiCacheStoreInterface) getStore()).flushCache();
3086    }
3087    // Flush renderers.. Groovy renderer has a cache
3088  0 getOldRendering().flushCache();
3089  0 getParseGroovyFromString().flushCache();
3090   
3091  0 XWikiPluginManager pmanager = getPluginManager();
3092  0 if (pmanager != null) {
3093  0 pmanager.flushCache(context);
3094    }
3095   
3096    // Make sure we call all classes flushCache function
3097  0 try {
3098  0 List<String> classes = getClassList(context);
3099  0 for (int i = 0; i < classes.size(); i++) {
3100  0 String className = classes.get(i);
3101  0 try {
3102  0 getClass(className, context).flushCache();
3103    } catch (Exception e) {
3104    }
3105    }
3106    } catch (Exception e) {
3107    }
3108   
3109    }
3110   
 
3111  99443 toggle public XWikiPluginManager getPluginManager()
3112    {
3113  99432 return this.pluginManager;
3114    }
3115   
 
3116  87 toggle public void setPluginManager(XWikiPluginManager pluginManager)
3117    {
3118  87 this.pluginManager = pluginManager;
3119    }
3120   
 
3121  138 toggle public void setStore(XWikiStoreInterface store)
3122    {
3123  138 this.store = store;
3124    }
3125   
 
3126  87 toggle public void setAttachmentStore(XWikiAttachmentStoreInterface attachmentStore)
3127    {
3128  87 this.attachmentStore = attachmentStore;
3129    }
3130   
 
3131  89 toggle public void setAttachmentVersioningStore(AttachmentVersioningStore avStore)
3132    {
3133  89 this.attachmentVersioningStore = avStore;
3134    }
3135   
 
3136  135 toggle public void setVersioningStore(XWikiVersioningStoreInterface versioningStore)
3137    {
3138  135 this.versioningStore = versioningStore;
3139    }
3140   
 
3141  95 toggle public void setRecycleBinStore(XWikiRecycleBinStoreInterface recycleBinStore)
3142    {
3143  95 this.recycleBinStore = recycleBinStore;
3144    }
3145   
 
3146  88 toggle public void setAttachmentRecycleBinStore(AttachmentRecycleBinStore attachmentRecycleBinStore)
3147    {
3148  88 this.attachmentRecycleBinStore = attachmentRecycleBinStore;
3149    }
3150   
 
3151  87 toggle public void setCriteriaService(XWikiCriteriaService criteriaService)
3152    {
3153  87 this.criteriaService = criteriaService;
3154    }
3155   
 
3156  0 toggle public void setVersion(String version)
3157    {
3158  0 this.version = version;
3159    }
3160   
3161    /**
3162    * Verify if the provided xclass page exists and that it contains all the required configuration properties to make
3163    * the tag feature work properly. If some properties are missing they are created and saved in the database.
3164    *
3165    * @param context see {@link XWikiContext}
3166    * @param classReference the reference of the document containing the class
3167    * @return the Base Class object containing the properties
3168    * @throws XWikiException if an error happens during the save to the database
3169    */
 
3170  102 toggle private BaseClass getMandatoryClass(XWikiContext context, DocumentReference classReference) throws XWikiException
3171    {
3172  102 XWikiDocument document = getDocument(classReference, context);
3173   
3174  102 if (context.get("initdone") == null) {
3175  102 @SuppressWarnings("deprecation")
3176    MandatoryDocumentInitializer initializer =
3177    Utils.getComponent(MandatoryDocumentInitializer.class, document.getFullName());
3178   
3179  102 if (initializer.updateDocument(document)) {
3180  4 saveDocument(document, localizePlainOrKey("core.model.xclass.mandatoryUpdateProperty.versionSummary"),
3181    context);
3182    }
3183    }
3184   
3185  102 return document.getXClass();
3186    }
3187   
3188    /**
3189    * Verify if the <code>XWiki.TagClass</code> page exists and that it contains all the required configuration
3190    * properties to make the tag feature work properly. If some properties are missing they are created and saved in
3191    * the database.
3192    *
3193    * @param context see {@link XWikiContext}
3194    * @return the TagClass Base Class object containing the properties
3195    * @throws XWikiException if an error happens during the save to the datavase
3196    */
 
3197  0 toggle public BaseClass getTagClass(XWikiContext context) throws XWikiException
3198    {
3199  0 return getMandatoryClass(context, new DocumentReference(context.getWikiId(), SYSTEM_SPACE, "TagClass"));
3200    }
3201   
3202    /**
3203    * Verify if the <code>XWiki.SheetClass</code> page exists and that it contains all the required configuration
3204    * properties to make the sheet feature work properly. If some properties are missing they are created and saved in
3205    * the database. SheetClass is used to a page as a sheet. When a page is tagged as a sheet and that page is included
3206    * in another page using the include macro then editing it triggers automatic inline edition (for XWiki Syntax 2.0
3207    * only - for XWiki Syntax 1.0 automatic inline edition is triggered using #includeForm).
3208    *
3209    * @param context see {@link XWikiContext}
3210    * @return the SheetClass Base Class object containing the properties
3211    * @throws XWikiException if an error happens during the save to the database
3212    * @deprecated since 3.1M2 edit mode class should be used for this purpose, not the sheet class
3213    * @see #getEditModeClass(XWikiContext)
3214    */
 
3215  0 toggle @Deprecated
3216    public BaseClass getSheetClass(XWikiContext context) throws XWikiException
3217    {
3218  0 return getMandatoryClass(context, new DocumentReference(context.getWikiId(), SYSTEM_SPACE, "SheetClass"));
3219    }
3220   
3221    /**
3222    * Verify if the {@code XWiki.EditModeClass} page exists and that it contains all the required configuration
3223    * properties to make the edit mode feature work properly. If some properties are missing they are created and saved
3224    * in the database. EditModeClass is used to specify the default edit mode of a page. It can also be used to mark a
3225    * page as a sheet. When a page is marked as a sheet and that page is included in another page using the include
3226    * macro then editing it triggers automatic inline edition (for XWiki Syntax 2.0 only - for XWiki Syntax 1.0
3227    * automatic inline edition is triggered using #includeForm). It replaces and enhances the SheetClass mechanism (see
3228    * {@link #getSheetClass(XWikiContext)}).
3229    *
3230    * @param context see {@link XWikiContext}
3231    * @return the EditModeClass Base Class object containing the properties
3232    * @throws XWikiException if an error happens during the save to the database
3233    * @since 3.1M2
3234    */
 
3235  0 toggle public BaseClass getEditModeClass(XWikiContext context) throws XWikiException
3236    {
3237  0 return getMandatoryClass(context, new DocumentReference(
3238    new LocalDocumentReference(XWikiConstant.EDIT_MODE_CLASS), new WikiReference(context.getWikiId())));
3239    }
3240   
3241    /**
3242    * Verify if the <code>XWiki.XWikiUsers</code> page exists and that it contains all the required configuration
3243    * properties to make the user feature work properly. If some properties are missing they are created and saved in
3244    * the database.
3245    *
3246    * @param context see {@link XWikiContext}
3247    * @return the XWikiUsers Base Class object containing the properties
3248    * @throws XWikiException if an error happens during the save to the datavase
3249    */
 
3250  33 toggle public BaseClass getUserClass(XWikiContext context) throws XWikiException
3251    {
3252  33 return getMandatoryClass(context, new DocumentReference(context.getWikiId(), SYSTEM_SPACE, "XWikiUsers"));
3253    }
3254   
3255    /**
3256    * Verify if the <code>XWiki.GlobalRedirect</code> page exists and that it contains all the required configuration
3257    * properties to make the redirection feature work properly. If some properties are missing they are created and
3258    * saved in the database.
3259    *
3260    * @param context see {@link XWikiContext}
3261    * @return the GlobalRedirect Base Class object containing the properties
3262    * @throws XWikiException if an error happens during the save to the datavase
3263    */
 
3264  0 toggle public BaseClass getRedirectClass(XWikiContext context) throws XWikiException
3265    {
3266  0 return getMandatoryClass(context, new DocumentReference(context.getWikiId(), SYSTEM_SPACE, "GlobalRedirect"));
3267    }
3268   
3269    /**
3270    * Verify if the <code>XWiki.XWikiPreferences</code> page exists and that it contains all the required configuration
3271    * properties to make XWiki work properly. If some properties are missing they are created and saved in the
3272    * database.
3273    *
3274    * @param context see {@link XWikiContext}
3275    * @return the XWiki Base Class object containing the properties
3276    * @throws XWikiException if an error happens during the save to the datavase
3277    */
 
3278  2 toggle public BaseClass getPrefsClass(XWikiContext context) throws XWikiException
3279    {
3280  2 return getMandatoryClass(context, getPreferencesDocumentReference(context));
3281    }
3282   
 
3283  26 toggle public BaseClass getGroupClass(XWikiContext context) throws XWikiException
3284    {
3285  26 return getMandatoryClass(context, new DocumentReference(context.getWikiId(), SYSTEM_SPACE, "XWikiGroups"));
3286    }
3287   
 
3288  32 toggle public BaseClass getRightsClass(String pagename, XWikiContext context) throws XWikiException
3289    {
3290  32 return getMandatoryClass(context, new DocumentReference(context.getWikiId(), SYSTEM_SPACE, pagename));
3291    }
3292   
 
3293  32 toggle public BaseClass getRightsClass(XWikiContext context) throws XWikiException
3294    {
3295  32 return getRightsClass("XWikiRights", context);
3296    }
3297   
 
3298  0 toggle public BaseClass getGlobalRightsClass(XWikiContext context) throws XWikiException
3299    {
3300  0 return getRightsClass("XWikiGlobalRights", context);
3301    }
3302   
 
3303  9 toggle public BaseClass getCommentsClass(XWikiContext context) throws XWikiException
3304    {
3305  9 return getMandatoryClass(context, new DocumentReference(context.getWikiId(), SYSTEM_SPACE, "XWikiComments"));
3306    }
3307   
 
3308  0 toggle public BaseClass getSkinClass(XWikiContext context) throws XWikiException
3309    {
3310  0 return getMandatoryClass(context, new DocumentReference(context.getWikiId(), SYSTEM_SPACE, "XWikiSkins"));
3311    }
3312   
 
3313  29 toggle public int createUser(XWikiContext context) throws XWikiException
3314    {
3315  29 return createUser(false, "edit", context);
3316    }
3317   
 
3318  4 toggle public int validateUser(boolean withConfirmEmail, XWikiContext context) throws XWikiException
3319    {
3320  4 try {
3321  4 XWikiRequest request = context.getRequest();
3322    // Get the user document
3323  4 String username = convertUsername(request.getParameter("xwikiname"), context);
3324  4 if (username.indexOf('.') == -1) {
3325  4 username = "XWiki." + username;
3326    }
3327  4 XWikiDocument userDocument = getDocument(username, context);
3328   
3329    // Get the stored validation key
3330  4 BaseObject userObject = userDocument.getObject("XWiki.XWikiUsers", 0);
3331  4 String storedKey = userObject.getStringValue("validkey");
3332   
3333    // Get the validation key from the URL
3334  4 String validationKey = request.getParameter("validkey");
3335  4 PropertyInterface validationKeyClass = getClass("XWiki.XWikiUsers", context).get("validkey");
3336  4 if (validationKeyClass instanceof PasswordClass) {
3337  4 validationKey = ((PasswordClass) validationKeyClass).getEquivalentPassword(storedKey, validationKey);
3338    }
3339   
3340    // Compare the two keys
3341  4 if ((!storedKey.equals("") && (storedKey.equals(validationKey)))) {
3342  2 userObject.setIntValue("active", 1);
3343  2 saveDocument(userDocument, context);
3344   
3345  2 if (withConfirmEmail) {
3346  0 String email = userObject.getStringValue("email");
3347  0 String password = userObject.getStringValue("password");
3348  0 sendValidationEmail(username, password, email, request.getParameter("validkey"),
3349    "confirmation_email_content", context);
3350    }
3351   
3352  2 return 0;
3353    } else {
3354  2 return -1;
3355    }
3356    } catch (Exception e) {
3357  0 LOGGER.error(e.getMessage(), e);
3358   
3359  0 throw new XWikiException(XWikiException.MODULE_XWIKI_APP, XWikiException.ERROR_XWIKI_APP_VALIDATE_USER,
3360    "Exception while validating user", e, null);
3361    }
3362    }
3363   
 
3364  29 toggle public int createUser(boolean withValidation, String userRights, XWikiContext context) throws XWikiException
3365    {
3366  29 try {
3367  29 XWikiRequest request = context.getRequest();
3368  29 Map<String, String[]> map = Util.getObject(request, "register");
3369   
3370  29 String content = "";
3371  29 Syntax syntax = getDefaultDocumentSyntaxInternal();
3372   
3373    // Read the values from the request.
3374  29 String xwikiname = request.getParameter("xwikiname");
3375  29 String password2 = request.getParameter("register2_password");
3376  29 String password = (map.get("password"))[0];
3377  29 String email = (map.get("email"))[0];
3378  29 String template = request.getParameter("template");
3379  29 String parent = request.getParameter("parent");
3380  29 String validkey = null;
3381   
3382    // Validate the values.
3383  29 if (XWikiRightService.SUPERADMIN_USER.equalsIgnoreCase(xwikiname)) {
3384  0 return -8;
3385    }
3386  29 try {
3387  29 if (!context.getUtil().match(getConfiguration().getProperty("xwiki.validusername", "/^[a-zA-Z0-9_]+$/"),
3388    xwikiname)) {
3389  0 return -4;
3390    }
3391    } catch (RuntimeException ex) {
3392  0 LOGGER.warn("Invalid regular expression for xwiki.validusername", ex);
3393  0 if (!context.getUtil().match("/^[a-zA-Z0-9_]+$/", xwikiname)) {
3394  0 return -4;
3395    }
3396    }
3397   
3398  29 if ((!password.equals(password2)) || (password.trim().equals(""))) {
3399    // TODO: throw wrong password exception
3400  0 return -2;
3401    }
3402   
3403  29 if ((template != null) && (!template.equals(""))) {
3404  0 XWikiDocument tdoc = getDocument(template, context);
3405  0 if ((!tdoc.isNew())) {
3406    // FIXME: This ignores template objects, attachments, etc.
3407  0 content = tdoc.getContent();
3408  0 syntax = tdoc.getSyntax();
3409    }
3410    }
3411   
3412  29 if ((parent == null) || (parent.equals(""))) {
3413  29 parent = "XWiki.XWikiUsers";
3414    }
3415   
3416    // Mark the user as active or waiting email validation.
3417  29 if (withValidation) {
3418  0 map.put("active", new String[] { "0" });
3419  0 validkey = generateValidationKey(16);
3420  0 map.put("validkey", new String[] { validkey });
3421   
3422    } else {
3423    // Mark user active
3424  29 map.put("active", new String[] { "1" });
3425    }
3426   
3427    // Create the user.
3428  29 int result =
3429    createUser(xwikiname, map, getRelativeEntityReferenceResolver().resolve(parent, EntityType.DOCUMENT),
3430    content, syntax, userRights, context);
3431   
3432    // Send validation mail, if needed.
3433  29 if ((result > 0) && (withValidation)) {
3434    // Send the validation email
3435  0 sendValidationEmail(xwikiname, password, email, validkey, "validation_email_content", context);
3436    }
3437   
3438  29 return result;
3439    } catch (XWikiException e) {
3440  0 LOGGER.error(e.getMessage(), e);
3441   
3442  0 throw e;
3443    } catch (Exception e) {
3444  0 LOGGER.error(e.getMessage(), e);
3445   
3446  0 throw new XWikiException(XWikiException.MODULE_XWIKI_APP, XWikiException.ERROR_XWIKI_APP_CREATE_USER,
3447    "Exception while creating user", e, null);
3448    }
3449    }
3450   
3451    /**
3452    * Method allows to create an empty user with no password (he won't be able to login) This method is usefull for
3453    * authentication like LDAP or App Server trusted
3454    *
3455    * @param xwikiname
3456    * @param userRights
3457    * @param context see {@link XWikiContext}
3458    * @return true if success
3459    * @throws XWikiException
3460    */
 
3461  0 toggle public boolean createEmptyUser(String xwikiname, String userRights, XWikiContext context) throws XWikiException
3462    {
3463  0 Map<String, String> map = new HashMap<String, String>();
3464  0 map.put("active", "1");
3465  0 map.put("first_name", xwikiname);
3466   
3467  0 if (createUser(xwikiname, map, userRights, context) == 1) {
3468  0 return true;
3469    } else {
3470  0 return false;
3471    }
3472    }
3473   
 
3474  0 toggle public void sendConfirmationEmail(String xwikiname, String password, String email, String message,
3475    String contentfield, XWikiContext context) throws XWikiException
3476    {
3477  0 sendValidationEmail(xwikiname, password, email, "message", message, contentfield, context);
3478    }
3479   
 
3480  0 toggle public void sendValidationEmail(String xwikiname, String password, String email, String validkey,
3481    String contentfield, XWikiContext context) throws XWikiException
3482    {
3483  0 sendValidationEmail(xwikiname, password, email, "validkey", validkey, contentfield, context);
3484    }
3485   
 
3486  0 toggle public void sendValidationEmail(String xwikiname, String password, String email, String addfieldname,
3487    String addfieldvalue, String contentfield, XWikiContext context) throws XWikiException
3488    {
3489  0 MailSenderConfiguration configuration = Utils.getComponent(MailSenderConfiguration.class);
3490   
3491  0 String sender;
3492  0 String content;
3493  0 try {
3494  0 sender = configuration.getFromAddress();
3495  0 if (StringUtils.isBlank(sender)) {
3496  0 String server = context.getRequest().getServerName();
3497  0 if (server.matches("\\[.*\\]|(\\d{1,3}+\\.){3}+\\d{1,3}+")) {
3498  0 sender = "noreply@domain.net";
3499    } else {
3500  0 sender = "noreply@" + server;
3501    }
3502    }
3503  0 content = getXWikiPreference(contentfield, context);
3504    } catch (Exception e) {
3505  0 throw new XWikiException(XWikiException.MODULE_XWIKI_EMAIL,
3506    XWikiException.ERROR_XWIKI_EMAIL_CANNOT_GET_VALIDATION_CONFIG,
3507    "Exception while reading the validation email config", e, null);
3508   
3509    }
3510   
3511  0 try {
3512  0 VelocityContext vcontext = (VelocityContext) context.get("vcontext");
3513  0 vcontext.put(addfieldname, addfieldvalue);
3514  0 vcontext.put("email", email);
3515  0 vcontext.put("password", password);
3516  0 vcontext.put("sender", sender);
3517  0 vcontext.put("xwikiname", xwikiname);
3518  0 content = parseContent(content, context);
3519    } catch (Exception e) {
3520  0 throw new XWikiException(XWikiException.MODULE_XWIKI_EMAIL,
3521    XWikiException.ERROR_XWIKI_EMAIL_CANNOT_PREPARE_VALIDATION_EMAIL,
3522    "Exception while preparing the validation email", e, null);
3523   
3524    }
3525   
3526    // Let's now send the message
3527  0 try {
3528  0 Session session =
3529    Session.getInstance(configuration.getAllProperties(), new XWikiAuthenticator(configuration));
3530  0 InputStream is = new ByteArrayInputStream(content.getBytes());
3531  0 MimeMessage message = new MimeMessage(session, is);
3532  0 message.setFrom(new InternetAddress(sender));
3533  0 message.setRecipients(Message.RecipientType.TO, email);
3534  0 message.setHeader("X-MailType", "Account Validation");
3535  0 MailSender mailSender = Utils.getComponent(MailSender.class);
3536  0 MailListener mailListener = Utils.getComponent(MailListener.class, "database");
3537  0 mailSender.sendAsynchronously(Arrays.asList(message), session, mailListener);
3538  0 mailListener.getMailStatusResult().waitTillProcessed(Long.MAX_VALUE);
3539  0 String errorMessage = MailStatusResultSerializer.serializeErrors(mailListener.getMailStatusResult());
3540  0 if (errorMessage != null) {
3541  0 throw new XWikiException(XWikiException.MODULE_XWIKI_EMAIL,
3542    XWikiException.ERROR_XWIKI_EMAIL_ERROR_SENDING_EMAIL,
3543    String.format("Error while sending the validation email. %s", errorMessage));
3544    }
3545    } catch (Exception e) {
3546  0 throw new XWikiException(XWikiException.MODULE_XWIKI_EMAIL,
3547    XWikiException.ERROR_XWIKI_EMAIL_ERROR_SENDING_EMAIL, "Error while sending the validation email", e);
3548    }
3549    }
3550   
 
3551  87 toggle public String generateRandomString(int size)
3552    {
3553  87 return RandomStringUtils.randomAlphanumeric(size);
3554    }
3555   
 
3556  0 toggle public String generateValidationKey(int size)
3557    {
3558  0 return generateRandomString(size);
3559    }
3560   
3561    /**
3562    * Create a new user.
3563    *
3564    * @param userName the name of the user (without the space)
3565    * @param map extra datas to add to user profile object
3566    * @param context see {@link XWikiContext}
3567    * @return
3568    * <ul>
3569    * <li>1: ok</li>
3570    * <li>-3: user already exists</li>
3571    * </ul>
3572    * @throws XWikiException failed to create the new user
3573    */
 
3574  0 toggle public int createUser(String userName, Map<String, ?> map, XWikiContext context) throws XWikiException
3575    {
3576  0 return createUser(userName, map, "edit", context);
3577    }
3578   
3579    /**
3580    * Create a new user.
3581    *
3582    * @param userName the name of the user (without the space)
3583    * @param map extra datas to add to user profile object
3584    * @param userRights the right of the user on his own profile page
3585    * @param context see {@link XWikiContext}
3586    * @return
3587    * <ul>
3588    * <li>1: ok</li>
3589    * <li>-3: user already exists</li>
3590    * </ul>
3591    * @throws XWikiException failed to create the new user
3592    */
 
3593  0 toggle public int createUser(String userName, Map<String, ?> map, String userRights, XWikiContext context)
3594    throws XWikiException
3595    {
3596  0 BaseClass userClass = getUserClass(context);
3597   
3598  0 String content = "";
3599  0 Syntax syntax = getDefaultDocumentSyntaxInternal();
3600   
3601  0 return createUser(userName, map,
3602    new EntityReference(userClass.getDocumentReference().getName(), EntityType.DOCUMENT), content, syntax,
3603    userRights, context);
3604    }
3605   
3606    /**
3607    * @deprecated since 2.4RC1 use
3608    * {@link #createUser(String, Map, EntityReference, String, Syntax, String, XWikiContext)} instead
3609    */
 
3610  0 toggle @Deprecated
3611    public int createUser(String userName, Map<String, ?> map, String parent, String content, String syntaxId,
3612    String userRights, XWikiContext context) throws XWikiException
3613    {
3614  0 Syntax syntax;
3615   
3616  0 try {
3617  0 syntax = getSyntaxFactory().createSyntaxFromIdString(syntaxId);
3618    } catch (ParseException e) {
3619  0 syntax = getDefaultDocumentSyntaxInternal();
3620    }
3621   
3622  0 return createUser(userName, map, getRelativeEntityReferenceResolver().resolve(parent, EntityType.DOCUMENT),
3623    content, syntax, userRights, context);
3624    }
3625   
3626    /**
3627    * Create a new user.
3628    *
3629    * @param userName the name of the user (without the space)
3630    * @param map extra datas to add to user profile object
3631    * @param parentReference the parent of the user profile
3632    * @param content the content of the user profile
3633    * @param syntax the syntax of the provided content
3634    * @param userRights the right of the user on his own profile page
3635    * @param context see {@link XWikiContext}
3636    * @return
3637    * <ul>
3638    * <li>1: ok</li>
3639    * <li>-3: user already exists</li>
3640    * </ul>
3641    * @throws XWikiException failed to create the new user
3642    */
 
3643  29 toggle public int createUser(String userName, Map<String, ?> map, EntityReference parentReference, String content,
3644    Syntax syntax, String userRights, XWikiContext context) throws XWikiException
3645    {
3646  29 BaseClass userClass = getUserClass(context);
3647   
3648  29 try {
3649    // TODO: Verify existing user
3650  29 XWikiDocument doc = getDocument(new DocumentReference(context.getWikiId(), "XWiki", userName), context);
3651   
3652  29 if (!doc.isNew()) {
3653    // TODO: throws Exception
3654  3 return -3;
3655    }
3656   
3657  26 DocumentReference userClassReference = userClass.getDocumentReference();
3658  26 BaseObject userObject =
3659    doc.newXObject(userClassReference.removeParent(userClassReference.getWikiReference()), context);
3660  26 userClass.fromMap(map, userObject);
3661   
3662  26 doc.setParentReference(parentReference);
3663  26 doc.setContent(content);
3664  26 doc.setSyntax(syntax);
3665  26 doc.setCreatorReference(doc.getDocumentReference());
3666  26 doc.setAuthorReference(doc.getDocumentReference());
3667   
3668    // The information from the user profile needs to be indexed using the proper locale. If multilingual is
3669    // enabled then the user can choose the desired locale (from the list of supported locales) before
3670    // registering. An administrator registering users can do the same. Otherwise, if there is only one locale
3671    // supported then that langage will be used.
3672  26 doc.setDefaultLocale(context.getLocale());
3673   
3674  26 protectUserPage(doc.getFullName(), userRights, doc, context);
3675   
3676  26 saveDocument(doc, localizePlainOrKey("core.comment.createdUser"), context);
3677   
3678    // Now let's add the user to XWiki.XWikiAllGroup
3679  26 setUserDefaultGroup(doc.getFullName(), context);
3680   
3681  26 return 1;
3682    } catch (Exception e) {
3683  0 Object[] args = { "XWiki." + userName };
3684  0 throw new XWikiException(XWikiException.MODULE_XWIKI_USER, XWikiException.ERROR_XWIKI_USER_CREATE,
3685    "Cannot create user {0}", e, args);
3686    }
3687    }
3688   
3689    /**
3690    * @deprecated starting with XE 1.8.1 use
3691    * {@link #createUser(String, Map, String, String, String, String, XWikiContext)} instead
3692    */
 
3693  0 toggle @Deprecated
3694    public int createUser(String xwikiname, Map<String, ?> map, String parent, String content, String userRights,
3695    XWikiContext context) throws XWikiException
3696    {
3697  0 return createUser(xwikiname, map, parent, content, Syntax.XWIKI_1_0.toIdString(), userRights, context);
3698    }
3699   
 
3700  29 toggle public void setUserDefaultGroup(String fullwikiname, XWikiContext context) throws XWikiException
3701    {
3702  29 String groupsPreference = getConfiguration().getProperty("xwiki.users.initialGroups", "XWiki.XWikiAllGroup");
3703   
3704  29 if (groupsPreference != null) {
3705  29 String[] groups = groupsPreference.split(",");
3706  29 for (String groupName : groups) {
3707  29 if (StringUtils.isNotBlank(groupName)) {
3708  29 addUserToGroup(fullwikiname, groupName.trim(), context);
3709    }
3710    }
3711    }
3712    }
3713   
 
3714  29 toggle protected void addUserToGroup(String userName, String groupName, XWikiContext context) throws XWikiException
3715    {
3716  29 XWikiDocument groupDoc = getDocument(groupName, context);
3717   
3718  29 DocumentReference groupClassReference = getGroupClass(context).getDocumentReference();
3719  29 BaseObject memberObject =
3720    groupDoc.newXObject(groupClassReference.removeParent(groupClassReference.getWikiReference()), context);
3721   
3722  29 memberObject.setStringValue("member", userName);
3723   
3724  29 this.saveDocument(groupDoc, localizePlainOrKey("core.comment.addedUserToGroup"), context);
3725    }
3726   
 
3727  29 toggle public void protectUserPage(String userName, String userRights, XWikiDocument doc, XWikiContext context)
3728    throws XWikiException
3729    {
3730  29 DocumentReference rightClassReference = getRightsClass(context).getDocumentReference();
3731   
3732  29 EntityReference relativeRightClassReference =
3733    rightClassReference.removeParent(rightClassReference.getWikiReference());
3734   
3735    // Allow users to edit their own profiles
3736  29 BaseObject newuserrightsobject = doc.newXObject(relativeRightClassReference, context);
3737  29 newuserrightsobject.setLargeStringValue("users", userName);
3738  29 newuserrightsobject.setStringValue("levels", userRights);
3739  29 newuserrightsobject.setIntValue("allow", 1);
3740    }
3741   
 
3742  3 toggle public User getUser(XWikiContext context)
3743    {
3744  3 XWikiUser xwikiUser = context.getXWikiUser();
3745  3 User user = new User(xwikiUser, context);
3746  3 return user;
3747    }
3748   
 
3749  0 toggle public User getUser(String username, XWikiContext context)
3750    {
3751  0 XWikiUser xwikiUser = new XWikiUser(username);
3752  0 User user = new User(xwikiUser, context);
3753  0 return user;
3754    }
3755   
3756    /**
3757    * Prepares the localized resources, according to the selected locale. Set context "msg" and locale.
3758    *
3759    * @param context see {@link XWikiContext}
3760    */
 
3761  11353 toggle public void prepareResources(XWikiContext context)
3762    {
3763  11348 if (context.get("msg") == null) {
3764  11303 Locale locale = getLocalePreference(context);
3765  11344 context.setLocale(locale);
3766  11342 if (context.getResponse() != null) {
3767  11342 context.getResponse().setLocale(locale);
3768    }
3769  11331 XWikiMessageTool msg = new XWikiMessageTool(Utils.getComponent(ContextualLocalizationManager.class));
3770  11328 context.put("msg", msg);
3771    }
3772    }
3773   
 
3774  13008 toggle public XWikiUser checkAuth(XWikiContext context) throws XWikiException
3775    {
3776  13018 return getAuthService().checkAuth(context);
3777    }
3778   
 
3779  11672 toggle public boolean checkAccess(String action, XWikiDocument doc, XWikiContext context) throws XWikiException
3780    {
3781    // Handle the 'skin' action specially so that resources don`t require special (or even 'view') rights.
3782  11674 String firstSpaceName = doc.getDocumentReference().getSpaceReferences().get(0).getName();
3783  11672 if (action.equals("skin") && SKIN_RESOURCE_SPACE_NAMES.contains(firstSpaceName)) {
3784    // We still need to call checkAuth to set the proper user.
3785  1112 XWikiUser user = checkAuth(context);
3786  1109 if (user != null) {
3787  851 context.setUser(user.getUser());
3788    }
3789   
3790    // Always allow.
3791  1114 return true;
3792    }
3793   
3794  10560 return getRightService().checkAccess(action, doc, context);
3795    }
3796   
 
3797  150 toggle public String include(String topic, boolean isForm, XWikiContext context) throws XWikiException
3798    {
3799  150 String database = null, incdatabase = null;
3800  150 String prefixedTopic, localTopic;
3801   
3802    // Save current documents in script context
3803  150 Document currentAPIdoc = null, currentAPIcdoc = null, currentAPItdoc = null;
3804  150 ScriptContextManager scritContextManager = Utils.getComponent(ScriptContextManager.class);
3805  150 ScriptContext scontext = scritContextManager.getScriptContext();
3806  150 String currentDocName = context.getWikiId() + ":" + context.getDoc().getFullName();
3807  150 if (scontext != null) {
3808  150 currentAPIdoc = (Document) scontext.getAttribute("doc");
3809  150 currentAPIcdoc = (Document) scontext.getAttribute("cdoc");
3810  150 currentAPItdoc = (Document) scontext.getAttribute("tdoc");
3811    }
3812   
3813  150 try {
3814  150 int i0 = topic.indexOf(':');
3815  150 if (i0 != -1) {
3816  0 incdatabase = topic.substring(0, i0);
3817  0 database = context.getWikiId();
3818  0 context.setWikiId(incdatabase);
3819  0 prefixedTopic = topic;
3820  0 localTopic = topic.substring(i0 + 1);
3821    } else {
3822  150 prefixedTopic = context.getWikiId() + ":" + topic;
3823  150 localTopic = topic;
3824    }
3825   
3826  150 XWikiDocument doc = null;
3827  150 try {
3828  150 LOGGER.debug("Including Topic " + topic);
3829  150 try {
3830  150 @SuppressWarnings("unchecked")
3831    Set<String> includedDocs = (Set<String>) context.get("included_docs");
3832  150 if (includedDocs == null) {
3833  150 includedDocs = new HashSet<String>();
3834  150 context.put("included_docs", includedDocs);
3835    }
3836   
3837  150 if (includedDocs.contains(prefixedTopic) || currentDocName.equals(prefixedTopic)) {
3838  0 LOGGER.warn("Error on too many recursive includes for topic " + topic);
3839  0 return "Cannot make recursive include";
3840    }
3841  150 includedDocs.add(prefixedTopic);
3842    } catch (Exception e) {
3843    }
3844   
3845    // Get document to include
3846  150 DocumentReference targetDocumentReference =
3847    getCurrentMixedDocumentReferenceResolver().resolve(localTopic);
3848  150 doc = getDocument(targetDocumentReference, context);
3849   
3850  150 if (checkAccess("view", doc, context) == false) {
3851  0 throw new XWikiException(XWikiException.MODULE_XWIKI_ACCESS,
3852    XWikiException.ERROR_XWIKI_ACCESS_DENIED, "Access to this document is denied: " + doc);
3853    }
3854    } catch (XWikiException e) {
3855  0 LOGGER.warn("Exception Including Topic " + topic, e);
3856  0 return "Topic " + topic + " does not exist";
3857    }
3858   
3859  150 XWikiDocument contentdoc = doc.getTranslatedDocument(context);
3860   
3861  150 String result;
3862  150 if (isForm) {
3863    // We do everything in the context of the including document
3864  72 if (database != null) {
3865  0 context.setWikiId(database);
3866    }
3867   
3868    // Note: the Script macro in the new rendering checks for programming rights for the document in
3869    // the xwiki context.
3870  72 result = getRenderedContent(contentdoc, (XWikiDocument) context.get("doc"), context);
3871    } else {
3872    // We stay in the included document context
3873   
3874    // Since the Script macro checks for programming rights in the current document, we need to
3875    // temporarily set the contentdoc as the current doc before rendering it.
3876  78 XWikiDocument originalDoc = null;
3877  78 try {
3878  78 originalDoc = context.getDoc();
3879  78 context.put("doc", doc);
3880  78 result = getRenderedContent(contentdoc, doc, context);
3881    } finally {
3882  78 context.put("doc", originalDoc);
3883    }
3884    }
3885  150 try {
3886  150 @SuppressWarnings("unchecked")
3887    Set<String> includedDocs = (Set<String>) context.get("included_docs");
3888  150 if (includedDocs != null) {
3889  150 includedDocs.remove(prefixedTopic);
3890    }
3891    } catch (Exception e) {
3892    }
3893  150 return result;
3894    } finally {
3895  150 if (database != null) {
3896  0 context.setWikiId(database);
3897    }
3898   
3899  150 if (currentAPIdoc != null) {
3900  150 if (scontext != null) {
3901  150 scontext.setAttribute("doc", currentAPIdoc, ScriptContext.ENGINE_SCOPE);
3902    }
3903    }
3904  150 if (currentAPIcdoc != null) {
3905  150 if (scontext != null) {
3906  150 scontext.setAttribute("cdoc", currentAPIcdoc, ScriptContext.ENGINE_SCOPE);
3907    }
3908    }
3909  150 if (currentAPItdoc != null) {
3910  150 if (scontext != null) {
3911  150 scontext.setAttribute("tdoc", currentAPItdoc, ScriptContext.ENGINE_SCOPE);
3912    }
3913    }
3914    }
3915    }
3916   
3917    /**
3918    * Render content from the passed included document, setting the correct security doc (sdoc) and including doc
3919    * (idoc).
3920    *
3921    * @since 2.2M2
3922    */
 
3923  150 toggle private String getRenderedContent(XWikiDocument includedDoc, XWikiDocument includingDoc, XWikiContext context)
3924    throws XWikiException
3925    {
3926  150 String result;
3927  150 XWikiDocument idoc = (XWikiDocument) context.get("idoc");
3928  150 XWikiDocument sdoc = (XWikiDocument) context.get("sdoc");
3929   
3930  150 context.put("idoc", includingDoc);
3931  150 context.put("sdoc", includedDoc);
3932  150 try {
3933  150 result = includedDoc.getRenderedContent(Utils.getComponent(RenderingContext.class).getTargetSyntax(), false,
3934    context);
3935    } finally {
3936    // Remove including doc or set the previous one
3937  150 if (idoc == null) {
3938  150 context.remove("idoc");
3939    } else {
3940  0 context.put("idoc", idoc);
3941    }
3942   
3943    // Remove security doc or set the previous one
3944  150 if (sdoc == null) {
3945  1 context.remove("sdoc");
3946    } else {
3947  149 context.put("sdoc", sdoc);
3948    }
3949    }
3950   
3951  150 return result;
3952    }
3953   
 
3954  129 toggle public void deleteDocument(XWikiDocument doc, XWikiContext context) throws XWikiException
3955    {
3956  129 deleteDocument(doc, true, context);
3957    }
3958   
 
3959  156 toggle public void deleteDocument(XWikiDocument doc, boolean totrash, XWikiContext context) throws XWikiException
3960    {
3961  156 String currentWiki = null;
3962   
3963  156 currentWiki = context.getWikiId();
3964  156 try {
3965  156 context.setWikiId(doc.getDocumentReference().getWikiReference().getName());
3966   
3967    // The source document is a new empty XWikiDocument to follow
3968    // DocumentUpdatedEvent policy: source document in new document and the old version is available using
3969    // doc.getOriginalDocument()
3970  156 XWikiDocument blankDoc = new XWikiDocument(doc.getDocumentReference());
3971    // Again to follow general event policy, new document author is the user who modified the document
3972    // (here the modification is delete)
3973  156 blankDoc.setOriginalDocument(doc.getOriginalDocument());
3974  156 blankDoc.setAuthorReference(context.getUserReference());
3975  156 blankDoc.setContentAuthorReference(context.getUserReference());
3976   
3977  156 ObservationManager om = getObservationManager();
3978   
3979    // Inform notification mechanisms that a document is about to be deleted
3980    // Note that for the moment the event being send is a bridge event, as we are still passing around
3981    // an XWikiDocument as source and an XWikiContext as data.
3982  156 if (om != null) {
3983  156 om.notify(new DocumentDeletingEvent(doc.getDocumentReference()), blankDoc, context);
3984    }
3985   
3986  156 if (hasRecycleBin(context) && totrash) {
3987  153 getRecycleBinStore().saveToRecycleBin(doc, context.getUser(), new Date(), context, true);
3988    }
3989   
3990  156 getStore().deleteXWikiDoc(doc, context);
3991   
3992  156 try {
3993    // Inform notification mechanisms that a document has been deleted
3994    // Note that for the moment the event being send is a bridge event, as we are still passing around
3995    // an XWikiDocument as source and an XWikiContext as data.
3996  156 if (om != null) {
3997  156 om.notify(new DocumentDeletedEvent(doc.getDocumentReference()), blankDoc, context);
3998    }
3999    } catch (Exception ex) {
4000  0 LOGGER.error("Failed to send document delete notifications for document [{}]",
4001    doc.getDocumentReference(), ex);
4002    }
4003    } finally {
4004  156 context.setWikiId(currentWiki);
4005    }
4006    }
4007   
 
4008  4 toggle public String getDatabase()
4009    {
4010  4 return this.database;
4011    }
4012   
 
4013  87 toggle public void setDatabase(String database)
4014    {
4015  87 this.database = database;
4016    }
4017   
 
4018  0 toggle public void gc()
4019    {
4020  0 System.gc();
4021    }
4022   
 
4023  0 toggle public long freeMemory()
4024    {
4025  0 return Runtime.getRuntime().freeMemory();
4026    }
4027   
 
4028  0 toggle public long totalMemory()
4029    {
4030  0 return Runtime.getRuntime().totalMemory();
4031    }
4032   
 
4033  0 toggle public long maxMemory()
4034    {
4035  0 return Runtime.getRuntime().maxMemory();
4036    }
4037   
 
4038  0 toggle public String[] split(String str, String sep)
4039    {
4040  0 return StringUtils.split(str, sep);
4041    }
4042   
4043    /**
4044    * @deprecated use {@link ExceptionUtils#getStackTrace(Throwable)} instead
4045    */
 
4046  0 toggle @Deprecated
4047    public String printStrackTrace(Throwable e)
4048    {
4049  0 StringWriter strwriter = new StringWriter();
4050  0 PrintWriter writer = new PrintWriter(strwriter);
4051  0 e.printStackTrace(writer);
4052   
4053  0 return strwriter.toString();
4054    }
4055   
4056    /**
4057    * @since 2.2M2
4058    */
 
4059  4 toggle public boolean copyDocument(DocumentReference sourceDocumentReference, DocumentReference targetDocumentReference,
4060    XWikiContext context) throws XWikiException
4061    {
4062  4 return copyDocument(sourceDocumentReference, targetDocumentReference, null, true, context);
4063    }
4064   
4065    /**
4066    * @since 2.2M2
4067    */
 
4068  3 toggle public boolean copyDocument(DocumentReference sourceDocumentReference, DocumentReference targetDocumentReference,
4069    boolean reset, XWikiContext context) throws XWikiException
4070    {
4071  3 return copyDocument(sourceDocumentReference, targetDocumentReference, null, reset, context);
4072    }
4073   
4074    /**
4075    * @since 2.2M2
4076    */
 
4077  0 toggle public boolean copyDocument(DocumentReference sourceDocumentReference, DocumentReference targetDocumentReference,
4078    boolean reset, boolean force, boolean resetCreationData, XWikiContext context) throws XWikiException
4079    {
4080  0 return copyDocument(sourceDocumentReference, targetDocumentReference, null, reset, force, resetCreationData,
4081    context);
4082    }
4083   
4084    /**
4085    * @since 2.2M2
4086    */
 
4087  0 toggle public boolean copyDocument(DocumentReference sourceDocumentReference, DocumentReference targetDocumentReference,
4088    String wikilocale, XWikiContext context) throws XWikiException
4089    {
4090  0 return copyDocument(sourceDocumentReference, targetDocumentReference, wikilocale, true, context);
4091    }
4092   
4093    /**
4094    * @since 2.2M2
4095    */
 
4096  7 toggle public boolean copyDocument(DocumentReference sourceDocumentReference, DocumentReference targetDocumentReference,
4097    String wikilocale, boolean reset, XWikiContext context) throws XWikiException
4098    {
4099  7 return copyDocument(sourceDocumentReference, targetDocumentReference, wikilocale, reset, false, context);
4100    }
4101   
4102    /**
4103    * @since 2.2M2
4104    */
 
4105  81 toggle public boolean copyDocument(DocumentReference sourceDocumentReference, DocumentReference targetDocumentReference,
4106    String wikilocale, boolean reset, boolean force, XWikiContext context) throws XWikiException
4107    {
4108  81 return copyDocument(sourceDocumentReference, targetDocumentReference, wikilocale, reset, force, false, context);
4109    }
4110   
4111    /**
4112    * @since 2.2M2
4113    */
 
4114  87 toggle public boolean copyDocument(DocumentReference sourceDocumentReference, DocumentReference targetDocumentReference,
4115    String wikilocale, boolean reset, boolean force, boolean resetCreationData, XWikiContext context)
4116    throws XWikiException
4117    {
4118  87 String db = context.getWikiId();
4119  87 String sourceWiki = sourceDocumentReference.getWikiReference().getName();
4120  87 String targetWiki = targetDocumentReference.getWikiReference().getName();
4121   
4122  87 String sourceStringReference = getDefaultEntityReferenceSerializer().serialize(sourceDocumentReference);
4123   
4124  87 try {
4125  87 context.setWikiId(sourceWiki);
4126  87 XWikiDocument sdoc = getDocument(sourceDocumentReference, context);
4127  87 if (!sdoc.isNew()) {
4128  87 if (LOGGER.isInfoEnabled()) {
4129  0 LOGGER.info(
4130    "Copying document [" + sourceDocumentReference + "] to [" + targetDocumentReference + "]");
4131    }
4132   
4133    // Let's switch to the other database to verify if the document already exists
4134  87 context.setWikiId(targetWiki);
4135  87 XWikiDocument tdoc = getDocument(targetDocumentReference, context);
4136    // There is already an existing document
4137  87 if (!tdoc.isNew()) {
4138  52 if (force) {
4139    // We need to delete the previous document
4140  52 deleteDocument(tdoc, context);
4141    } else {
4142  0 return false;
4143    }
4144    }
4145   
4146    // Let's switch back again to the original db
4147  87 context.setWikiId(sourceWiki);
4148   
4149  87 if (wikilocale == null) {
4150  87 tdoc = sdoc.copyDocument(targetDocumentReference, context);
4151   
4152    // We know the target document doesn't exist and we want to save the attachments without
4153    // incrementing their versions.
4154    // See XWIKI-8157: The "Copy Page" action adds an extra version to the attached file
4155  87 tdoc.setNew(true);
4156   
4157    // forget past versions
4158  87 if (reset) {
4159  78 tdoc.setVersion("1.1");
4160    }
4161  87 if (resetCreationData) {
4162  6 Date now = new Date();
4163  6 tdoc.setCreationDate(now);
4164  6 tdoc.setContentUpdateDate(now);
4165  6 tdoc.setDate(now);
4166  6 tdoc.setCreatorReference(context.getUserReference());
4167  6 tdoc.setAuthorReference(context.getUserReference());
4168    }
4169   
4170    // We don't want to trigger a new version otherwise the version number will be wrong.
4171  87 tdoc.setMetaDataDirty(false);
4172  87 tdoc.setContentDirty(false);
4173   
4174  87 saveDocument(tdoc, "Copied from " + sourceStringReference, context);
4175   
4176  87 if (!reset) {
4177  9 context.setWikiId(sourceWiki);
4178  9 XWikiDocumentArchive txda = getVersioningStore().getXWikiDocumentArchive(sdoc, context);
4179  9 context.setWikiId(targetWiki);
4180  9 txda = txda.clone(tdoc.getId(), context);
4181  9 getVersioningStore().saveXWikiDocArchive(txda, true, context);
4182    } else {
4183  78 context.setWikiId(targetWiki);
4184  78 getVersioningStore().resetRCSArchive(tdoc, true, context);
4185    }
4186   
4187    // Now we need to copy the translations
4188  87 context.setWikiId(sourceWiki);
4189  87 List<String> tlist = sdoc.getTranslationList(context);
4190  87 for (String clanguage : tlist) {
4191  30 XWikiDocument stdoc = sdoc.getTranslatedDocument(clanguage, context);
4192  30 if (LOGGER.isInfoEnabled()) {
4193  0 LOGGER.info("Copying document [" + sourceWiki + "], language [" + clanguage + "] to ["
4194    + targetDocumentReference + "]");
4195    }
4196   
4197  30 context.setWikiId(targetWiki);
4198  30 XWikiDocument ttdoc = tdoc.getTranslatedDocument(clanguage, context);
4199   
4200    // There is already an existing document
4201  30 if (ttdoc != tdoc) {
4202  0 return false;
4203    }
4204   
4205    // Let's switch back again to the original db
4206  30 context.setWikiId(sourceWiki);
4207   
4208  30 ttdoc = stdoc.copyDocument(targetDocumentReference, context);
4209   
4210    // forget past versions
4211  30 if (reset) {
4212  30 ttdoc.setNew(true);
4213  30 ttdoc.setVersion("1.1");
4214    }
4215  30 if (resetCreationData) {
4216  0 Date now = new Date();
4217  0 ttdoc.setCreationDate(now);
4218  0 ttdoc.setContentUpdateDate(now);
4219  0 ttdoc.setDate(now);
4220  0 ttdoc.setCreatorReference(context.getUserReference());
4221  0 ttdoc.setAuthorReference(context.getUserReference());
4222    }
4223   
4224    // we don't want to trigger a new version
4225    // otherwise the version number will be wrong
4226  30 tdoc.setMetaDataDirty(false);
4227  30 tdoc.setContentDirty(false);
4228   
4229  30 saveDocument(ttdoc, "Copied from " + sourceStringReference, context);
4230   
4231  30 if (!reset) {
4232  0 context.setWikiId(sourceWiki);
4233  0 XWikiDocumentArchive txda = getVersioningStore().getXWikiDocumentArchive(sdoc, context);
4234  0 context.setWikiId(targetWiki);
4235  0 txda = txda.clone(tdoc.getId(), context);
4236  0 getVersioningStore().saveXWikiDocArchive(txda, true, context);
4237    } else {
4238  30 getVersioningStore().resetRCSArchive(tdoc, true, context);
4239    }
4240    }
4241    } else {
4242    // We want only one language in the end
4243  0 XWikiDocument stdoc = sdoc.getTranslatedDocument(wikilocale, context);
4244   
4245  0 tdoc = stdoc.copyDocument(targetDocumentReference, context);
4246   
4247    // We know the target document doesn't exist and we want to save the attachments without
4248    // incrementing their versions.
4249    // See XWIKI-8157: The "Copy Page" action adds an extra version to the attached file
4250  0 tdoc.setNew(true);
4251   
4252    // forget language
4253  0 tdoc.setDefaultLanguage(wikilocale);
4254  0 tdoc.setLanguage("");
4255    // forget past versions
4256  0 if (reset) {
4257  0 tdoc.setVersion("1.1");
4258    }
4259  0 if (resetCreationData) {
4260  0 Date now = new Date();
4261  0 tdoc.setCreationDate(now);
4262  0 tdoc.setContentUpdateDate(now);
4263  0 tdoc.setDate(now);
4264  0 tdoc.setCreatorReference(context.getUserReference());
4265  0 tdoc.setAuthorReference(context.getUserReference());
4266    }
4267   
4268    // we don't want to trigger a new version
4269    // otherwise the version number will be wrong
4270  0 tdoc.setMetaDataDirty(false);
4271  0 tdoc.setContentDirty(false);
4272   
4273  0 saveDocument(tdoc, "Copied from " + sourceStringReference, context);
4274   
4275  0 if (!reset) {
4276  0 context.setWikiId(sourceWiki);
4277  0 XWikiDocumentArchive txda = getVersioningStore().getXWikiDocumentArchive(sdoc, context);
4278  0 context.setWikiId(targetWiki);
4279  0 txda = txda.clone(tdoc.getId(), context);
4280  0 getVersioningStore().saveXWikiDocArchive(txda, true, context);
4281    } else {
4282  0 getVersioningStore().resetRCSArchive(tdoc, true, context);
4283    }
4284    }
4285    }
4286  87 return true;
4287    } finally {
4288  87 context.setWikiId(db);
4289    }
4290    }
4291   
 
4292  0 toggle public int copySpaceBetweenWikis(String space, String sourceWiki, String targetWiki, String locale,
4293    XWikiContext context) throws XWikiException
4294    {
4295  0 return copySpaceBetweenWikis(space, sourceWiki, targetWiki, locale, false, context);
4296    }
4297   
 
4298  0 toggle public int copySpaceBetweenWikis(String space, String sourceWiki, String targetWiki, String locale, boolean clean,
4299    XWikiContext context) throws XWikiException
4300    {
4301  0 String db = context.getWikiId();
4302  0 int nb = 0;
4303    // Workaround for XWIKI-3915: Do not use XWikiStoreInterface#searchDocumentNames since currently it has the
4304    // side effect of hidding hidden documents and no other workaround exists than directly using
4305    // XWikiStoreInterface#search directly
4306  0 String sql = "select distinct doc.fullName from XWikiDocument as doc";
4307  0 List<String> parameters = new ArrayList<String>();
4308  0 if (space != null) {
4309  0 sql += " where doc.space = ?";
4310  0 parameters.add(space);
4311    }
4312   
4313  0 if (clean) {
4314  0 try {
4315  0 context.setWikiId(targetWiki);
4316  0 List<String> list = getStore().search(sql, 0, 0, parameters, context);
4317  0 if (LOGGER.isInfoEnabled()) {
4318  0 LOGGER.info("Deleting " + list.size() + " documents from wiki " + targetWiki);
4319    }
4320   
4321  0 for (String docname : list) {
4322  0 XWikiDocument doc = getDocument(docname, context);
4323  0 deleteDocument(doc, context);
4324    }
4325    } finally {
4326  0 context.setWikiId(db);
4327    }
4328    }
4329   
4330  0 try {
4331  0 context.setWikiId(sourceWiki);
4332  0 List<String> list = getStore().search(sql, 0, 0, parameters, context);
4333  0 if (LOGGER.isInfoEnabled()) {
4334  0 LOGGER.info("Copying " + list.size() + " documents from wiki " + sourceWiki + " to wiki " + targetWiki);
4335    }
4336   
4337  0 WikiReference sourceWikiReference = new WikiReference(sourceWiki);
4338  0 WikiReference targetWikiReference = new WikiReference(targetWiki);
4339  0 for (String docname : list) {
4340  0 DocumentReference sourceDocumentReference = getCurrentMixedDocumentReferenceResolver().resolve(docname);
4341  0 sourceDocumentReference = sourceDocumentReference
4342    .replaceParent(sourceDocumentReference.getWikiReference(), sourceWikiReference);
4343  0 DocumentReference targetDocumentReference =
4344    sourceDocumentReference.replaceParent(sourceWikiReference, targetWikiReference);
4345  0 copyDocument(sourceDocumentReference, targetDocumentReference, locale, context);
4346  0 nb++;
4347    }
4348  0 return nb;
4349    } finally {
4350  0 context.setWikiId(db);
4351    }
4352    }
4353   
4354    /**
4355    * Copy an entire wiki to a target wiki.
4356    * <p>
4357    * It does not override document already existing in target wiki.
4358    *
4359    * @param sourceWiki the source wiki identifier
4360    * @param targetWiki the target wiki identifier
4361    * @param locale the locale to copy
4362    * @param context see {@link XWikiContext}
4363    * @return the number of copied documents
4364    * @throws XWikiException failed to copy wiki
4365    * @deprecated since 5.3, use {@link WikiManager#copy(String, String, String, boolean, boolean, boolean)} instead
4366    */
 
4367  0 toggle @Deprecated
4368    public int copyWiki(String sourceWiki, String targetWiki, String locale, XWikiContext context) throws XWikiException
4369    {
4370  0 return copyWiki(sourceWiki, targetWiki, locale, false, context);
4371    }
4372   
4373    /**
4374    * Copy an entire wiki to a target wiki.
4375    *
4376    * @param sourceWiki the source wiki identifier
4377    * @param targetWiki the target wiki identifier
4378    * @param locale the locale to copy
4379    * @param clean clean the target wiki before copying
4380    * @param context see {@link XWikiContext}
4381    * @return the number of copied documents
4382    * @throws XWikiException failed to copy wiki
4383    * @deprecated since 5.3, use {@link WikiManager#copy(String, String, String, boolean, boolean, boolean)} instead
4384    */
 
4385  0 toggle @Deprecated
4386    public int copyWiki(String sourceWiki, String targetWiki, String locale, boolean clean, XWikiContext context)
4387    throws XWikiException
4388    {
4389  0 int documents = copySpaceBetweenWikis(null, sourceWiki, targetWiki, locale, clean, context);
4390   
4391  0 ObservationManager om = getObservationManager();
4392   
4393  0 if (om != null) {
4394  0 om.notify(new WikiCopiedEvent(sourceWiki, targetWiki), sourceWiki, context);
4395    }
4396   
4397  0 return documents;
4398    }
4399   
 
4400  28124 toggle public String getEncoding()
4401    {
4402  28124 return getConfiguration().getProperty("xwiki.encoding", "UTF-8");
4403    }
4404   
 
4405  9600 toggle public URL getServerURL(String database, XWikiContext context) throws MalformedURLException
4406    {
4407  9600 String serverurl = null;
4408   
4409    // In virtual wiki path mode the server is the standard one
4410  9600 if ("1".equals(getConfiguration().getProperty("xwiki.virtual.usepath", "1"))) {
4411  9596 return null;
4412    }
4413   
4414  4 if (database != null) {
4415  4 String db = context.getWikiId();
4416  4 try {
4417  4 context.setWikiId(getDatabase());
4418  4 XWikiDocument doc = getDocument("XWiki.XWikiServer" + StringUtils.capitalize(database), context);
4419  4 BaseObject serverobject = doc.getXObject(VIRTUAL_WIKI_DEFINITION_CLASS_REFERENCE);
4420  4 if (serverobject != null) {
4421  4 String server = serverobject.getStringValue("server");
4422  4 if (server != null) {
4423  4 String protocol = getConfiguration().getProperty("xwiki.url.protocol", null);
4424  4 if (protocol == null) {
4425  4 int iSecure = serverobject.getIntValue("secure", -1);
4426    // Check the request object if the "secure" property is undefined.
4427  4 boolean secure = iSecure == 1 || (iSecure < 0 && context.getRequest().isSecure());
4428  4 protocol = secure ? "https" : "http";
4429    }
4430  4 long port = context.getURL().getPort();
4431  4 if (port == 80 || port == 443) {
4432  0 port = -1;
4433    }
4434  4 if (port != -1) {
4435  0 serverurl = protocol + "://" + server + ":" + port + "/";
4436    } else {
4437  4 serverurl = protocol + "://" + server + "/";
4438    }
4439    }
4440    }
4441    } catch (Exception ex) {
4442    } finally {
4443  4 context.setWikiId(db);
4444    }
4445    }
4446   
4447  4 if (serverurl != null) {
4448  4 return new URL(serverurl);
4449    } else {
4450  0 return null;
4451    }
4452    }
4453   
 
4454  112287 toggle public String getServletPath(String wikiName, XWikiContext context)
4455    {
4456    // unless we are in virtual wiki path mode we should return null
4457  112283 if (!context.getMainXWiki().equalsIgnoreCase(wikiName)
4458    && "1".equals(getConfiguration().getProperty("xwiki.virtual.usepath", "1"))) {
4459  10048 String database = context.getWikiId();
4460  10048 try {
4461  10048 context.setWikiId(context.getMainXWiki());
4462  10049 XWikiDocument doc = getDocument(getServerWikiPage(wikiName), context);
4463  10049 BaseObject serverobject = doc.getXObject(VIRTUAL_WIKI_DEFINITION_CLASS_REFERENCE);
4464  10049 if (serverobject != null) {
4465  10025 String server = serverobject.getStringValue("server");
4466  10025 return "wiki/" + server + "/";
4467    }
4468    } catch (Exception e) {
4469  0 LOGGER.error("Failed to get URL for provided wiki [" + wikiName + "]", e);
4470    } finally {
4471  10049 context.setWikiId(database);
4472    }
4473    }
4474   
4475  102261 String servletPath = getConfiguration().getProperty("xwiki.servletpath", "");
4476   
4477  102260 if (context.getRequest() != null) {
4478  102260 if (StringUtils.isEmpty(servletPath)) {
4479  102260 String currentServletpath = context.getRequest().getServletPath();
4480  102258 if (currentServletpath != null && currentServletpath.startsWith("/bin")) {
4481  100826 servletPath = "bin/";
4482    } else {
4483  1432 servletPath = getConfiguration().getProperty("xwiki.defaultservletpath", "bin/");
4484    }
4485    }
4486    }
4487   
4488  102258 return servletPath;
4489    }
4490   
 
4491  14047 toggle public String getWebAppPath(XWikiContext context)
4492    {
4493  14046 String contextPath = getConfiguration().getProperty("xwiki.webapppath");
4494  14048 if (contextPath == null) {
4495    // Try getting the context path by asking the request for it (if a request exists!) and if it doesn't
4496    // work try extracting it from the context URL.
4497    // TODO: Instead of trying to extract from the URL, save the context path at webapp init (using a
4498    // ServlettContextListener for example).
4499  14048 XWikiRequest request = context.getRequest();
4500  14046 if (request != null) {
4501  14046 contextPath = request.getContextPath();
4502    }
4503  14047 if (contextPath == null) {
4504    // Extract the context by getting the first path segment
4505  123 contextPath = StringUtils.substringBefore(StringUtils.stripStart(context.getURL().getPath(), "/"), "/");
4506    }
4507    }
4508   
4509    // Remove any leading or trailing slashes
4510  14043 contextPath = StringUtils.strip(contextPath, "/");
4511   
4512    // TODO We're using URL parts in a wrong way, since contextPath and servletPath are returned with a leading /,
4513    // while we need a trailing /. This code ensure we always have CONTEXTNAME + "/".
4514  14023 return contextPath + "/";
4515    }
4516   
4517    /**
4518    * @since 7.2M1
4519    */
 
4520  2452 toggle public String getURL(EntityReference entityReference, String action, String queryString, String anchor,
4521    XWikiContext context)
4522    {
4523    // TODO: replace this API with a clean implementation of EntityResourceReferenceSerializer
4524   
4525    // Handle attachment URL
4526  2451 if (EntityType.ATTACHMENT.equals(entityReference.getType())) {
4527    // Get the full attachment reference
4528  1 AttachmentReference attachmentReference = getCurrentAttachmentResolver().resolve(entityReference);
4529  1 return getAttachmentURL(attachmentReference, action, queryString, context);
4530    }
4531   
4532    // For all other types, we return the URL of the default corresponding document.
4533  2450 DocumentReference documentReference = getCurrentGetDocumentResolver().resolve(entityReference);
4534  2451 return getURL(documentReference, action, queryString, anchor, context);
4535    }
4536   
4537    /**
4538    * @since 7.2M1
4539    */
 
4540  2424 toggle public String getURL(EntityReference reference, String action, XWikiContext context)
4541    {
4542  2424 return getURL(reference, action, null, null, context);
4543    }
4544   
4545    /**
4546    * @since 7.2RC1
4547    */
 
4548  2425 toggle public String getURL(EntityReference reference, XWikiContext context)
4549    {
4550  2425 String action = "view";
4551  2425 if (reference.getType() == EntityType.ATTACHMENT) {
4552  1 action = "download";
4553    }
4554  2425 return getURL(reference, action, context);
4555    }
4556   
4557    /**
4558    * @since 2.2.1
4559    */
 
4560  43998 toggle public String getURL(DocumentReference documentReference, String action, String queryString, String anchor,
4561    XWikiContext context)
4562    {
4563    // We need to serialize the space reference because the old createURL() API doesn't accept a DocumentReference.
4564  43996 String spaces = getLocalStringEntityReferenceSerializer().serialize(documentReference.getLastSpaceReference());
4565   
4566    // Take into account the specified document locale.
4567  43997 Locale documentLocale = documentReference.getLocale();
4568  43998 String actualQueryString = queryString;
4569  43996 if (documentLocale != null && documentLocale != Locale.ROOT) {
4570  91 String localeQueryString = "language=" + documentLocale;
4571  91 if (StringUtils.isEmpty(queryString)) {
4572  90 actualQueryString = localeQueryString;
4573    } else {
4574    // Note: if the locale is already specified on the given query string then it won't be overwriten
4575    // because the first parameter value is taken into account.
4576  1 actualQueryString += '&' + localeQueryString;
4577    }
4578    }
4579   
4580  43998 URL url = context.getURLFactory().createURL(spaces, documentReference.getName(), action, actualQueryString,
4581    anchor, documentReference.getWikiReference().getName(), context);
4582   
4583  43998 return context.getURLFactory().getURL(url, context);
4584    }
4585   
4586    /**
4587    * @deprecated since 2.2.1 use {@link #getURL(DocumentReference, String, String, String, XWikiContext)}
4588    */
 
4589  9977 toggle @Deprecated
4590    public String getURL(String fullname, String action, String queryString, String anchor, XWikiContext context)
4591    {
4592  9977 return getURL(getCurrentMixedDocumentReferenceResolver().resolve(fullname), action, queryString, anchor,
4593    context);
4594    }
4595   
 
4596  5546 toggle public String getURL(String fullname, String action, String querystring, XWikiContext context)
4597    {
4598  5547 return getURL(fullname, action, querystring, null, context);
4599    }
4600   
4601    /**
4602    * @since 2.3M2
4603    */
 
4604  12250 toggle public String getURL(DocumentReference reference, String action, XWikiContext context)
4605    {
4606  12248 return getURL(reference, action, null, null, context);
4607    }
4608   
4609    /**
4610    * @deprecated since 2.3M2 use {@link #getURL(DocumentReference, String, XWikiContext)}
4611    */
 
4612  4430 toggle @Deprecated
4613    public String getURL(String fullname, String action, XWikiContext context)
4614    {
4615  4430 return getURL(fullname, action, null, null, context);
4616    }
4617   
 
4618  0 toggle public String getExternalURL(String fullname, String action, XWikiContext context) throws XWikiException
4619    {
4620  0 XWikiDocument doc = new XWikiDocument(getCurrentMixedDocumentReferenceResolver().resolve(fullname));
4621   
4622  0 URL url = context.getURLFactory().createExternalURL(doc.getSpace(), doc.getName(), action, null, null,
4623    doc.getDatabase(), context);
4624  0 return url.toString();
4625    }
4626   
 
4627  0 toggle public String getExternalURL(String fullname, String action, String querystring, XWikiContext context)
4628    throws XWikiException
4629    {
4630  0 XWikiDocument doc = new XWikiDocument(getCurrentMixedDocumentReferenceResolver().resolve(fullname));
4631   
4632  0 URL url = context.getURLFactory().createExternalURL(doc.getSpace(), doc.getName(), action, querystring, null,
4633    doc.getDatabase(), context);
4634  0 return url.toString();
4635    }
4636   
4637    /**
4638    * @since 7.2M1
4639    */
 
4640  317 toggle public String getAttachmentURL(AttachmentReference attachmentReference, String action, String queryString,
4641    XWikiContext context)
4642    {
4643  317 DocumentReference documentReference = attachmentReference.getDocumentReference();
4644  317 SpaceReference spaceReference = documentReference.getLastSpaceReference();
4645  317 WikiReference wikiReference = spaceReference.getWikiReference();
4646   
4647    // We need to serialize the space reference because the old URLFactory has no method to create an Attachment URL
4648    // from an AttachmentReference...
4649  317 String serializedSpace = getLocalStringEntityReferenceSerializer().serialize(spaceReference);
4650   
4651  317 URL url = context.getURLFactory().createAttachmentURL(attachmentReference.getName(), serializedSpace,
4652    documentReference.getName(), action, queryString, wikiReference.getName(), context);
4653   
4654  317 return context.getURLFactory().getURL(url, context);
4655    }
4656   
4657    /**
4658    * @since 7.2M1
4659    */
 
4660  280 toggle public String getAttachmentURL(AttachmentReference attachmentReference, String queryString, XWikiContext context)
4661    {
4662  280 return getAttachmentURL(attachmentReference, "download", queryString, context);
4663    }
4664   
4665    /**
4666    * @since 7.2M1
4667    */
 
4668  0 toggle public String getAttachmentRevisionURL(AttachmentReference attachmentReference, String revision, String queryString,
4669    XWikiContext context)
4670    {
4671  0 DocumentReference documentReference = attachmentReference.getDocumentReference();
4672  0 SpaceReference spaceReference = documentReference.getLastSpaceReference();
4673  0 WikiReference wikiReference = spaceReference.getWikiReference();
4674   
4675    // We need to serialize the space reference because the old URLFactory has no method to create an Attachment URL
4676    // from an AttachmentReference...
4677  0 String serializedSpace = getLocalStringEntityReferenceSerializer().serialize(spaceReference);
4678   
4679  0 URL url = context.getURLFactory().createAttachmentRevisionURL(attachmentReference.getName(), serializedSpace,
4680    documentReference.getName(), revision, queryString, wikiReference.getName(), context);
4681   
4682  0 return context.getURLFactory().getURL(url, context);
4683    }
4684   
 
4685  4 toggle public String getAttachmentURL(String fullname, String filename, XWikiContext context) throws XWikiException
4686    {
4687  4 return getAttachmentURL(fullname, filename, null, context);
4688    }
4689   
4690    /**
4691    * @since 2.5RC1
4692    */
 
4693  280 toggle public String getAttachmentURL(String fullname, String filename, String queryString, XWikiContext context)
4694    throws XWikiException
4695    {
4696  280 AttachmentReference attachmentReference =
4697    new AttachmentReference(filename, getCurrentMixedDocumentReferenceResolver().resolve(fullname));
4698   
4699  280 return getAttachmentURL(attachmentReference, queryString, context);
4700    }
4701   
4702    // Usefull date functions
4703   
 
4704  0 toggle public int getTimeDelta(long time)
4705    {
4706  0 Date ctime = new Date();
4707  0 return (int) (ctime.getTime() - time);
4708    }
4709   
 
4710  22590 toggle public boolean isMultiLingual(XWikiContext context)
4711    {
4712  22568 return "1".equals(getXWikiPreference("multilingual", "0", context));
4713    }
4714   
 
4715  32 toggle public boolean isLDAP()
4716    {
4717  32 return "1".equals(getConfiguration().getProperty("xwiki.authentication.ldap"));
4718    }
4719   
 
4720  9499 toggle public int checkActive(XWikiContext context) throws XWikiException
4721    {
4722  9502 return checkActive(context.getUser(), context);
4723    }
4724   
 
4725  9504 toggle public int checkActive(String user, XWikiContext context) throws XWikiException
4726    {
4727  9505 int active = 1;
4728   
4729    // These users are necessarily active
4730  9508 if (user.equals(XWikiRightService.GUEST_USER_FULLNAME)
4731    || (user.equals(XWikiRightService.SUPERADMIN_USER_FULLNAME))) {
4732  6195 return active;
4733    }
4734   
4735  3311 String checkactivefield = getXWikiPreference("auth_active_check", context);
4736  3311 if (checkactivefield.equals("1")) {
4737  0 XWikiDocument userdoc = getDocument(user, context);
4738  0 active = userdoc.getIntValue("XWiki.XWikiUsers", "active");
4739    }
4740   
4741  3311 return active;
4742    }
4743   
4744    /**
4745    * @since 2.3M1
4746    */
 
4747  10252 toggle public DocumentReference getDocumentReference(XWikiRequest request, XWikiContext context)
4748    {
4749  10252 DocumentReference reference;
4750  10243 if (context.getMode() == XWikiContext.MODE_PORTLET) {
4751  0 if (request.getParameter("topic") != null) {
4752  0 reference = getCurrentMixedDocumentReferenceResolver().resolve(request.getParameter("topic"));
4753    } else {
4754    // Point to this wiki's home page
4755  0 reference = getDefaultDocumentReference().setWikiReference(new WikiReference(context.getWikiId()));
4756    }
4757  10237 } else if (context.getMode() == XWikiContext.MODE_XMLRPC) {
4758  0 reference = new DocumentReference(context.getWikiId(),
4759    context.getDoc().getDocumentReference().getLastSpaceReference().getName(),
4760    context.getDoc().getDocumentReference().getName());
4761    } else {
4762  10226 ResourceReference resourceReference = getResourceReferenceManager().getResourceReference();
4763  10240 if (resourceReference instanceof EntityResourceReference) {
4764  10236 EntityResourceReference entityResource = (EntityResourceReference) resourceReference;
4765  10223 String action = entityResource.getAction().getActionName();
4766  10242 if ((request.getParameter("topic") != null) && (action.equals("edit") || action.equals("inline"))) {
4767  0 reference = getCurrentMixedDocumentReferenceResolver().resolve(request.getParameter("topic"));
4768    } else {
4769  10235 reference = new DocumentReference(
4770    entityResource.getEntityReference().extractReference(EntityType.DOCUMENT));
4771    }
4772    } else {
4773    // TODO: Handle references not pointing to a document...
4774    // Big problem we don't have an Entity URL!
4775  0 throw new RuntimeException(
4776    String.format("Resource Reference [%s] isn't an Entity Resource Reference!", resourceReference));
4777    }
4778    }
4779   
4780  10240 return reference;
4781    }
4782   
4783    /**
4784    * Helper method, removes a predefined path segment (the context path or the servel path) from the start of the
4785    * requested URI and returns the remainder. This method is needed because special characters in the path can be
4786    * URL-encoded, depending on whether the request is forwarded through the request dispatcher or not, and also
4787    * depending on the client (some browsers encode -, while some don't).
4788    *
4789    * @param path the path, as taken from the requested URI
4790    * @param segment the segment to remove, as reported by the container
4791    * @return the path with the specified segment trimmed from its start
4792    */
 
4793  118 toggle public static String stripSegmentFromPath(String path, String segment)
4794    {
4795  118 if (!path.startsWith(segment)) {
4796    // The context path probably contains special characters that are encoded in the URL
4797  0 try {
4798  0 segment = URIUtil.encodePath(segment);
4799    } catch (URIException e) {
4800  0 LOGGER.warn("Invalid path: [" + segment + "]");
4801    }
4802    }
4803  118 if (!path.startsWith(segment)) {
4804    // Some clients also encode -, although it's allowed in the path
4805  0 segment = segment.replaceAll("-", "%2D");
4806    }
4807  118 if (!path.startsWith(segment)) {
4808    // Can't find the context path in the URL (shouldn't happen), just skip to the next path segment
4809  0 return path.substring(path.indexOf('/', 1));
4810    }
4811  118 return path.substring(segment.length());
4812    }
4813   
 
4814  9516 toggle public boolean prepareDocuments(XWikiRequest request, XWikiContext context, VelocityContext vcontext)
4815    throws XWikiException
4816    {
4817  9516 XWikiDocument doc;
4818  9514 context.getWiki().prepareResources(context);
4819  9513 DocumentReference reference = getDocumentReference(request, context);
4820  9503 if (context.getAction().equals("register")) {
4821  163 setPhonyDocument(reference, context, vcontext);
4822  163 doc = context.getDoc();
4823    } else {
4824  9342 try {
4825  9321 doc = getDocument(reference, context);
4826    } catch (XWikiException e) {
4827  0 doc = context.getDoc();
4828  0 if (context.getAction().equals("delete")) {
4829  0 if (doc == null) {
4830  0 setPhonyDocument(reference, context, vcontext);
4831  0 doc = context.getDoc();
4832    }
4833  0 if (!checkAccess("admin", doc, context)) {
4834  0 throw e;
4835    }
4836    } else {
4837  0 throw e;
4838    }
4839    }
4840    }
4841   
4842    // We need to check rights before we look for translations
4843    // Otherwise we don't have the user language
4844  9509 if (checkAccess(context.getAction(), doc, context) == false) {
4845  5 Object[] args = { doc.getFullName(), context.getUser() };
4846  5 setPhonyDocument(reference, context, vcontext);
4847  5 throw new XWikiException(XWikiException.MODULE_XWIKI_ACCESS, XWikiException.ERROR_XWIKI_ACCESS_DENIED,
4848    "Access to document {0} has been denied to user {1}", null, args);
4849  9507 } else if (checkActive(context) == 0) { // if auth_active_check, check if user is inactive
4850  0 boolean allow = false;
4851  0 String action = context.getAction();
4852    /*
4853    * Allow inactive users to see skins, ressources, SSX, JSX and downloads they could have seen as guest. The
4854    * rational behind this behaviour is that inactive users should be able to access the same UI that guests
4855    * are used to see, including custom icons, panels, and so on...
4856    */
4857  0 if ((action.equals("skin") && (doc.getSpace().equals("skins") || doc.getSpace().equals("resources")))
4858    || ((action.equals("skin") || action.equals("download") || action.equals("ssx") || action.equals("jsx"))
4859    && getRightService().hasAccessLevel("view", XWikiRightService.GUEST_USER_FULLNAME,
4860    doc.getPrefixedFullName(), context))
4861    || ((action.equals("view") && doc.getFullName().equals("XWiki.AccountValidation")))) {
4862  0 allow = true;
4863    } else {
4864  0 String allowed = getConfiguration().getProperty("xwiki.inactiveuser.allowedpages", "");
4865  0 if (context.getAction().equals("view") && !allowed.equals("")) {
4866  0 String[] allowedList = StringUtils.split(allowed, " ,");
4867  0 for (String element : allowedList) {
4868  0 if (element.equals(doc.getFullName())) {
4869  0 allow = true;
4870  0 break;
4871    }
4872    }
4873    }
4874    }
4875  0 if (!allow) {
4876  0 Object[] args = { context.getUser() };
4877  0 setPhonyDocument(reference, context, vcontext);
4878  0 throw new XWikiException(XWikiException.MODULE_XWIKI_USER, XWikiException.ERROR_XWIKI_USER_INACTIVE,
4879    "User {0} account is inactive", null, args);
4880    }
4881    }
4882   
4883  9509 context.put("doc", doc);
4884  9506 context.put("cdoc", doc);
4885  9510 vcontext.put("doc", doc.newDocument(context));
4886  9498 vcontext.put("cdoc", vcontext.get("doc"));
4887  9503 XWikiDocument tdoc = doc.getTranslatedDocument(context);
4888  9508 try {
4889  9510 String rev = (String) context.get("rev");
4890  9501 if (StringUtils.isNotEmpty(rev)) {
4891  0 tdoc = getDocument(tdoc, rev, context);
4892    }
4893    } catch (Exception ex) {
4894    // Invalid version, just use the most recent one
4895    }
4896  9501 context.put("tdoc", tdoc);
4897  9508 vcontext.put("tdoc", tdoc.newDocument(context));
4898   
4899  9510 return true;
4900    }
4901   
4902    /**
4903    * @since 8.3M1
4904    */
 
4905  168 toggle public void setPhonyDocument(DocumentReference reference, XWikiContext context)
4906    {
4907  168 XWikiDocument doc = new XWikiDocument(reference);
4908  168 doc.setElements(XWikiDocument.HAS_ATTACHMENTS | XWikiDocument.HAS_OBJECTS);
4909  168 doc.setStore(getStore());
4910  168 context.put("doc", doc);
4911    }
4912   
4913    /**
4914    * @since 2.3M1
4915    * @deprecated since 8.3M1, use {@link #setPhonyDocument(DocumentReference, XWikiContext)} instead
4916    */
 
4917  168 toggle @Deprecated
4918    public void setPhonyDocument(DocumentReference reference, XWikiContext context, VelocityContext vcontext)
4919    {
4920  168 setPhonyDocument(reference, context);
4921   
4922  168 vcontext.put("doc", context.getDoc().newDocument(context));
4923  168 vcontext.put("cdoc", vcontext.get("doc"));
4924  168 vcontext.put("tdoc", vcontext.get("doc"));
4925    }
4926   
4927    /**
4928    * @deprecated since 2.3M1 use {@link #setPhonyDocument(DocumentReference, XWikiContext, VelocityContext)}
4929    */
 
4930  0 toggle @Deprecated
4931    public void setPhonyDocument(String docName, XWikiContext context, VelocityContext vcontext)
4932    {
4933  0 setPhonyDocument(getCurrentMixedDocumentReferenceResolver().resolve(docName), context, vcontext);
4934    }
4935   
 
4936  89991 toggle public XWikiEngineContext getEngineContext()
4937    {
4938  89994 return this.engine_context;
4939    }
4940   
 
4941  87 toggle public void setEngineContext(XWikiEngineContext engine_context)
4942    {
4943  87 this.engine_context = engine_context;
4944    }
4945   
 
4946  1 toggle public void setAuthService(XWikiAuthService authService)
4947    {
4948  1 this.authService = authService;
4949    }
4950   
 
4951  20 toggle public void setRightService(XWikiRightService rightService)
4952    {
4953  20 this.rightService = rightService;
4954    }
4955   
 
4956  230 toggle public XWikiGroupService getGroupService(XWikiContext context) throws XWikiException
4957    {
4958  230 synchronized (this.GROUP_SERVICE_LOCK) {
4959  230 if (this.groupService == null) {
4960  50 String groupClass = getConfiguration().getProperty("xwiki.authentication.groupclass",
4961    "com.xpn.xwiki.user.impl.xwiki.XWikiGroupServiceImpl");
4962   
4963  50 try {
4964  50 this.groupService = (XWikiGroupService) Class.forName(groupClass).newInstance();
4965    } catch (Exception e) {
4966  0 LOGGER.error("Failed to instantiate custom group service class: " + e.getMessage(), e);
4967  0 this.groupService = new XWikiGroupServiceImpl();
4968    }
4969  50 this.groupService.init(this, context);
4970    }
4971   
4972  230 return this.groupService;
4973    }
4974    }
4975   
 
4976  0 toggle public void setGroupService(XWikiGroupService groupService)
4977    {
4978  0 this.groupService = groupService;
4979    }
4980   
4981    // added some log statements to make debugging easier - LBlaze 2005.06.02
 
4982  21823 toggle public XWikiAuthService getAuthService()
4983    {
4984  21826 synchronized (this.AUTH_SERVICE_LOCK) {
4985  21834 if (this.authService == null) {
4986   
4987  32 LOGGER.info("Initializing AuthService...");
4988   
4989  32 String authClass = getConfiguration().getProperty("xwiki.authentication.authclass");
4990  32 if (StringUtils.isNotEmpty(authClass)) {
4991  0 if (LOGGER.isDebugEnabled()) {
4992  0 LOGGER.debug("Using custom AuthClass " + authClass + ".");
4993    }
4994    } else {
4995  32 if (isLDAP()) {
4996  0 authClass = "com.xpn.xwiki.user.impl.LDAP.XWikiLDAPAuthServiceImpl";
4997    } else {
4998  32 authClass = "com.xpn.xwiki.user.impl.xwiki.XWikiAuthServiceImpl";
4999    }
5000   
5001  32 if (LOGGER.isDebugEnabled()) {
5002  0 LOGGER.debug("Using default AuthClass " + authClass + ".");
5003    }
5004    }
5005   
5006  32 try {
5007    // Get the current ClassLoader
5008  32 @SuppressWarnings("deprecation")
5009    ClassLoaderManager clManager = Utils.getComponent(ClassLoaderManager.class);
5010  32 ClassLoader classloader = null;
5011  32 if (clManager != null) {
5012  32 classloader = clManager.getURLClassLoader("wiki:xwiki", false);
5013    }
5014   
5015    // Get the class
5016  32 if (classloader != null) {
5017  32 this.authService = (XWikiAuthService) Class.forName(authClass, true, classloader).newInstance();
5018    } else {
5019  0 this.authService = (XWikiAuthService) Class.forName(authClass).newInstance();
5020    }
5021   
5022  32 LOGGER.debug("Initialized AuthService using Relfection.");
5023    } catch (Exception e) {
5024  0 LOGGER.warn("Failed to initialize AuthService " + authClass
5025    + " using Reflection, trying default implementations using 'new'.", e);
5026   
5027  0 this.authService = new XWikiAuthServiceImpl();
5028   
5029  0 if (LOGGER.isDebugEnabled()) {
5030  0 LOGGER.debug(
5031    "Initialized AuthService " + this.authService.getClass().getName() + " using 'new'.");
5032    }
5033    }
5034    }
5035   
5036  21834 return this.authService;
5037    }
5038    }
5039   
5040    private static final String DEFAULT_RIGHT_SERVICE_CLASS =
5041    "org.xwiki.security.authorization.internal.XWikiCachingRightService";
5042   
 
5043  67854 toggle public XWikiRightService getRightService()
5044    {
5045  67851 synchronized (this.RIGHT_SERVICE_LOCK) {
5046  67858 if (this.rightService == null) {
5047  59 LOGGER.info("Initializing RightService...");
5048   
5049  59 String rightsClass = getConfiguration().getProperty("xwiki.authentication.rightsclass");
5050  59 if (rightsClass != null && !rightsClass.equals(DEFAULT_RIGHT_SERVICE_CLASS)) {
5051  0 if (LOGGER.isDebugEnabled()) {
5052  0 LOGGER.warn("Using custom Right Service [{}].", rightsClass);
5053    }
5054    } else {
5055  59 rightsClass = DEFAULT_RIGHT_SERVICE_CLASS;
5056  59 if (LOGGER.isDebugEnabled()) {
5057  0 LOGGER.debug("Using default Right Service [{}].", rightsClass);
5058    }
5059    }
5060   
5061  59 try {
5062  59 this.rightService = (XWikiRightService) Class.forName(rightsClass).newInstance();
5063  59 LOGGER.debug("Initialized RightService using Reflection.");
5064    } catch (Exception e) {
5065  0 Exception lastException = e;
5066   
5067  0 if (!rightsClass.equals(DEFAULT_RIGHT_SERVICE_CLASS)) {
5068  0 LOGGER.warn(String.format(
5069    "Failed to initialize custom RightService [%s]"
5070    + " by Reflection, using default implementation [%s].",
5071    rightsClass, DEFAULT_RIGHT_SERVICE_CLASS), e);
5072  0 rightsClass = DEFAULT_RIGHT_SERVICE_CLASS;
5073  0 try {
5074  0 this.rightService = (XWikiRightService) Class.forName(rightsClass).newInstance();
5075  0 LOGGER.debug("Initialized default RightService using Reflection.");
5076    } catch (Exception e1) {
5077  0 lastException = e1;
5078    }
5079    }
5080   
5081  0 if (this.rightService == null) {
5082  0 LOGGER.warn(String.format(
5083    "Failed to initialize RightService [%s]"
5084    + " by Reflection, using OLD implementation [%s] with 'new'.",
5085    rightsClass, XWikiRightServiceImpl.class.getCanonicalName()), lastException);
5086   
5087  0 this.rightService = new XWikiRightServiceImpl();
5088   
5089  0 if (LOGGER.isDebugEnabled()) {
5090  0 LOGGER.debug("Initialized old RightService implementation "
5091    + this.rightService.getClass().getName() + " using 'new'.");
5092    }
5093    }
5094    }
5095    }
5096  67858 return this.rightService;
5097    }
5098    }
5099   
 
5100  60 toggle public XWikiStatsService getStatsService(XWikiContext context)
5101    {
5102  60 synchronized (this.STATS_SERVICE_LOCK) {
5103  60 if (this.statsService == null) {
5104  60 if ("1".equals(getConfiguration().getProperty("xwiki.stats", "1"))) {
5105  60 String storeClass = getConfiguration().getProperty("xwiki.stats.class",
5106    "com.xpn.xwiki.stats.impl.XWikiStatsServiceImpl");
5107  60 try {
5108  60 this.statsService = (XWikiStatsService) Class.forName(storeClass).newInstance();
5109    } catch (Exception e) {
5110  0 LOGGER.error(e.getMessage(), e);
5111   
5112  0 this.statsService = new XWikiStatsServiceImpl();
5113    }
5114   
5115  60 this.statsService.init(context);
5116    }
5117    }
5118   
5119  60 return this.statsService;
5120    }
5121    }
5122   
 
5123  11610 toggle public XWikiURLFactoryService getURLFactoryService()
5124    {
5125  11600 if (this.urlFactoryService == null) {
5126  87 synchronized (this.URLFACTORY_SERVICE_LOCK) {
5127  87 if (this.urlFactoryService == null) {
5128  87 LOGGER.info("Initializing URLFactory Service...");
5129   
5130  87 XWikiURLFactoryService factoryService = null;
5131   
5132  87 String urlFactoryServiceClass = getConfiguration().getProperty("xwiki.urlfactory.serviceclass");
5133  87 if (urlFactoryServiceClass != null) {
5134  0 try {
5135  0 if (LOGGER.isDebugEnabled()) {
5136  0 LOGGER.debug("Using custom URLFactory Service Class [" + urlFactoryServiceClass + "]");
5137    }
5138  0 factoryService = (XWikiURLFactoryService) Class.forName(urlFactoryServiceClass)
5139    .getConstructor(new Class<?>[] { XWiki.class }).newInstance(new Object[] { this });
5140    } catch (Exception e) {
5141  0 factoryService = null;
5142  0 LOGGER.warn("Failed to initialize URLFactory Service [" + urlFactoryServiceClass + "]", e);
5143    }
5144    }
5145  87 if (factoryService == null) {
5146  87 if (LOGGER.isDebugEnabled()) {
5147  0 LOGGER.debug("Using default URLFactory Service Class [" + urlFactoryServiceClass + "]");
5148    }
5149  87 factoryService = new XWikiURLFactoryServiceImpl(this);
5150    }
5151   
5152    // Set the urlFactoryService object in one assignment to prevent threading
5153    // issues when checking for
5154    // null above.
5155  87 this.urlFactoryService = factoryService;
5156    }
5157    }
5158    }
5159   
5160  11610 return this.urlFactoryService;
5161    }
5162   
 
5163  14 toggle public XWikiCriteriaService getCriteriaService(XWikiContext context)
5164    {
5165  14 return this.criteriaService;
5166    }
5167   
 
5168  0 toggle public ZipOutputStream getZipOutputStream(XWikiContext context) throws IOException
5169    {
5170  0 return new ZipOutputStream(context.getResponse().getOutputStream());
5171    }
5172   
 
5173  0 toggle private Map<String, SearchEngineRule> getSearchEngineRules(XWikiContext context)
5174    {
5175    // We currently hardcode the rules
5176    // We will put them in the preferences soon
5177  0 Map<String, SearchEngineRule> map = new HashMap<String, SearchEngineRule>();
5178  0 map.put("Google", new SearchEngineRule("google.", "s/(^|.*&)q=(.*?)(&.*|$)/$2/"));
5179  0 map.put("MSN", new SearchEngineRule("search.msn.", "s/(^|.*&)q=(.*?)(&.*|$)/$2/"));
5180  0 map.put("Yahoo", new SearchEngineRule("search.yahoo.", "s/(^|.*&)p=(.*?)(&.*|$)/$2/"));
5181  0 map.put("Voila", new SearchEngineRule("voila.fr", "s/(^|.*&)kw=(.*?)(&.*|$)/$2/"));
5182   
5183  0 return map;
5184    }
5185   
 
5186  0 toggle public String getRefererText(String referer, XWikiContext context)
5187    {
5188  0 try {
5189  0 URL url = new URL(referer);
5190  0 Map<String, SearchEngineRule> searchengines = getSearchEngineRules(context);
5191  0 if (searchengines != null) {
5192  0 for (SearchEngineRule senginerule : searchengines.values()) {
5193  0 String host = url.getHost();
5194  0 int i1 = host.indexOf(senginerule.getHost());
5195  0 if (i1 != -1) {
5196  0 String query = context.getUtil().substitute(senginerule.getRegEx(), url.getQuery());
5197  0 if ((query != null) && (!query.equals(""))) {
5198    // We return the query text instead of the full referer
5199  0 return host.substring(i1) + ":" + query;
5200    }
5201    }
5202    }
5203    }
5204    } catch (Exception e) {
5205    }
5206   
5207  0 String result = referer.substring(referer.indexOf("://") + 3);
5208  0 if (result.endsWith("/")) {
5209  0 return result.substring(0, result.length() - 1);
5210    } else {
5211  0 return result;
5212    }
5213    }
5214   
 
5215  0 toggle public boolean isMySQL()
5216    {
5217  0 if (getHibernateStore() == null) {
5218  0 return false;
5219    }
5220   
5221  0 Object dialect = getHibernateStore().getConfiguration().getProperties().get("dialect");
5222  0 return "org.hibernate.dialect.MySQLDialect".equals(dialect)
5223    || "net.sf.hibernate.dialect.MySQLDialect".equals(dialect);
5224    }
5225   
 
5226  0 toggle public String getFullNameSQL()
5227    {
5228  0 return getFullNameSQL(true);
5229    }
5230   
 
5231  0 toggle public String getFullNameSQL(boolean newFullName)
5232    {
5233  0 if (newFullName) {
5234  0 return "doc.fullName";
5235    }
5236   
5237  0 if (this.fullNameSQL == null) {
5238  0 if (isMySQL()) {
5239  0 this.fullNameSQL = "CONCAT(doc.space,'.',doc.name)";
5240    } else {
5241  0 this.fullNameSQL = "doc.space||'.'||doc.name";
5242    }
5243    }
5244   
5245  0 return this.fullNameSQL;
5246    }
5247   
 
5248  0 toggle public String getUserName(String user, XWikiContext context)
5249    {
5250  0 return getUserName(user, null, true, context);
5251    }
5252   
 
5253  1157 toggle public String getUserName(String user, String format, XWikiContext context)
5254    {
5255  1157 return getUserName(user, format, true, context);
5256    }
5257   
5258    /**
5259    * @return a formatted and pretty printed user name for displaying
5260    */
 
5261  5443 toggle public String getUserName(String user, String format, boolean link, XWikiContext context)
5262    {
5263  5441 if (StringUtils.isBlank(user)) {
5264  0 return localizePlainOrKey("core.users.unknownUser");
5265    }
5266   
5267  5442 DocumentReference userReference = getCurrentMixedDocumentReferenceResolver().resolve(user);
5268   
5269  5443 return getUserName(userReference, format, link, true, context);
5270    }
5271   
5272    /**
5273    * Generate a display user name and return it.
5274    *
5275    * @param userReference
5276    * @param format a Velocity scnippet used to format the user name
5277    * @param link true if a full html link snippet should be returned
5278    * @param escapeXML true if the returned name should be escaped (forced true if {@code link} is true)
5279    * @param context see {@link XWikiContext}
5280    * @return the display user name or a html snippet with the link to the passed user
5281    * @since 6.4RC1
5282    */
 
5283  7615 toggle public String getUserName(DocumentReference userReference, String format, boolean link, boolean escapeXML,
5284    XWikiContext context)
5285    {
5286  7616 if (userReference == null) {
5287  94 return localizePlainOrKey("core.users.unknownUser");
5288    }
5289   
5290  7520 XWikiDocument userdoc = null;
5291  7521 try {
5292  7522 userdoc = getDocument(userReference, context);
5293  7522 if (userdoc == null) {
5294  0 return escapeXML ? XMLUtils.escape(userReference.getName()) : userReference.getName();
5295    }
5296   
5297  7522 BaseObject userobj = userdoc.getObject("XWiki.XWikiUsers");
5298  7522 if (userobj == null) {
5299  6167 return escapeXML ? XMLUtils.escape(userdoc.getDocumentReference().getName())
5300    : userdoc.getDocumentReference().getName();
5301    }
5302   
5303  1355 String text;
5304   
5305  1355 if (format == null) {
5306  1355 text = userobj.getStringValue("first_name");
5307  1355 String lastName = userobj.getStringValue("last_name");
5308  1355 if (!text.isEmpty() && !lastName.isEmpty()) {
5309  239 text += ' ';
5310    }
5311  1355 text += userobj.getStringValue("last_name");
5312  1355 if (StringUtils.isBlank(text)) {
5313  1114 text = userdoc.getDocumentReference().getName();
5314    }
5315    } else {
5316  0 VelocityContext vcontext = new VelocityContext();
5317  0 for (String propname : userobj.getPropertyList()) {
5318  0 vcontext.put(propname, userobj.getStringValue(propname));
5319    }
5320  0 text = evaluateVelocity(format,
5321    "<username formatting code in " + context.getDoc().getDocumentReference() + ">", vcontext);
5322    }
5323   
5324  1355 if (escapeXML || link) {
5325  1274 text = XMLUtils.escape(text.trim());
5326    }
5327   
5328  1355 if (link) {
5329  275 text = "<span class=\"wikilink\"><a href=\"" + userdoc.getURL("view", context) + "\">" + text
5330    + "</a></span>";
5331    }
5332  1355 return text;
5333    } catch (Exception e) {
5334  0 LOGGER.warn("Failed to display the user name of [{}]. Root cause is [{}]. Falling back on the user id.",
5335    userReference, ExceptionUtils.getRootCauseMessage(e));
5336   
5337  0 return escapeXML ? XMLUtils.escape(userReference.getName()) : userReference.getName();
5338    }
5339    }
5340   
5341    /**
5342    * @param content the Velocity content to evaluate
5343    * @param namespace the namespace under which to evaluate it (used for isolation)
5344    * @param vcontext the Velocity context to use when evaluating. If {@code null}, then a new context will be created,
5345    * initialized and used.
5346    * @return the evaluated content
5347    * @since 7.2M1
5348    */
 
5349  997 toggle public String evaluateVelocity(String content, String namespace, VelocityContext vcontext)
5350    {
5351  998 StringWriter writer = new StringWriter();
5352   
5353  993 boolean renderingContextPushed = false;
5354  992 try {
5355    // Switch current namespace if needed
5356  994 String currentNamespace = getRenderingContext().getTransformationId();
5357  996 if (namespace != null && !StringUtils.equals(namespace, currentNamespace)) {
5358  994 if (getRenderingContext() instanceof MutableRenderingContext) {
5359    // Make the current velocity template id available
5360  993 ((MutableRenderingContext) getRenderingContext()).push(getRenderingContext().getTransformation(),
5361    getRenderingContext().getXDOM(), getRenderingContext().getDefaultSyntax(), namespace,
5362    getRenderingContext().isRestricted(), getRenderingContext().getTargetSyntax());
5363   
5364  1001 renderingContextPushed = true;
5365    }
5366    }
5367   
5368  999 VelocityManager velocityManager = Utils.getComponent(VelocityManager.class);
5369  1000 velocityManager.getVelocityEngine().evaluate(vcontext, writer, namespace, content);
5370   
5371  1001 return writer.toString();
5372    } catch (Exception e) {
5373  0 LOGGER.error("Error while parsing velocity template namespace [{}] with content:\n[{}]", namespace, content,
5374    e);
5375  0 Object[] args = { namespace };
5376  0 XWikiException xe = new XWikiException(XWikiException.MODULE_XWIKI_RENDERING,
5377    XWikiException.ERROR_XWIKI_RENDERING_VELOCITY_EXCEPTION, "Error while parsing velocity page {0}", e,
5378    args);
5379  0 return Util.getHTMLExceptionMessage(xe, null);
5380    } finally {
5381    // Get rid of temporary rendering context
5382  1001 if (renderingContextPushed) {
5383  1001 ((MutableRenderingContext) this.renderingContext).pop();
5384    }
5385    }
5386    }
5387   
5388    /**
5389    * @param content the Velocity content to evaluate
5390    * @param name the namespace under which to evaluate it (used for isolation)
5391    * @return the evaluated content
5392    * @since 7.2M1
5393    */
 
5394  1001 toggle public String evaluateVelocity(String content, String name)
5395    {
5396  1001 try {
5397  999 VelocityManager velocityManager = Utils.getComponent(VelocityManager.class);
5398  1000 VelocityContext velocityContext = velocityManager.getVelocityContext();
5399  996 return evaluateVelocity(content, name, velocityContext);
5400    } catch (Exception e) {
5401  0 LOGGER.error("Error while parsing velocity template namespace [{}] with content:\n[{}]", name, content, e);
5402  0 Object[] args = { name };
5403  0 XWikiException xe = new XWikiException(XWikiException.MODULE_XWIKI_RENDERING,
5404    XWikiException.ERROR_XWIKI_RENDERING_VELOCITY_EXCEPTION, "Error while parsing velocity page {0}", e,
5405    args);
5406  0 return Util.getHTMLExceptionMessage(xe, null);
5407    }
5408    }
5409   
5410    /**
5411    * Generate and return an unescaped user display name.
5412    *
5413    * @param userReference the user reference
5414    * @param context see {@link XWikiContext}
5415    * @return the unescaped display user name
5416    * @since 6.4RC1
5417    */
 
5418  2173 toggle public String getPlainUserName(DocumentReference userReference, XWikiContext context)
5419    {
5420  2173 return getUserName(userReference, null, false, false, context);
5421    }
5422   
 
5423  0 toggle public boolean hasCentralizedAuthentication(XWikiContext context)
5424    {
5425  0 String bl = getXWikiPreference("authentication_centralized", "", context);
5426  0 if ("1".equals(bl)) {
5427  0 return true;
5428    }
5429   
5430  0 if ("0".equals(bl)) {
5431  0 return false;
5432    }
5433   
5434  0 return "1".equals(getConfiguration().getProperty("xwiki.authentication.centralized", "0"));
5435    }
5436   
 
5437  0 toggle public String getLocalUserName(String user, XWikiContext context)
5438    {
5439  0 if (hasCentralizedAuthentication(context)) {
5440  0 return getUserName(user, null, true, context);
5441    } else {
5442  0 return getUserName(user.substring(user.indexOf(':') + 1), null, true, context);
5443    }
5444    }
5445   
 
5446  0 toggle public String getLocalUserName(String user, String format, XWikiContext context)
5447    {
5448  0 if (hasCentralizedAuthentication(context)) {
5449  0 return getUserName(user, format, true, context);
5450    } else {
5451  0 return getUserName(user.substring(user.indexOf(':') + 1), format, true, context);
5452    }
5453    }
5454   
 
5455  0 toggle public String getLocalUserName(String user, String format, boolean link, XWikiContext context)
5456    {
5457  0 if (hasCentralizedAuthentication(context)) {
5458  0 return getUserName(user, format, link, context);
5459    } else {
5460  0 return getUserName(user.substring(user.indexOf(':') + 1), format, link, context);
5461    }
5462    }
5463   
 
5464  1218 toggle public String formatDate(Date date, String format, XWikiContext context)
5465    {
5466  1218 if (date == null) {
5467  0 return "";
5468    }
5469  1218 String xformat = format;
5470  1218 String defaultFormat = "yyyy/MM/dd HH:mm";
5471   
5472  1218 if (format == null) {
5473  1042 xformat = getXWikiPreference("dateformat", defaultFormat, context);
5474    }
5475   
5476  1218 try {
5477  1218 DateFormatSymbols formatSymbols = null;
5478  1218 try {
5479  1218 String language = getLanguagePreference(context);
5480  1218 formatSymbols = new DateFormatSymbols(new Locale(language));
5481    } catch (Exception e2) {
5482  0 String language = getXWikiPreference("default_language", context);
5483  0 if ((language != null) && (!language.equals(""))) {
5484  0 formatSymbols = new DateFormatSymbols(new Locale(language));
5485    }
5486    }
5487   
5488  1218 SimpleDateFormat sdf;
5489  1218 if (formatSymbols != null) {
5490  1218 sdf = new SimpleDateFormat(xformat, formatSymbols);
5491    } else {
5492  0 sdf = new SimpleDateFormat(xformat);
5493    }
5494   
5495  1218 try {
5496  1218 sdf.setTimeZone(TimeZone.getTimeZone(getUserTimeZone(context)));
5497    } catch (Exception e) {
5498    }
5499   
5500  1218 return sdf.format(date);
5501    } catch (Exception e) {
5502  0 LOGGER.info("Failed to format date [" + date + "] with pattern [" + xformat + "]: " + e.getMessage());
5503  0 if (format == null) {
5504  0 if (xformat.equals(defaultFormat)) {
5505  0 return date.toString();
5506    } else {
5507  0 return formatDate(date, defaultFormat, context);
5508    }
5509    } else {
5510  0 return formatDate(date, null, context);
5511    }
5512    }
5513    }
5514   
5515    /*
5516    * Allow to read user setting providing the user timezone All dates will be expressed with this timezone
5517    */
 
5518  1218 toggle public String getUserTimeZone(XWikiContext context)
5519    {
5520  1218 String tz = getUserPreference("timezone", context);
5521    // We perform this verification ourselves since TimeZone#getTimeZone(String) with an invalid parameter returns
5522    // GMT and not the system default.
5523  1218 if (!ArrayUtils.contains(TimeZone.getAvailableIDs(), tz)) {
5524  1212 String defaultTz = TimeZone.getDefault().getID();
5525  1212 return getConfiguration().getProperty("xwiki.timezone", defaultTz);
5526    } else {
5527  6 return tz;
5528    }
5529    }
5530   
5531    /**
5532    * @deprecated since 2.2.1 use {@link #exists(DocumentReference, XWikiContext)}
5533    */
 
5534  37367 toggle @Deprecated
5535    public boolean exists(String fullname, XWikiContext context)
5536    {
5537  37367 return exists(getCurrentMixedDocumentReferenceResolver().resolve(fullname), context);
5538    }
5539   
 
5540  54724 toggle public boolean exists(DocumentReference documentReference, XWikiContext context)
5541    {
5542  54723 String currentWiki = context.getWikiId();
5543   
5544  54722 try {
5545  54723 XWikiDocument doc = new XWikiDocument(documentReference, documentReference.getLocale());
5546   
5547  54724 context.setWikiId(documentReference.getWikiReference().getName());
5548   
5549  54725 return getStore().exists(doc, context);
5550    } catch (XWikiException e) {
5551  0 return false;
5552    } finally {
5553  54725 context.setWikiId(currentWiki);
5554    }
5555    }
5556   
 
5557  0 toggle public String getAdType(XWikiContext context)
5558    {
5559  0 String adtype = "";
5560  0 XWikiDocument wikiServer = context.getWikiServer();
5561  0 if (wikiServer != null) {
5562  0 adtype = wikiServer.getStringValue(VIRTUAL_WIKI_DEFINITION_CLASS_REFERENCE, "adtype");
5563    }
5564   
5565  0 if (adtype.equals("")) {
5566  0 adtype = getConfiguration().getProperty("xwiki.ad.type", "");
5567    }
5568   
5569  0 return adtype;
5570    }
5571   
 
5572  0 toggle public String getAdClientId(XWikiContext context)
5573    {
5574  0 final String defaultadclientid = "pub-2778691407285481";
5575  0 String adclientid = "";
5576  0 XWikiDocument wikiServer = context.getWikiServer();
5577  0 if (wikiServer != null) {
5578  0 adclientid = wikiServer.getStringValue(VIRTUAL_WIKI_DEFINITION_CLASS_REFERENCE, "adclientid");
5579    }
5580   
5581  0 if (adclientid.equals("")) {
5582  0 adclientid = getConfiguration().getProperty("xwiki.ad.clientid", "");
5583    }
5584   
5585  0 if (adclientid.equals("")) {
5586  0 adclientid = defaultadclientid;
5587    }
5588   
5589  0 return adclientid;
5590    }
5591   
 
5592  85418 toggle @Deprecated
5593    public XWikiPluginInterface getPlugin(String name, XWikiContext context)
5594    {
5595  85405 XWikiPluginManager plugins = getPluginManager();
5596  85381 Vector<String> pluginlist = plugins.getPlugins();
5597  78475 for (String pluginname : pluginlist) {
5598  247758 if (pluginname.equals(name)) {
5599  21955 return plugins.getPlugin(pluginname);
5600    }
5601    }
5602   
5603  56539 return null;
5604    }
5605   
 
5606  23875 toggle @Deprecated
5607    public Api getPluginApi(String name, XWikiContext context)
5608    {
5609  23875 XWikiPluginInterface plugin = getPlugin(name, context);
5610  23875 if (plugin != null) {
5611  21953 return plugin.getPluginApi(plugin, context);
5612    }
5613   
5614  1922 return null;
5615    }
5616   
 
5617  0 toggle public int getHttpTimeout(XWikiContext context)
5618    {
5619  0 return getConfiguration().getProperty("xwiki.http.timeout", 60000);
5620    }
5621   
 
5622  0 toggle public String getHttpUserAgent(XWikiContext context)
5623    {
5624  0 return getConfiguration().getProperty("xwiki.http.useragent", "XWikiBot/1.0");
5625    }
5626   
 
5627  0 toggle public String getURLContent(String surl, XWikiContext context) throws IOException
5628    {
5629  0 return getURLContent(surl, getHttpTimeout(context), getHttpUserAgent(context));
5630    }
5631   
 
5632  0 toggle public String getURLContent(String surl, int timeout, String userAgent) throws IOException
5633    {
5634  0 String content;
5635  0 HttpClient client = getHttpClient(timeout, userAgent);
5636  0 GetMethod get = new GetMethod(surl);
5637   
5638  0 try {
5639  0 client.executeMethod(get);
5640  0 content = get.getResponseBodyAsString();
5641    } finally {
5642    // Release any connection resources used by the method
5643  0 get.releaseConnection();
5644    }
5645   
5646  0 return content;
5647    }
5648   
 
5649  0 toggle public String getURLContent(String surl, String username, String password, XWikiContext context) throws IOException
5650    {
5651  0 return getURLContent(surl, username, password, getHttpTimeout(context), getHttpUserAgent(context));
5652    }
5653   
 
5654  0 toggle public String getURLContent(String surl, String username, String password, int timeout, String userAgent)
5655    throws IOException
5656    {
5657  0 HttpClient client = getHttpClient(timeout, userAgent);
5658   
5659    // pass our credentials to HttpClient, they will only be used for
5660    // authenticating to servers with realm "realm", to authenticate agains
5661    // an arbitrary realm change this to null.
5662  0 client.getState().setCredentials(new AuthScope(null, -1, null),
5663    new UsernamePasswordCredentials(username, password));
5664   
5665    // create a GET method that reads a file over HTTPS, we're assuming
5666    // that this file requires basic authentication using the realm above.
5667  0 GetMethod get = new GetMethod(surl);
5668   
5669  0 try {
5670    // Tell the GET method to automatically handle authentication. The
5671    // method will use any appropriate credentials to handle basic
5672    // authentication requests. Setting this value to false will cause
5673    // any request for authentication to return with a status of 401.
5674    // It will then be up to the client to handle the authentication.
5675  0 get.setDoAuthentication(true);
5676   
5677    // execute the GET
5678  0 client.executeMethod(get);
5679   
5680    // print the status and response
5681  0 return get.getResponseBodyAsString();
5682    } finally {
5683    // release any connection resources used by the method
5684  0 get.releaseConnection();
5685    }
5686    }
5687   
 
5688  0 toggle public byte[] getURLContentAsBytes(String surl, XWikiContext context) throws IOException
5689    {
5690  0 return getURLContentAsBytes(surl, getHttpTimeout(context), getHttpUserAgent(context));
5691    }
5692   
 
5693  0 toggle public byte[] getURLContentAsBytes(String surl, int timeout, String userAgent) throws IOException
5694    {
5695  0 HttpClient client = getHttpClient(timeout, userAgent);
5696   
5697    // create a GET method that reads a file over HTTPS, we're assuming
5698    // that this file requires basic authentication using the realm above.
5699  0 GetMethod get = new GetMethod(surl);
5700   
5701  0 try {
5702    // execute the GET
5703  0 client.executeMethod(get);
5704   
5705    // print the status and response
5706  0 return get.getResponseBody();
5707    } finally {
5708    // release any connection resources used by the method
5709  0 get.releaseConnection();
5710    }
5711    }
5712   
 
5713  0 toggle public byte[] getURLContentAsBytes(String surl, String username, String password, XWikiContext context)
5714    throws IOException
5715    {
5716  0 return getURLContentAsBytes(surl, username, password, getHttpTimeout(context), getHttpUserAgent(context));
5717    }
5718   
 
5719  0 toggle public byte[] getURLContentAsBytes(String surl, String username, String password, int timeout, String userAgent)
5720    throws IOException
5721    {
5722  0 HttpClient client = getHttpClient(timeout, userAgent);
5723   
5724    // pass our credentials to HttpClient, they will only be used for
5725    // authenticating to servers with realm "realm", to authenticate agains
5726    // an arbitrary realm change this to null.
5727  0 client.getState().setCredentials(new AuthScope(null, -1, null),
5728    new UsernamePasswordCredentials(username, password));
5729   
5730    // create a GET method that reads a file over HTTPS, we're assuming
5731    // that this file requires basic authentication using the realm above.
5732  0 GetMethod get = new GetMethod(surl);
5733   
5734  0 try {
5735    // Tell the GET method to automatically handle authentication. The
5736    // method will use any appropriate credentials to handle basic
5737    // authentication requests. Setting this value to false will cause
5738    // any request for authentication to return with a status of 401.
5739    // It will then be up to the client to handle the authentication.
5740  0 get.setDoAuthentication(true);
5741   
5742    // execute the GET
5743  0 client.executeMethod(get);
5744   
5745    // print the status and response
5746  0 return get.getResponseBody();
5747    } finally {
5748    // release any connection resources used by the method
5749  0 get.releaseConnection();
5750    }
5751    }
5752   
5753    /**
5754    * API to list all spaces in the current wiki.
5755    * <p>
5756    * Hidden spaces are filtered unless current user enabled them.
5757    *
5758    * @return a list of string representing all non-hidden spaces (ie spaces that have non-hidden pages) for the
5759    * current wiki
5760    * @throws XWikiException if something went wrong
5761    * @deprecated use query service instead
5762    */
 
5763  32 toggle @Deprecated
5764    public List<String> getSpaces(XWikiContext context) throws XWikiException
5765    {
5766  32 try {
5767  32 return getStore().getQueryManager().getNamedQuery("getSpaces")
5768    .addFilter(Utils.<QueryFilter>getComponent(QueryFilter.class, "hidden")).execute();
5769    } catch (QueryException ex) {
5770  0 throw new XWikiException(0, 0, ex.getMessage(), ex);
5771    }
5772    }
5773   
5774    /**
5775    * API to list all non-hidden documents in a space.
5776    *
5777    * @param spaceReference the local reference of the space for which to return all non-hidden documents
5778    * @return the list of document names (in the format {@code Space.Page}) for non-hidden documents in the specified
5779    * space
5780    * @throws XWikiException if the loading went wrong
5781    * @deprecated use query service instead
5782    */
 
5783  0 toggle @Deprecated
5784    public List<String> getSpaceDocsName(String spaceReference, XWikiContext context) throws XWikiException
5785    {
5786  0 try {
5787  0 return getStore().getQueryManager().getNamedQuery("getSpaceDocsName")
5788    .addFilter(Utils.<QueryFilter>getComponent(QueryFilter.class, "hidden"))
5789    .bindValue("space", spaceReference).execute();
5790    } catch (QueryException ex) {
5791  0 throw new XWikiException(0, 0, ex.getMessage(), ex);
5792    }
5793    }
5794   
 
5795  0 toggle public List<String> getIncludedMacros(String defaultSpace, String content, XWikiContext context)
5796    {
5797  0 List<String> list;
5798   
5799  0 try {
5800  0 String pattern = "#includeMacros[ ]*\\([ ]*([\"'])(.*?)\\1[ ]*\\)";
5801  0 list = context.getUtil().getUniqueMatches(content, pattern, 2);
5802  0 for (int i = 0; i < list.size(); i++) {
5803  0 String name = list.get(i);
5804  0 if (name.indexOf('.') == -1) {
5805  0 list.set(i, defaultSpace + "." + name);
5806    }
5807    }
5808    } catch (Exception e) {
5809    // This should never happen
5810  0 LOGGER.error("Failed to extract #includeMacros targets from provided content [" + content + "]", e);
5811   
5812  0 list = Collections.emptyList();
5813    }
5814   
5815  0 return list;
5816    }
5817   
5818    /**
5819    * accessor for the isReadOnly instance var.
5820    *
5821    * @see #isReadOnly
5822    */
 
5823  24046 toggle public boolean isReadOnly()
5824    {
5825  24046 return this.isReadOnly;
5826    }
5827   
 
5828  0 toggle public void setReadOnly(boolean readOnly)
5829    {
5830  0 this.isReadOnly = readOnly;
5831    }
5832   
 
5833  25 toggle public void deleteAllDocuments(XWikiDocument doc, XWikiContext context) throws XWikiException
5834    {
5835  25 deleteAllDocuments(doc, true, context);
5836    }
5837   
 
5838  26 toggle public void deleteAllDocuments(XWikiDocument doc, boolean toTrash, XWikiContext context) throws XWikiException
5839    {
5840    // Delete all translation documents
5841  26 for (Locale locale : doc.getTranslationLocales(context)) {
5842  0 XWikiDocument tdoc = doc.getTranslatedDocument(locale, context);
5843  0 deleteDocument(tdoc, toTrash, context);
5844    }
5845   
5846    // Delete the default document
5847  26 deleteDocument(doc, toTrash, context);
5848    }
5849   
 
5850  0 toggle public void refreshLinks(XWikiContext context) throws XWikiException
5851    {
5852  0 try {
5853    // refreshes all Links of each doc of the wiki
5854  0 @SuppressWarnings("deprecation")
5855    List<String> docs = getStore().getQueryManager().getNamedQuery("getAllDocuments")
5856    .addFilter(Utils.<QueryFilter>getComponent(QueryFilter.class, "hidden")).execute();
5857  0 for (int i = 0; i < docs.size(); i++) {
5858  0 XWikiDocument myDoc = this.getDocument(docs.get(i), context);
5859  0 myDoc.getStore().saveLinks(myDoc, context, true);
5860    }
5861    } catch (QueryException ex) {
5862  0 throw new XWikiException(0, 0, ex.getMessage(), ex);
5863    }
5864    }
5865   
 
5866  3958 toggle public boolean hasBacklinks(XWikiContext context)
5867    {
5868  3958 if (this.hasBacklinks == null) {
5869  60 this.hasBacklinks = "1".equals(getXWikiPreference("backlinks", "xwiki.backlinks", "0", context));
5870    }
5871  3958 return this.hasBacklinks;
5872    }
5873   
 
5874  0 toggle public boolean hasTags(XWikiContext context)
5875    {
5876  0 return "1".equals(getXWikiPreference("tags", "xwiki.tags", "0", context));
5877    }
5878   
 
5879  330 toggle public boolean hasCustomMappings()
5880    {
5881  330 return "1".equals(getConfiguration().getProperty("xwiki.store.hibernate.custommapping", "1"));
5882    }
5883   
 
5884  15031 toggle public boolean hasDynamicCustomMappings()
5885    {
5886  15032 return "1".equals(getConfiguration().getProperty("xwiki.store.hibernate.custommapping.dynamic", "0"));
5887    }
5888   
 
5889  36 toggle public String getDefaultSpace(XWikiContext context)
5890    {
5891  36 String defaultSpace = getXWikiPreference("defaultweb", "", context);
5892  36 if (StringUtils.isEmpty(defaultSpace)) {
5893  36 return getConfiguration().getProperty("xwiki.defaultweb", DEFAULT_HOME_SPACE);
5894    }
5895  0 return defaultSpace;
5896    }
5897   
 
5898  111220 toggle public boolean showViewAction(XWikiContext context)
5899    {
5900  111221 String bl = getXWikiPreference("showviewaction", "", context);
5901  111221 if ("1".equals(bl)) {
5902  0 return true;
5903  111221 } else if ("0".equals(bl)) {
5904  0 return false;
5905    }
5906   
5907  111221 return "1".equals(getConfiguration().getProperty("xwiki.showviewaction", "1"));
5908    }
5909   
 
5910  97961 toggle public boolean useDefaultAction(XWikiContext context)
5911    {
5912  97964 String bl = getXWikiPreference("usedefaultaction", "", context);
5913  97968 if ("1".equals(bl)) {
5914  0 return true;
5915    }
5916   
5917  97968 if ("0".equals(bl)) {
5918  0 return false;
5919    }
5920   
5921  97968 return "1".equals(getConfiguration().getProperty("xwiki.usedefaultaction", "0"));
5922    }
5923   
 
5924  98002 toggle public String getDefaultPage(XWikiContext context)
5925    {
5926  98002 String defaultPage = getXWikiPreference("defaultpage", "", context);
5927  98003 if (StringUtils.isEmpty(defaultPage)) {
5928  98002 return getConfiguration().getProperty("xwiki.defaultpage", DEFAULT_SPACE_HOMEPAGE);
5929    }
5930  0 return defaultPage;
5931    }
5932   
 
5933  118 toggle public boolean hasEditComment(XWikiContext context)
5934    {
5935  118 String bl = getXWikiPreference("editcomment", "", context);
5936  118 if ("1".equals(bl)) {
5937  0 return true;
5938    }
5939   
5940  118 if ("0".equals(bl)) {
5941  0 return false;
5942    }
5943   
5944  118 return "1".equals(getConfiguration().getProperty("xwiki.editcomment", "0"));
5945    }
5946   
 
5947  100 toggle public boolean isEditCommentFieldHidden(XWikiContext context)
5948    {
5949  100 String bl = getXWikiPreference("editcomment_hidden", "", context);
5950  100 if ("1".equals(bl)) {
5951  0 return true;
5952    }
5953   
5954  100 if ("0".equals(bl)) {
5955  0 return false;
5956    }
5957   
5958  100 return "1".equals(getConfiguration().getProperty("xwiki.editcomment.hidden", "0"));
5959    }
5960   
 
5961  34 toggle public boolean isEditCommentSuggested(XWikiContext context)
5962    {
5963  34 String bl = getXWikiPreference("editcomment_suggested", "", context);
5964  34 if ("1".equals(bl)) {
5965  0 return true;
5966    }
5967   
5968  34 if ("0".equals(bl)) {
5969  0 return false;
5970    }
5971   
5972  34 return "1".equals(getConfiguration().getProperty("xwiki.editcomment.suggested", "0"));
5973    }
5974   
 
5975  68 toggle public boolean isEditCommentMandatory(XWikiContext context)
5976    {
5977  68 String bl = getXWikiPreference("editcomment_mandatory", "", context);
5978  68 if ("1".equals(bl)) {
5979  0 return true;
5980    }
5981   
5982  68 if ("0".equals(bl)) {
5983  0 return false;
5984    }
5985   
5986  68 return "1".equals(getConfiguration().getProperty("xwiki.editcomment.mandatory", "0"));
5987    }
5988   
5989    /**
5990    * @see com.xpn.xwiki.api.XWiki#hasMinorEdit()
5991    */
 
5992  59 toggle public boolean hasMinorEdit(XWikiContext context)
5993    {
5994  59 String bl = getXWikiPreference("minoredit", "", context);
5995  59 if ("1".equals(bl)) {
5996  0 return true;
5997    }
5998   
5999  59 if ("0".equals(bl)) {
6000  0 return false;
6001    }
6002   
6003  59 return "1".equals(getConfiguration().getProperty("xwiki.minoredit", "1"));
6004    }
6005   
6006    /**
6007    * @see com.xpn.xwiki.api.XWiki#hasRecycleBin()
6008    * @param context see {@link XWikiContext}
6009    */
 
6010  569 toggle public boolean hasRecycleBin(XWikiContext context)
6011    {
6012  570 return "1".equals(getConfiguration().getProperty("xwiki.recyclebin", "1"));
6013    }
6014   
6015    /**
6016    * Indicates whether deleted attachments are stored in a recycle bin or not. This can be configured using the key
6017    * <var>storage.attachment.recyclebin</var>.
6018    *
6019    * @param context see {@link XWikiContext}
6020    */
 
6021  3987 toggle public boolean hasAttachmentRecycleBin(XWikiContext context)
6022    {
6023  3987 return "1".equals(getConfiguration().getProperty("storage.attachment.recyclebin", "1"));
6024    }
6025   
6026    /**
6027    * @deprecated use {@link XWikiDocument#rename(String, XWikiContext)} instead
6028    */
 
6029  0 toggle @Deprecated
6030    public XWikiDocument renamePage(XWikiDocument doc, String newFullName, XWikiContext context) throws XWikiException
6031    {
6032  0 if (context.getWiki().exists(newFullName, context)) {
6033  0 XWikiDocument delDoc = context.getWiki().getDocument(newFullName, context);
6034  0 context.getWiki().deleteDocument(delDoc, context);
6035    }
6036   
6037  0 XWikiDocument renamedDoc = doc.copyDocument(newFullName, context);
6038  0 saveDocument(renamedDoc, context);
6039  0 renamedDoc.saveAllAttachments(context);
6040  0 deleteDocument(doc, context);
6041   
6042  0 return renamedDoc;
6043    }
6044   
6045    /**
6046    * @deprecated use {@link XWikiDocument#rename(String, XWikiContext)} instead
6047    */
 
6048  0 toggle @Deprecated
6049    public XWikiDocument renamePage(XWikiDocument doc, XWikiContext context, String newFullName) throws XWikiException
6050    {
6051  0 return renamePage(doc, newFullName, context);
6052    }
6053   
6054    /**
6055    * @since 2.2M2
6056    */
 
6057  45895 toggle public BaseClass getXClass(DocumentReference documentReference, XWikiContext context) throws XWikiException
6058    {
6059    // Used to avoid recursive loading of documents if there are recursives usage of classes
6060  45895 BaseClass bclass = context.getBaseClass(documentReference);
6061  45885 if (bclass != null) {
6062  5005 return bclass;
6063    }
6064   
6065  40880 return getDocument(documentReference, context).getXClass();
6066    }
6067   
6068    /**
6069    * @deprecated since 2.2M2 use {@link #getXClass(DocumentReference, XWikiContext)}
6070    */
 
6071  275 toggle @Deprecated
6072    public BaseClass getClass(String fullName, XWikiContext context) throws XWikiException
6073    {
6074  275 DocumentReference reference = null;
6075  275 if (StringUtils.isNotEmpty(fullName)) {
6076  275 reference = getCurrentMixedDocumentReferenceResolver().resolve(fullName);
6077    }
6078  275 return getXClass(reference, context);
6079    }
6080   
 
6081  92 toggle public String getEditorPreference(XWikiContext context)
6082    {
6083  92 String defaultSyntaxContentEditor = getEditConfiguration().getDefaultEditor(SyntaxContent.class);
6084   
6085  92 return defaultSyntaxContentEditor == null ? "" : defaultSyntaxContentEditor.toLowerCase();
6086    }
6087   
6088    /**
6089    * Privileged API to retrieve an object instantiated from groovy code in a String. Note that Groovy scripts
6090    * compilation is cached.
6091    *
6092    * @param script the Groovy class definition string (public class MyClass { ... })
6093    * @return An object instantiating this class
6094    * @throws XWikiException
6095    */
 
6096  0 toggle public Object parseGroovyFromString(String script, XWikiContext xcontext) throws XWikiException
6097    {
6098  0 return getParseGroovyFromString().parseGroovyFromString(script, xcontext);
6099    }
6100   
6101    /**
6102    * Privileged API to retrieve an object instantiated from groovy code in a String, using a classloader including all
6103    * JAR files located in the passed page as attachments. Note that Groovy scripts compilation is cached
6104    *
6105    * @param script the Groovy class definition string (public class MyClass { ... })
6106    * @return An object instantiating this class
6107    * @throws XWikiException
6108    */
 
6109  0 toggle public Object parseGroovyFromString(String script, String jarWikiPage, XWikiContext xcontext) throws XWikiException
6110    {
6111  0 XWikiPageClassLoader pcl = new XWikiPageClassLoader(jarWikiPage, xcontext);
6112  0 Object prevParentClassLoader = xcontext.get("parentclassloader");
6113  0 try {
6114  0 xcontext.put("parentclassloader", pcl);
6115   
6116  0 return parseGroovyFromString(script, xcontext);
6117    } finally {
6118  0 if (prevParentClassLoader == null) {
6119  0 xcontext.remove("parentclassloader");
6120    } else {
6121  0 xcontext.put("parentclassloader", prevParentClassLoader);
6122    }
6123    }
6124    }
6125   
 
6126  0 toggle public Object parseGroovyFromPage(String fullname, XWikiContext context) throws XWikiException
6127    {
6128  0 return parseGroovyFromString(context.getWiki().getDocument(fullname, context).getContent(), context);
6129    }
6130   
 
6131  0 toggle public Object parseGroovyFromPage(String fullName, String jarWikiPage, XWikiContext context) throws XWikiException
6132    {
6133  0 return parseGroovyFromString(context.getWiki().getDocument(fullName, context).getContent(), jarWikiPage,
6134    context);
6135    }
6136   
 
6137  0 toggle public String getMacroList(XWikiContext context)
6138    {
6139  0 String macrosmapping = "";
6140  0 XWiki xwiki = context.getWiki();
6141   
6142  0 try {
6143  0 macrosmapping = getResourceContent(MACROS_FILE);
6144    } catch (IOException e) {
6145    }
6146   
6147  0 macrosmapping += "\r\n" + xwiki.getXWikiPreference("macros_mapping", "", context);
6148   
6149  0 return macrosmapping;
6150    }
6151   
6152    // This functions adds an object from an new object creation form
 
6153  0 toggle public BaseObject getObjectFromRequest(String className, XWikiContext context) throws XWikiException
6154    {
6155  0 Map<String, String[]> map = Util.getObject(context.getRequest(), className);
6156  0 BaseClass bclass = context.getWiki().getClass(className, context);
6157  0 BaseObject newobject = (BaseObject) bclass.fromMap(map, context);
6158   
6159  0 return newobject;
6160    }
6161   
 
6162  12742 toggle public String getConvertingUserNameType(XWikiContext context)
6163    {
6164  12742 if (StringUtils.isNotBlank(context.getWiki().getXWikiPreference("convertmail", context))) {
6165  0 return context.getWiki().getXWikiPreference("convertmail", "0", context);
6166    }
6167   
6168  12742 return getConfiguration().getProperty("xwiki.authentication.convertemail", "0");
6169    }
6170   
 
6171  8795 toggle public String convertUsername(String username, XWikiContext context)
6172    {
6173  8792 if (username == null) {
6174  2424 return null;
6175    }
6176   
6177  6371 if (getConvertingUserNameType(context).equals("1") && (username.indexOf('@') != -1)) {
6178  0 String id = "" + username.hashCode();
6179  0 id = id.replace("-", "");
6180  0 if (username.length() > 1) {
6181  0 int i1 = username.indexOf('@');
6182  0 id = "" + username.charAt(0) + username.substring(i1 + 1, i1 + 2)
6183    + username.charAt(username.length() - 1) + id;
6184    }
6185   
6186  0 return id;
6187  6371 } else if (getConvertingUserNameType(context).equals("2")) {
6188  0 return username.replaceAll("[\\.\\@]", "_");
6189    } else {
6190  6371 return username;
6191    }
6192    }
6193   
 
6194  176 toggle public boolean hasSectionEdit(XWikiContext context)
6195    {
6196  176 return getConfiguration().getProperty("xwiki.section.edit", 0) == 1;
6197    }
6198   
6199    /**
6200    * @return The maximum section depth for which section editing is available. This can be customized through the
6201    * {@code xwiki.section.depth} configuration property. Defaults to 2 when not defined.
6202    */
 
6203  47 toggle public long getSectionEditingDepth()
6204    {
6205  47 return getConfiguration().getProperty("xwiki.section.depth", 2L);
6206    }
6207   
 
6208  0 toggle public String getWysiwygToolbars(XWikiContext context)
6209    {
6210  0 return getConfiguration().getProperty("xwiki.wysiwyg.toolbars", "");
6211    }
6212   
 
6213  36 toggle public String clearName(String name, XWikiContext context)
6214    {
6215  36 return clearName(name, true, true, context);
6216    }
6217   
 
6218  40 toggle public String clearName(String name, boolean stripDots, boolean ascii, XWikiContext context)
6219    {
6220  40 String temp = name;
6221  40 temp = temp.replaceAll(
6222    "[\u00c0\u00c1\u00c2\u00c3\u00c4\u00c5\u0100\u0102\u0104\u01cd\u01de\u01e0\u01fa\u0200\u0202\u0226]", "A");
6223  40 temp = temp.replaceAll(
6224    "[\u00e0\u00e1\u00e2\u00e3\u00e4\u00e5\u0101\u0103\u0105\u01ce\u01df\u01e1\u01fb\u0201\u0203\u0227]", "a");
6225  40 temp = temp.replaceAll("[\u00c6\u01e2\u01fc]", "AE");
6226  40 temp = temp.replaceAll("[\u00e6\u01e3\u01fd]", "ae");
6227  40 temp = temp.replaceAll("[\u008c\u0152]", "OE");
6228  40 temp = temp.replaceAll("[\u009c\u0153]", "oe");
6229  40 temp = temp.replaceAll("[\u00c7\u0106\u0108\u010a\u010c]", "C");
6230  40 temp = temp.replaceAll("[\u00e7\u0107\u0109\u010b\u010d]", "c");
6231  40 temp = temp.replaceAll("[\u00d0\u010e\u0110]", "D");
6232  40 temp = temp.replaceAll("[\u00f0\u010f\u0111]", "d");
6233  40 temp = temp.replaceAll("[\u00c8\u00c9\u00ca\u00cb\u0112\u0114\u0116\u0118\u011a\u0204\u0206\u0228]", "E");
6234  40 temp = temp.replaceAll("[\u00e8\u00e9\u00ea\u00eb\u0113\u0115\u0117\u0119\u011b\u01dd\u0205\u0207\u0229]", "e");
6235  40 temp = temp.replaceAll("[\u011c\u011e\u0120\u0122\u01e4\u01e6\u01f4]", "G");
6236  40 temp = temp.replaceAll("[\u011d\u011f\u0121\u0123\u01e5\u01e7\u01f5]", "g");
6237  40 temp = temp.replaceAll("[\u0124\u0126\u021e]", "H");
6238  40 temp = temp.replaceAll("[\u0125\u0127\u021f]", "h");
6239  40 temp = temp.replaceAll("[\u00cc\u00cd\u00ce\u00cf\u0128\u012a\u012c\u012e\u0130\u01cf\u0208\u020a]", "I");
6240  40 temp = temp.replaceAll("[\u00ec\u00ed\u00ee\u00ef\u0129\u012b\u012d\u012f\u0131\u01d0\u0209\u020b]", "i");
6241  40 temp = temp.replaceAll("[\u0132]", "IJ");
6242  40 temp = temp.replaceAll("[\u0133]", "ij");
6243  40 temp = temp.replaceAll("[\u0134]", "J");
6244  40 temp = temp.replaceAll("[\u0135]", "j");
6245  40 temp = temp.replaceAll("[\u0136\u01e8]", "K");
6246  40 temp = temp.replaceAll("[\u0137\u0138\u01e9]", "k");
6247  40 temp = temp.replaceAll("[\u0139\u013b\u013d\u013f\u0141]", "L");
6248  40 temp = temp.replaceAll("[\u013a\u013c\u013e\u0140\u0142\u0234]", "l");
6249  40 temp = temp.replaceAll("[\u00d1\u0143\u0145\u0147\u014a\u01f8]", "N");
6250  40 temp = temp.replaceAll("[\u00f1\u0144\u0146\u0148\u0149\u014b\u01f9\u0235]", "n");
6251  40 temp = temp.replaceAll(
6252    "[\u00d2\u00d3\u00d4\u00d5\u00d6\u00d8\u014c\u014e\u0150\u01d1\u01ea\u01ec\u01fe\u020c\u020e\u022a\u022c"
6253    + "\u022e\u0230]",
6254    "O");
6255  40 temp = temp.replaceAll(
6256    "[\u00f2\u00f3\u00f4\u00f5\u00f6\u00f8\u014d\u014f\u0151\u01d2\u01eb\u01ed\u01ff\u020d\u020f\u022b\u022d"
6257    + "\u022f\u0231]",
6258    "o");
6259  40 temp = temp.replaceAll("[\u0156\u0158\u0210\u0212]", "R");
6260  40 temp = temp.replaceAll("[\u0157\u0159\u0211\u0213]", "r");
6261  40 temp = temp.replaceAll("[\u015a\u015c\u015e\u0160\u0218]", "S");
6262  40 temp = temp.replaceAll("[\u015b\u015d\u015f\u0161\u0219]", "s");
6263  40 temp = temp.replaceAll("[\u00de\u0162\u0164\u0166\u021a]", "T");
6264  40 temp = temp.replaceAll("[\u00fe\u0163\u0165\u0167\u021b\u0236]", "t");
6265  40 temp = temp.replaceAll(
6266    "[\u00d9\u00da\u00db\u00dc\u0168\u016a\u016c\u016e\u0170\u0172\u01d3\u01d5\u01d7\u01d9\u01db\u0214\u0216]",
6267    "U");
6268  40 temp = temp.replaceAll(
6269    "[\u00f9\u00fa\u00fb\u00fc\u0169\u016b\u016d\u016f\u0171\u0173\u01d4\u01d6\u01d8\u01da\u01dc\u0215\u0217]",
6270    "u");
6271  40 temp = temp.replaceAll("[\u0174]", "W");
6272  40 temp = temp.replaceAll("[\u0175]", "w");
6273  40 temp = temp.replaceAll("[\u00dd\u0176\u0178\u0232]", "Y");
6274  40 temp = temp.replaceAll("[\u00fd\u00ff\u0177\u0233]", "y");
6275  40 temp = temp.replaceAll("[\u0179\u017b\u017d]", "Z");
6276  40 temp = temp.replaceAll("[\u017a\u017c\u017e]", "z");
6277  40 temp = temp.replaceAll("[\u00df]", "SS");
6278  40 temp = temp.replaceAll("[_':,;\\\\/]", " ");
6279  40 name = temp;
6280  40 name = name.replaceAll("\\s+", "");
6281  40 name = name.replaceAll("[\\(\\)]", " ");
6282   
6283  40 if (stripDots) {
6284  38 name = name.replaceAll("[\\.]", "");
6285    }
6286   
6287  40 if (ascii) {
6288  38 name = name.replaceAll("[^a-zA-Z0-9\\-_\\.]", "");
6289    }
6290   
6291  40 if (name.length() > 250) {
6292  0 name = name.substring(0, 250);
6293    }
6294   
6295  40 return name;
6296   
6297    }
6298   
 
6299  36 toggle public String getUniquePageName(String space, XWikiContext context)
6300    {
6301  36 String pageName = generateRandomString(16);
6302   
6303  36 return getUniquePageName(space, pageName, context);
6304    }
6305   
 
6306  36 toggle public String getUniquePageName(String space, String name, XWikiContext context)
6307    {
6308  36 String pageName = clearName(name, context);
6309  36 if (exists(space + "." + pageName, context)) {
6310  0 int i = 0;
6311  0 while (exists(space + "." + pageName + "_" + i, context)) {
6312  0 i++;
6313    }
6314   
6315  0 return pageName + "_" + i;
6316    }
6317   
6318  36 return pageName;
6319    }
6320   
 
6321  0 toggle public PropertyClass getPropertyClassFromName(String propPath, XWikiContext context)
6322    {
6323  0 int i1 = propPath.indexOf('_');
6324  0 if (i1 == -1) {
6325  0 return null;
6326    } else {
6327  0 String className = propPath.substring(0, i1);
6328  0 String propName = propPath.substring(i1 + 1);
6329  0 try {
6330  0 return (PropertyClass) getDocument(className, context).getXClass().get(propName);
6331    } catch (XWikiException e) {
6332  0 return null;
6333    }
6334    }
6335    }
6336   
 
6337  0 toggle public boolean validateDocument(XWikiDocument doc, XWikiContext context) throws XWikiException
6338    {
6339  0 return doc.validate(context);
6340    }
6341   
 
6342  0 toggle public String addTooltip(String html, String message, String params, XWikiContext context)
6343    {
6344  0 StringBuilder buffer = new StringBuilder();
6345  0 buffer.append("<span class=\"tooltip_span\" onmouseover=\"");
6346  0 buffer.append(params);
6347  0 buffer.append("; return escape('");
6348  0 buffer.append(message.replaceAll("'", "\\'"));
6349  0 buffer.append("');\">");
6350  0 buffer.append(html);
6351  0 buffer.append("</span>");
6352   
6353  0 return buffer.toString();
6354    }
6355   
 
6356  0 toggle public String addTooltipJS(XWikiContext context)
6357    {
6358  0 StringBuilder buffer = new StringBuilder();
6359  0 buffer.append("<script type=\"text/javascript\" src=\"");
6360  0 buffer.append(getSkinFile("ajax/wzToolTip.js", context));
6361  0 buffer.append("\"></script>");
6362    // buffer.append("<div id=\"dhtmltooltip\"></div>");
6363   
6364  0 return buffer.toString();
6365    }
6366   
 
6367  0 toggle public String addTooltip(String html, String message, XWikiContext context)
6368    {
6369  0 return addTooltip(html, message, "this.WIDTH='300'", context);
6370    }
6371   
 
6372  0 toggle public void renamePage(String fullName, String newFullName, XWikiContext context) throws XWikiException
6373    {
6374  0 renamePage(context.getWiki().getDocument(fullName, context), newFullName, context);
6375    }
6376   
 
6377  0 toggle public String addMandatory(XWikiContext context)
6378    {
6379  0 String star =
6380    "<span class=\"mandatoryParenthesis\">&nbsp;(</span><span class=\"mandatoryDot\">&lowast;</span><span class=\"mandatoryParenthesis\">)&nbsp;</span>";
6381  0 return context.getWiki().getXWikiPreference("mandatory_display", star, context);
6382    }
6383   
6384    /**
6385    * @since 2.3M1
6386    */
 
6387  5783 toggle public boolean hasVersioning(XWikiContext context)
6388    {
6389  5783 return ("1".equals(getConfiguration().getProperty("xwiki.store.versioning", "1")));
6390    }
6391   
 
6392  87 toggle public boolean hasAttachmentVersioning(XWikiContext context)
6393    {
6394  87 return ("1".equals(getConfiguration().getProperty("xwiki.store.attachment.versioning", "1")));
6395    }
6396   
 
6397  0 toggle public String getExternalAttachmentURL(String fullName, String filename, XWikiContext context)
6398    {
6399  0 XWikiDocument doc = new XWikiDocument();
6400  0 doc.setFullName(fullName, context);
6401   
6402  0 return doc.getExternalAttachmentURL(filename, "download", context);
6403    }
6404   
 
6405  0 toggle public int getMaxRecursiveSpaceChecks(XWikiContext context)
6406    {
6407  0 int max = getXWikiPreferenceAsInt("rights_maxrecursivespacechecks", -1, context);
6408  0 if (max == -1) {
6409  0 return getConfiguration().getProperty("xwiki.rights.maxrecursivespacechecks", 0);
6410    } else {
6411  0 return max;
6412    }
6413    }
6414   
6415    /**
6416    * Restore a document with passed index from recycle bin.
6417    *
6418    * @param doc the document to restore
6419    * @param comment the comment to use when saving the document
6420    * @param context see {@link XWikiContext}
6421    * @throws XWikiException when failing to restore document
6422    * @since 5.4RC1
6423    */
 
6424  0 toggle public void restoreFromRecycleBin(final XWikiDocument doc, String comment, XWikiContext context)
6425    throws XWikiException
6426    {
6427  0 XWikiDeletedDocument[] deletedDocuments = getRecycleBinStore().getAllDeletedDocuments(doc, context, true);
6428  0 if (deletedDocuments != null && deletedDocuments.length > 0) {
6429  0 long index = deletedDocuments[0].getId();
6430  0 restoreFromRecycleBin(doc, index, comment, context);
6431    }
6432    }
6433   
6434    /**
6435    * Restore a document with passed index from recycle bin.
6436    *
6437    * @param doc the document to restore
6438    * @param index the index of the document in the recycle bin
6439    * @param comment the comment to use when saving the document
6440    * @param context see {@link XWikiContext}
6441    * @throws XWikiException when failing to restore document
6442    * @since 5.4RC1
6443    */
 
6444  2 toggle public void restoreFromRecycleBin(final XWikiDocument doc, long index, String comment, XWikiContext context)
6445    throws XWikiException
6446    {
6447  2 XWikiDocument newdoc = getRecycleBinStore().restoreFromRecycleBin(doc, index, context, true);
6448  2 saveDocument(newdoc, comment, context);
6449  2 getRecycleBinStore().deleteFromRecycleBin(doc, index, context, true);
6450    }
6451   
 
6452  2 toggle public XWikiDocument rollback(final XWikiDocument tdoc, String rev, XWikiContext context) throws XWikiException
6453    {
6454  2 LOGGER.debug("Rolling back [" + tdoc + "] to version " + rev);
6455    // Let's clone rolledbackDoc since we might modify it
6456  2 XWikiDocument rolledbackDoc = getDocument(tdoc, rev, context).clone();
6457   
6458  2 if ("1".equals(getConfiguration().getProperty("xwiki.store.rollbackattachmentwithdocuments", "1"))) {
6459    // Attachment handling strategy:
6460    // - Two lists: Old Attachments, Current Attachments
6461    // Goals:
6462    // 1. Attachments that are only in OA must be restored from the trash
6463    // 2. Attachments that are only in CA must be sent to the trash
6464    // 3. Attachments that are in both lists should be reverted to the right version
6465    // 4. Gotcha: deleted and re-uploaded attachments should be both trashed and restored.
6466    // Plan:
6467    // - Construct two lists: to restore, to revert
6468    // - Iterate over OA.
6469    // -- If the attachment is not in CA, add it to the restore list
6470    // -- If it is in CA, but the date of the first version of the current attachment is after the date of the
6471    // restored document version, add it the restore & move the current attachment to the recycle bin
6472    // -- Otherwise, add it to the revert list
6473    // - Iterate over CA
6474    // -- If the attachment is not in OA, delete it
6475   
6476  0 List<XWikiAttachment> oldAttachments = rolledbackDoc.getAttachmentList();
6477  0 List<XWikiAttachment> currentAttachments = tdoc.getAttachmentList();
6478  0 List<XWikiAttachment> toRestore = new ArrayList<XWikiAttachment>();
6479  0 List<XWikiAttachment> toRevert = new ArrayList<XWikiAttachment>();
6480   
6481    // First step, determine what to do with each attachment
6482  0 LOGGER.debug("Checking attachments");
6483   
6484  0 for (XWikiAttachment oldAttachment : oldAttachments) {
6485  0 String filename = oldAttachment.getFilename();
6486  0 XWikiAttachment equivalentAttachment = tdoc.getAttachment(filename);
6487  0 if (equivalentAttachment == null) {
6488    // Deleted attachment
6489  0 LOGGER.debug("Deleted attachment: " + filename);
6490  0 toRestore.add(oldAttachment);
6491  0 continue;
6492    }
6493  0 XWikiAttachment equivalentAttachmentRevision =
6494    equivalentAttachment.getAttachmentRevision(oldAttachment.getVersion(), context);
6495    // We compare the number of milliseconds instead of the date objects directly because Hibernate can
6496    // return java.sql.Timestamp for date fields and the JavaDoc says that Timestamp.equals(Object) doesn't
6497    // return true if the passed value is a java.util.Date object with the same number of milliseconds
6498    // because the nanoseconds component of the passed date is unknown.
6499  0 if (equivalentAttachmentRevision == null
6500    || equivalentAttachmentRevision.getDate().getTime() != oldAttachment.getDate().getTime()) {
6501    // Recreated attachment
6502  0 LOGGER.debug("Recreated attachment: " + filename);
6503    // If the attachment trash is not available, don't lose the existing attachment
6504  0 if (getAttachmentRecycleBinStore() != null) {
6505  0 getAttachmentRecycleBinStore().saveToRecycleBin(equivalentAttachment, context.getUser(),
6506    new Date(), context, true);
6507  0 toRestore.add(oldAttachment);
6508    }
6509  0 continue;
6510    }
6511  0 if (!StringUtils.equals(oldAttachment.getVersion(), equivalentAttachment.getVersion())) {
6512    // Updated attachment
6513  0 LOGGER.debug("Updated attachment: " + filename);
6514  0 toRevert.add(equivalentAttachment);
6515    }
6516    }
6517  0 for (XWikiAttachment attachment : currentAttachments) {
6518  0 if (rolledbackDoc.getAttachment(attachment.getFilename()) == null) {
6519  0 LOGGER.debug("New attachment: " + attachment.getFilename());
6520    // XWikiDocument#save() is actually the only way to delete an attachment cleanly
6521  0 rolledbackDoc.getAttachmentsToRemove().add(new XWikiAttachmentToRemove(attachment, true));
6522    }
6523    }
6524   
6525    // Second step, treat each affected attachment
6526   
6527    // Revert updated attachments to the old version
6528  0 for (XWikiAttachment attachmentToRevert : toRevert) {
6529  0 String oldAttachmentVersion =
6530    rolledbackDoc.getAttachment(attachmentToRevert.getFilename()).getVersion();
6531  0 XWikiAttachment oldAttachmentRevision =
6532    attachmentToRevert.getAttachmentRevision(oldAttachmentVersion, context);
6533  0 if (oldAttachmentRevision == null) {
6534    // Previous version is lost, just leave the current version in place
6535  0 replaceAttachmentInPlace(rolledbackDoc, attachmentToRevert);
6536  0 continue;
6537    }
6538    // We can't just leave the old version in place, since it will break the revision history, given the
6539    // current implementation, so we set the attachment version to the most recent version, mark the content
6540    // as dirty, and the storage will automatically bump up the version number.
6541    // This is a hack, to be fixed once the storage doesn't take care of updating the history and version,
6542    // and once the current attachment version can point to an existing version from the history.
6543  0 oldAttachmentRevision.setVersion(attachmentToRevert.getVersion());
6544  0 oldAttachmentRevision.setMetaDataDirty(true);
6545  0 oldAttachmentRevision.getAttachment_content().setContentDirty(true);
6546  0 replaceAttachmentInPlace(rolledbackDoc, oldAttachmentRevision);
6547    }
6548   
6549    // Restore deleted attachments from the trash
6550  0 if (getAttachmentRecycleBinStore() != null) {
6551  0 for (XWikiAttachment attachmentToRestore : toRestore) {
6552    // There might be multiple versions of the attachment in the trash, search for the right one
6553  0 List<DeletedAttachment> deletedVariants =
6554    getAttachmentRecycleBinStore().getAllDeletedAttachments(attachmentToRestore, context, true);
6555  0 DeletedAttachment correctVariant = null;
6556  0 for (DeletedAttachment variant : deletedVariants) { // Reverse chronological order
6557  0 if (variant.getDate().before(rolledbackDoc.getDate())) {
6558  0 break;
6559    }
6560  0 correctVariant = variant;
6561    }
6562  0 if (correctVariant == null) {
6563    // Not found in the trash, nothing left to do
6564  0 continue;
6565    }
6566  0 XWikiAttachment restoredAttachment = correctVariant.restoreAttachment(null, context);
6567  0 XWikiAttachment restoredAttachmentRevision =
6568    restoredAttachment.getAttachmentRevision(attachmentToRestore.getVersion(), context);
6569   
6570  0 if (restoredAttachmentRevision != null) {
6571  0 restoredAttachmentRevision.setAttachment_archive(restoredAttachment.getAttachment_archive());
6572  0 restoredAttachmentRevision.getAttachment_archive().setAttachment(restoredAttachmentRevision);
6573  0 restoredAttachmentRevision.setVersion(restoredAttachment.getVersion());
6574  0 restoredAttachmentRevision.setMetaDataDirty(true);
6575  0 restoredAttachmentRevision.getAttachment_content().setContentDirty(true);
6576  0 replaceAttachmentInPlace(rolledbackDoc, restoredAttachmentRevision);
6577    } else {
6578    // This particular version is lost, update to the one available
6579  0 replaceAttachmentInPlace(rolledbackDoc, restoredAttachment);
6580    }
6581    }
6582    } else {
6583    // No trash, can't restore. Remove the attachment references, so that the document is not broken
6584  0 for (XWikiAttachment attachmentToRestore : toRestore) {
6585  0 rolledbackDoc.getAttachmentList().remove(attachmentToRestore);
6586    }
6587    }
6588    }
6589   
6590    // Special treatment for deleted objects
6591  2 rolledbackDoc.addXObjectsToRemoveFromVersion(tdoc);
6592   
6593    // now we save the final document..
6594  2 rolledbackDoc.setOriginalDocument(tdoc);
6595  2 rolledbackDoc.setAuthorReference(context.getUserReference());
6596  2 rolledbackDoc.setRCSVersion(tdoc.getRCSVersion());
6597  2 rolledbackDoc.setVersion(tdoc.getVersion());
6598  2 rolledbackDoc.setContentDirty(true);
6599   
6600  2 ObservationManager om = getObservationManager();
6601  2 if (om != null) {
6602    // Notify listeners about the document that is going to be rolled back.
6603    // Note that for the moment the event being send is a bridge event, as we are still passing around
6604    // an XWikiDocument as source and an XWikiContext as data.
6605  2 om.notify(new DocumentRollingBackEvent(rolledbackDoc.getDocumentReference(), rev), rolledbackDoc, context);
6606    }
6607   
6608  2 saveDocument(rolledbackDoc, localizePlainOrKey("core.comment.rollback", rev), context);
6609   
6610    // Since the the store resets the original document, we need to temporarily put it back to send notifications.
6611  2 XWikiDocument newOriginalDocument = rolledbackDoc.getOriginalDocument();
6612  2 rolledbackDoc.setOriginalDocument(tdoc);
6613   
6614  2 try {
6615  2 if (om != null) {
6616    // Notify listeners about the document that was rolled back.
6617    // Note that for the moment the event being send is a bridge event, as we are still passing around an
6618    // XWikiDocument as source and an XWikiContext as data.
6619  2 om.notify(new DocumentRolledBackEvent(rolledbackDoc.getDocumentReference(), rev), rolledbackDoc,
6620    context);
6621    }
6622    } finally {
6623  2 rolledbackDoc.setOriginalDocument(newOriginalDocument);
6624    }
6625   
6626  2 return rolledbackDoc;
6627    }
6628   
 
6629  0 toggle private void replaceAttachmentInPlace(XWikiDocument doc, XWikiAttachment attachment)
6630    {
6631  0 for (ListIterator<XWikiAttachment> it = doc.getAttachmentList().listIterator(); it.hasNext();) {
6632  0 if (StringUtils.equals(it.next().getFilename(), attachment.getFilename())) {
6633  0 it.remove();
6634  0 it.add(attachment);
6635  0 break;
6636    }
6637    }
6638    }
6639   
6640    /**
6641    * @return the ids of configured syntaxes for this wiki (e.g. {@code xwiki/2.0}, {@code xwiki/2.1},
6642    * {@code mediawiki/1.0}, etc)
6643    * @deprecated since 8.2M1, use the XWiki Rendering Configuration component or the Rendering Script Service one
6644    * instead
6645    */
 
6646  0 toggle @Deprecated
6647    public List<String> getConfiguredSyntaxes()
6648    {
6649  0 return this.configuredSyntaxes;
6650    }
6651   
6652    /**
6653    * @return the syntax id of the syntax to use when creating new documents
6654    */
 
6655  0 toggle public String getDefaultDocumentSyntax()
6656    {
6657    // TODO: Fix this method to return a Syntax object instead of a String
6658  0 return getDefaultDocumentSyntaxInternal().toIdString();
6659    }
6660   
6661    /**
6662    * @return the syntax to use when creating new documents
6663    */
 
6664  29 toggle private Syntax getDefaultDocumentSyntaxInternal()
6665    {
6666  29 return Utils.getComponent(CoreConfiguration.class).getDefaultDocumentSyntax();
6667    }
6668   
6669    /**
6670    * Get the syntax of the content currently being executed.
6671    * <p>
6672    * The document currently being executed is not the same than the actual content syntax since the executed code
6673    * might come from an included page or some macro that change the context syntax. The same logic used inside
6674    * rendering macros is used (see {@link org.xwiki.rendering.macro.MacroContentParser}).
6675    * <p>
6676    * If the current document can't be found, the method assume that the executed document is the context document
6677    * (it's generally the case when a document is directly rendered with
6678    * {@link XWikiDocument#getRenderedContent(XWikiContext)} for example).
6679    *
6680    * @param defaultSyntaxId the default value to return if no document can be found
6681    * @return the syntax identifier
6682    */
 
6683  1923 toggle public String getCurrentContentSyntaxId(String defaultSyntaxId, XWikiContext context)
6684    {
6685  1923 String syntaxId = getCurrentContentSyntaxIdInternal(context);
6686   
6687  1923 if (syntaxId == null) {
6688  2 syntaxId = defaultSyntaxId;
6689    }
6690   
6691  1923 return syntaxId;
6692    }
6693   
6694    /**
6695    * Get the syntax of the content currently being executed.
6696    * <p>
6697    * The document currently being executed is not the same than the actual content syntax since the executed code
6698    * might come from an included page or some macro that change the context syntax. The same logic used inside
6699    * rendering macros is used (see {@link org.xwiki.rendering.macro.MacroContentParser}).
6700    * <p>
6701    * If the current document can't be found, the method assume that the executed document is the context document
6702    * (it's generally the case when a document is directly rendered with
6703    * {@link XWikiDocument#getRenderedContent(XWikiContext)} for example).
6704    *
6705    * @return the syntax identifier
6706    */
 
6707  182 toggle public String getCurrentContentSyntaxId(XWikiContext context)
6708    {
6709  182 String syntaxId = getCurrentContentSyntaxIdInternal(context);
6710   
6711  182 if (syntaxId == null) {
6712  0 throw new RuntimeException("Cannot get the current syntax since there's no current document set");
6713    }
6714   
6715  182 return syntaxId;
6716    }
6717   
6718    /**
6719    * Get the syntax of the content currently being executed.
6720    * <p>
6721    * The document currently being executed is not the same than the actual content syntax since the executed code
6722    * might come from an included page or some macro that change the context syntax. The same logic used inside
6723    * rendering macros is used (see {@link org.xwiki.rendering.macro.MacroContentParser}).
6724    * <p>
6725    * If the current document can't be found, the method assume that the executed document is the context document
6726    * (it's generally the case when a document is directly rendered with
6727    * {@link XWikiDocument#getRenderedContent(XWikiContext)} for example).
6728    *
6729    * @return the syntax identifier
6730    */
 
6731  2105 toggle private String getCurrentContentSyntaxIdInternal(XWikiContext context)
6732    {
6733  2105 Syntax syntax = getCurrentContentSyntaxInternal(context);
6734   
6735  2105 return syntax != null ? syntax.toIdString() : null;
6736    }
6737   
6738    /**
6739    * Get the syntax of the code currently being executed.
6740    * <p>
6741    * The document currently being executed is not the same than the actual content syntax since the executed code
6742    * might come from an included page or some macro that change the context syntax. The same logic used inside
6743    * rendering macros is used (see {@link org.xwiki.rendering.macro.MacroContentParser}).
6744    * <p>
6745    * If the current document can't be found, the method assume that the executed document is the context document
6746    * (it's generally the case when a document is directly rendered with
6747    * {@link XWikiDocument#getRenderedContent(XWikiContext)} for example).
6748    *
6749    * @return the syntax
6750    */
 
6751  2105 toggle private Syntax getCurrentContentSyntaxInternal(XWikiContext context)
6752    {
6753  2105 Syntax syntax = null;
6754   
6755    // Try to find the current syntax
6756  2105 if (getRenderingContext() != null) {
6757  2105 Block curentBlock = getRenderingContext().getCurrentBlock();
6758   
6759  2105 if (curentBlock != null) {
6760  1240 MetaDataBlock metaDataBlock =
6761    curentBlock.getFirstBlock(new MetadataBlockMatcher(MetaData.SYNTAX), Axes.ANCESTOR_OR_SELF);
6762   
6763  1240 if (metaDataBlock != null) {
6764  1240 return (Syntax) metaDataBlock.getMetaData().getMetaData(MetaData.SYNTAX);
6765    }
6766    }
6767    }
6768   
6769    // Fallback on secure and current document in the context
6770  865 if (context.get("sdoc") != null) {
6771    // The content document
6772  858 syntax = ((XWikiDocument) context.get("sdoc")).getSyntax();
6773  7 } else if (context.getDoc() != null) {
6774    // The context document
6775  5 syntax = context.getDoc().getSyntax();
6776    }
6777   
6778  865 return syntax;
6779    }
6780   
6781    /**
6782    * @return true if title handling should be using the compatibility mode or not. When the compatibility mode is
6783    * active, if the document's content first header (level 1 or level 2) matches the document's title the
6784    * first header is stripped.
6785    */
 
6786  212 toggle public boolean isTitleInCompatibilityMode()
6787    {
6788  212 return "1".equals(getConfiguration().getProperty("xwiki.title.compatibility", "0"));
6789    }
6790   
 
6791  3 toggle @Override
6792    public void onEvent(Event event, Object source, Object data)
6793    {
6794  3 if (event instanceof WikiDeletedEvent) {
6795    // A wiki has been deleted
6796  3 onWikiDeletedEvent((WikiDeletedEvent) event);
6797  0 } else if (event instanceof ComponentDescriptorAddedEvent) {
6798    // A new mandatory document initializer has been installed
6799  0 onMandatoryDocumentInitializerAdded((ComponentDescriptorAddedEvent) event, (ComponentManager) source);
6800    } else {
6801    // Document modifications
6802   
6803  0 XWikiDocument doc = (XWikiDocument) source;
6804  0 XWikiContext context = (XWikiContext) data;
6805   
6806  0 if (event instanceof XObjectPropertyEvent) {
6807  0 EntityReference reference = ((XObjectPropertyEvent) event).getReference();
6808  0 String modifiedProperty = reference.getName();
6809  0 if ("backlinks".equals(modifiedProperty)) {
6810  0 this.hasBacklinks = doc.getXObject((ObjectReference) reference.getParent()).getIntValue("backlinks",
6811    getConfiguration().getProperty("xwiki.backlinks", 0)) == 1;
6812    }
6813    }
6814    }
6815    }
6816   
 
6817  3 toggle private void onWikiDeletedEvent(WikiDeletedEvent event)
6818    {
6819  3 this.initializedWikis.remove(event.getWikiId());
6820    }
6821   
 
6822  0 toggle private void onMandatoryDocumentInitializerAdded(ComponentDescriptorAddedEvent event,
6823    ComponentManager componentManager)
6824    {
6825  0 String namespace;
6826  0 if (componentManager instanceof NamespacedComponentManager) {
6827  0 namespace = ((NamespacedComponentManager) componentManager).getNamespace();
6828    } else {
6829  0 namespace = null;
6830    }
6831   
6832  0 MandatoryDocumentInitializer initializer;
6833  0 try {
6834  0 initializer = componentManager.getInstance(MandatoryDocumentInitializer.class, event.getRoleHint());
6835   
6836  0 XWikiContext context = getXWikiContext();
6837  0 if (namespace == null) {
6838    // Initialize in already initialized wikis (will be initialized in others when they are initialized)
6839  0 for (String wiki : this.initializedWikis.keySet()) {
6840  0 initializeMandatoryDocument(wiki, initializer, context);
6841    }
6842  0 } else if (namespace.startsWith("wiki:")) {
6843    // Initialize in the wiki where the extension is installed
6844  0 initializeMandatoryDocument(namespace.substring("wiki:".length()), initializer, context);
6845    }
6846    } catch (ComponentLookupException e) {
6847  0 LOGGER.error("Failed to lookup mandatory document initializer", e);
6848    }
6849    }
6850   
6851    /**
6852    * The reference to match properties "plugins" and "backlinks" of class XWiki.XWikiPreference on whatever wiki.
6853    */
6854    private static final RegexEntityReference XWIKIPREFERENCE_PROPERTY_REFERENCE =
6855    new RegexEntityReference(Pattern.compile("backlinks"), EntityType.OBJECT_PROPERTY,
6856    new RegexEntityReference(Pattern.compile(".*:XWiki.XWikiPreferences\\[\\d*\\]"), EntityType.OBJECT));
6857   
6858    private static final List<Event> LISTENER_EVENTS =
6859    Arrays.<Event>asList(new XObjectPropertyAddedEvent(XWIKIPREFERENCE_PROPERTY_REFERENCE),
6860    new XObjectPropertyDeletedEvent(XWIKIPREFERENCE_PROPERTY_REFERENCE),
6861    new XObjectPropertyUpdatedEvent(XWIKIPREFERENCE_PROPERTY_REFERENCE), new WikiDeletedEvent(),
6862    new ComponentDescriptorAddedEvent(MandatoryDocumentInitializer.class));
6863   
 
6864  87 toggle @Override
6865    public List<Event> getEvents()
6866    {
6867  87 return LISTENER_EVENTS;
6868    }
6869   
 
6870  1017 toggle @Override
6871    public String getName()
6872    {
6873  1017 return "xwiki-core";
6874    }
6875   
6876    /**
6877    * Return the document reference to the wiki preferences.
6878    *
6879    * @param context see {@link XWikiContext}
6880    * @since 4.3M2
6881    */
 
6882  2 toggle private DocumentReference getPreferencesDocumentReference(XWikiContext context)
6883    {
6884  2 String database = context.getWikiId();
6885  2 EntityReference spaceReference;
6886  2 if (database != null) {
6887  2 spaceReference = new EntityReference(SYSTEM_SPACE, EntityType.SPACE, new WikiReference(database));
6888    } else {
6889  0 spaceReference = getCurrentMixedEntityReferenceResolver().resolve(SYSTEM_SPACE, EntityType.SPACE);
6890    }
6891  2 return new DocumentReference("XWikiPreferences", new SpaceReference(spaceReference));
6892    }
6893   
6894    /**
6895    * Search attachments by passing HQL where clause values as parameters. You can specify properties of the "attach"
6896    * (the attachment) or "doc" (the document it is attached to)
6897    *
6898    * @param parametrizedSqlClause The HQL where clause. For example {@code where doc.fullName
6899    * <> ? and (attach.author = ? or (attach.filename = ? and doc.space = ?))}
6900    * @param checkRight if true, only return attachments in documents which the "current user" has permission to view.
6901    * @param nb The number of rows to return. If 0 then all rows are returned
6902    * @param start The number of rows to skip at the beginning.
6903    * @param parameterValues A {@link java.util.List} of the where clause values that replace the question marks (?)
6904    * @param context see {@link XWikiContext}
6905    * @return A List of {@link XWikiAttachment} objects.
6906    * @throws XWikiException in case of error while performing the query
6907    * @see com.xpn.xwiki.store.XWikiStoreInterface#searchDocuments(String, int, int, java.util.List, XWikiContext)
6908    * @since 5.0M2
6909    */
 
6910  2 toggle public List<XWikiAttachment> searchAttachments(String parametrizedSqlClause, boolean checkRight, int nb, int start,
6911    List<?> parameterValues, XWikiContext context) throws XWikiException
6912    {
6913  2 parametrizedSqlClause = parametrizedSqlClause.trim().replaceFirst("^and ", "").replaceFirst("^where ", "");
6914   
6915    // Get the attachment filenames and document fullNames
6916  2 List<java.lang.Object[]> results = this.getStore().search(
6917    "select attach.filename, doc.fullName from XWikiAttachment attach, XWikiDocument doc where doc.id = attach.docId and "
6918    + parametrizedSqlClause,
6919    nb, start, parameterValues, context);
6920   
6921  2 HashMap<String, List<String>> filenamesByDocFullName = new HashMap<String, List<String>>();
6922   
6923    // Put each attachment name with the document name it belongs to
6924  5 for (int i = 0; i < results.size(); i++) {
6925  3 String filename = (String) results.get(i)[0];
6926  3 String docFullName = (String) results.get(i)[1];
6927  3 if (!filenamesByDocFullName.containsKey(docFullName)) {
6928  3 filenamesByDocFullName.put(docFullName, new ArrayList<String>());
6929    }
6930  3 filenamesByDocFullName.get(docFullName).add(filename);
6931    }
6932   
6933  2 List<XWikiAttachment> out = new ArrayList<XWikiAttachment>();
6934   
6935    // Index through the document names, get relivent attachments
6936  2 for (Map.Entry<String, List<String>> entry : filenamesByDocFullName.entrySet()) {
6937  3 String fullName = entry.getKey();
6938   
6939  3 XWikiDocument doc = getDocument(fullName, context);
6940  3 if (checkRight) {
6941  3 if (!context.getWiki().getRightService().hasAccessLevel("view", context.getUser(), doc.getFullName(),
6942    context)) {
6943  0 continue;
6944    }
6945    }
6946  3 List<String> returnedAttachmentNames = entry.getValue();
6947  3 for (XWikiAttachment attach : doc.getAttachmentList()) {
6948  3 if (returnedAttachmentNames.contains(attach.getFilename())) {
6949  3 out.add(attach);
6950    }
6951    }
6952    }
6953   
6954  2 return out;
6955    }
6956   
6957    /**
6958    * Count attachments returned by a given parameterized query
6959    *
6960    * @param parametrizedSqlClause Everything which would follow the "WHERE" in HQL
6961    * @param parameterValues A {@link java.util.List} of the where clause values that replace the question marks (?)
6962    * @param context see {@link XWikiContext}
6963    * @return int number of attachments found.
6964    * @throws XWikiException in event of an exception querying the database
6965    * @see #searchAttachments(String, boolean, int, int, java.util.List, XWikiContext)
6966    * @since 5.0M2
6967    */
 
6968  2 toggle public int countAttachments(String parametrizedSqlClause, List<?> parameterValues, XWikiContext context)
6969    throws XWikiException
6970    {
6971  2 parametrizedSqlClause = parametrizedSqlClause.trim().replaceFirst("^and ", "").replaceFirst("^where ", "");
6972   
6973  2 List l = getStore().search("select count(attach) from XWikiAttachment attach, XWikiDocument doc where "
6974    + "attach.docId=doc.id and " + parametrizedSqlClause, 0, 0, parameterValues, context);
6975  2 return ((Number) l.get(0)).intValue();
6976    }
6977   
6978    // Deprecated
6979   
6980    /**
6981    * @deprecated since 6.1M2, use {@link XWikiCfgConfigurationSource#getConfigPath()} instead
6982    */
 
6983  0 toggle @Deprecated
6984    public static String getConfigPath() throws NamingException
6985    {
6986  0 return XWikiCfgConfigurationSource.getConfigPath();
6987    }
6988   
6989    /**
6990    * @deprecated since 6.1M3, use {@link #XWiki(XWikiContext)} instead
6991    */
 
6992  27 toggle @Deprecated
6993    public XWiki(XWikiConfig config, XWikiContext context) throws XWikiException
6994    {
6995  27 this(config, context, null, false);
6996    }
6997   
6998    /**
6999    * @deprecated since 6.1M3, use {@link #XWiki(XWikiContext, XWikiEngineContext, boolean)} instead
7000    */
 
7001  55 toggle @Deprecated
7002    public XWiki(XWikiConfig config, XWikiContext context, XWikiEngineContext engine_context, boolean noupdate)
7003    throws XWikiException
7004    {
7005  55 initXWiki(config, context, engine_context, noupdate);
7006    }
7007   
7008    /**
7009    * @deprecated use {@link #XWiki(XWikiContext)} instead
7010    */
 
7011  0 toggle @Deprecated
7012    public XWiki(String xwikicfgpath, XWikiContext context) throws XWikiException
7013    {
7014  0 this(xwikicfgpath, context, null, false);
7015    }
7016   
7017    /**
7018    * @deprecated use {@link #XWiki(XWikiContext, XWikiEngineContext, boolean)} instead
7019    */
 
7020  0 toggle @Deprecated
7021    public XWiki(String xwikicfgpath, XWikiContext context, XWikiEngineContext engine_context, boolean noupdate)
7022    throws XWikiException
7023    {
7024  0 try {
7025  0 initXWiki(new XWikiConfig(new FileInputStream(xwikicfgpath)), context, engine_context, noupdate);
7026    } catch (FileNotFoundException e) {
7027  0 Object[] args = { xwikicfgpath };
7028  0 throw new XWikiException(XWikiException.MODULE_XWIKI_CONFIG, XWikiException.ERROR_XWIKI_CONFIG_FILENOTFOUND,
7029    "Configuration file {0} not found", e, args);
7030    }
7031    }
7032   
7033    /**
7034    * @deprecated use {@link #XWiki(XWikiContext, XWikiEngineContext, boolean)} instead
7035    */
 
7036  0 toggle @Deprecated
7037    public XWiki(InputStream is, XWikiContext context, XWikiEngineContext engine_context) throws XWikiException
7038    {
7039  0 initXWiki(new XWikiConfig(is), context, engine_context, true);
7040    }
7041   
7042    /**
7043    * @deprecated since 6.1M2, use {@link ConfigurationSource} component with hint <code>xwikicfg</code> instead
7044    */
 
7045  17272 toggle @Deprecated
7046    public XWikiConfig getConfig()
7047    {
7048  17272 return new XWikiConfigDelegate(getConfiguration());
7049    }
7050   
7051    /**
7052    * @deprecated since 6.1M2
7053    */
 
7054  66 toggle @Deprecated
7055    public void setConfig(XWikiConfig config)
7056    {
7057  66 ConfigurationSource configuration = getConfiguration();
7058   
7059  66 if (configuration instanceof XWikiCfgConfigurationSource) {
7060  28 ((XWikiCfgConfigurationSource) configuration).set(config);
7061    }
7062    }
7063   
7064    /**
7065    * @deprecated since 6.1M2, use {@link ConfigurationSource} component with hint <code>xwikicfg</code> instead
7066    */
 
7067  71360 toggle @Deprecated
7068    public String Param(String key)
7069    {
7070  71356 return Param(key, null);
7071    }
7072   
7073    /**
7074    * @deprecated since 6.1M2, use {@link ConfigurationSource} component with hint <code>xwikicfg</code> instead
7075    */
 
7076  137559 toggle @Deprecated
7077    public String Param(String key, String default_value)
7078    {
7079  137586 if (getConfiguration() != null) {
7080  137580 return getConfiguration().getProperty(key, default_value);
7081    }
7082   
7083  0 return default_value;
7084    }
7085   
7086    /**
7087    * @deprecated since 6.1M2, use {@link ConfigurationSource} component with hint <code>xwikicfg</code> instead
7088    */
 
7089  0 toggle @Deprecated
7090    public long ParamAsLong(String key)
7091    {
7092  0 return getConfiguration().getProperty(key, long.class);
7093    }
7094   
7095    /**
7096    * @deprecated since 6.1M2, use {@link ConfigurationSource} component with hint <code>xwikicfg</code> instead
7097    */
 
7098  11625 toggle @Deprecated
7099    public long ParamAsLong(String key, long default_value)
7100    {
7101  11625 return getConfiguration().getProperty(key, default_value);
7102    }
7103    }