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

File Document.java

 

Coverage histogram

../../../../img/srcFileCovDistChart5.png
74% of files have more coverage

Code metrics

212
689
242
1
3,078
1,773
397
0.58
2.85
242
1.64

Classes

Class Line # Actions
Document 89 689 0% 397 639
0.4409448844.1%
 

Contributing tests

This file is covered by 55 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.api;
21   
22    import java.io.IOException;
23    import java.io.InputStream;
24    import java.util.ArrayList;
25    import java.util.Collections;
26    import java.util.Date;
27    import java.util.HashMap;
28    import java.util.List;
29    import java.util.Locale;
30    import java.util.Map;
31    import java.util.Vector;
32   
33    import org.apache.commons.fileupload.FileItem;
34    import org.apache.commons.lang3.StringUtils;
35    import org.slf4j.Logger;
36    import org.slf4j.LoggerFactory;
37    import org.suigeneris.jrcs.diff.DifferentiationFailedException;
38    import org.suigeneris.jrcs.diff.delta.Delta;
39    import org.suigeneris.jrcs.rcs.Version;
40    import org.xwiki.context.Execution;
41    import org.xwiki.context.ExecutionContext;
42    import org.xwiki.display.internal.DocumentDisplayerParameters;
43    import org.xwiki.filter.output.OutputTarget;
44    import org.xwiki.model.reference.DocumentReference;
45    import org.xwiki.model.reference.DocumentReferenceResolver;
46    import org.xwiki.model.reference.EntityReferenceSerializer;
47    import org.xwiki.rendering.block.XDOM;
48    import org.xwiki.rendering.parser.ParseException;
49    import org.xwiki.rendering.syntax.Syntax;
50    import org.xwiki.rendering.syntax.SyntaxFactory;
51    import org.xwiki.security.authorization.ContextualAuthorizationManager;
52   
53    import com.xpn.xwiki.XWiki;
54    import com.xpn.xwiki.XWikiConstant;
55    import com.xpn.xwiki.XWikiContext;
56    import com.xpn.xwiki.XWikiException;
57    import com.xpn.xwiki.criteria.impl.Period;
58    import com.xpn.xwiki.criteria.impl.PeriodFactory;
59    import com.xpn.xwiki.criteria.impl.Range;
60    import com.xpn.xwiki.criteria.impl.RangeFactory;
61    import com.xpn.xwiki.criteria.impl.RevisionCriteria;
62    import com.xpn.xwiki.criteria.impl.Scope;
63    import com.xpn.xwiki.criteria.impl.ScopeFactory;
64    import com.xpn.xwiki.doc.MetaDataDiff;
65    import com.xpn.xwiki.doc.XWikiAttachment;
66    import com.xpn.xwiki.doc.XWikiDocument;
67    import com.xpn.xwiki.doc.XWikiDocumentArchive;
68    import com.xpn.xwiki.doc.XWikiLink;
69    import com.xpn.xwiki.doc.XWikiLock;
70    import com.xpn.xwiki.objects.BaseObject;
71    import com.xpn.xwiki.objects.BaseProperty;
72    import com.xpn.xwiki.objects.ObjectDiff;
73    import com.xpn.xwiki.objects.classes.BaseClass;
74    import com.xpn.xwiki.plugin.fileupload.FileUploadPlugin;
75    import com.xpn.xwiki.stats.api.XWikiStatsService;
76    import com.xpn.xwiki.stats.impl.DocumentStats;
77    import com.xpn.xwiki.stats.impl.RefererStats;
78    import com.xpn.xwiki.util.TOCGenerator;
79    import com.xpn.xwiki.util.Util;
80    import com.xpn.xwiki.web.Utils;
81   
82    /**
83    * This class represents a document or page in the wiki. This is a security and usability wrapper which wraps
84    * {@link com.xpn.xwiki.doc.XWikiDocument} In scripting, an object representing the document in which the script resides
85    * will be bound to a variable called doc.
86    *
87    * @version $Id: 039f9cc83c29abae191e55008e591d95778dfb46 $
88    */
 
89    public class Document extends Api
90    {
91    /** Logging helper object. */
92    private static final Logger LOGGER = LoggerFactory.getLogger(Document.class);
93   
94    /**
95    * The XWikiDocument object wrapped by this API.
96    */
97    protected XWikiDocument initialDoc;
98   
99    /**
100    * The XWikiDocument object wrapped by this API.
101    */
102    protected XWikiDocument doc;
103   
104    /**
105    * Convenience object used by object related methods.
106    */
107    protected Object currentObj;
108   
109    /**
110    * Used to resolve a string into a proper Document Reference using the current document's reference to fill the
111    * blanks, except for the page name for which the default page name is used instead and for the wiki name for which
112    * the current wiki is used instead of the current document reference's wiki.
113    */
114    private DocumentReferenceResolver<String> currentMixedDocumentReferenceResolver;
115   
116    /**
117    * Used to convert a proper Document Reference to string (standard form).
118    */
119    private EntityReferenceSerializer<String> defaultEntityReferenceSerializer;
120   
121    /**
122    * Used to convert a proper Document Reference to a string but without the wiki name.
123    */
124    private EntityReferenceSerializer<String> localEntityReferenceSerializer;
125   
126    /**
127    * Used to convert user references to string.
128    */
129    private EntityReferenceSerializer<String> compactWikiEntityReferenceSerializer;
130   
131    /**
132    * Authorization manager used to check rights.
133    */
134    private ContextualAuthorizationManager authorizationManager;
135   
 
136  2 toggle private DocumentReferenceResolver<String> getCurrentMixedDocumentReferenceResolver()
137    {
138  2 if (this.currentMixedDocumentReferenceResolver == null) {
139  2 this.currentMixedDocumentReferenceResolver =
140    Utils.getComponent(DocumentReferenceResolver.TYPE_STRING, "currentmixed");
141    }
142   
143  2 return this.currentMixedDocumentReferenceResolver;
144    }
145   
 
146  1477 toggle private EntityReferenceSerializer<String> getDefaultEntityReferenceSerializer()
147    {
148  1477 if (this.defaultEntityReferenceSerializer == null) {
149  988 this.defaultEntityReferenceSerializer = Utils.getComponent(EntityReferenceSerializer.TYPE_STRING);
150    }
151   
152  1477 return this.defaultEntityReferenceSerializer;
153    }
154   
 
155  6768 toggle private EntityReferenceSerializer<String> getLocalEntityReferenceSerializer()
156    {
157  6768 if (this.localEntityReferenceSerializer == null) {
158  3385 this.localEntityReferenceSerializer = Utils.getComponent(EntityReferenceSerializer.TYPE_STRING, "local");
159    }
160   
161  6768 return this.localEntityReferenceSerializer;
162    }
163   
 
164  0 toggle private EntityReferenceSerializer<String> getCompactWikiEntityReferenceSerializer()
165    {
166  0 if (this.compactWikiEntityReferenceSerializer == null) {
167  0 this.compactWikiEntityReferenceSerializer =
168    Utils.getComponent(EntityReferenceSerializer.TYPE_STRING, "compactwiki");
169    }
170   
171  0 return this.compactWikiEntityReferenceSerializer;
172    }
173   
174    /**
175    * Document constructor.
176    *
177    * @param doc The XWikiDocument object to wrap.
178    * @param context The current request context.
179    */
 
180  193439 toggle public Document(XWikiDocument doc, XWikiContext context)
181    {
182  193470 super(context);
183   
184  193433 this.initialDoc = doc;
185  193432 this.doc = this.initialDoc;
186    }
187   
188    /**
189    * Get the XWikiDocument wrapped by this API. This function is accessible only if you have the programming rights
190    * give access to the priviledged API of the Document.
191    *
192    * @return The XWikiDocument wrapped by this API.
193    */
 
194  8 toggle public XWikiDocument getDocument()
195    {
196  8 if (hasProgrammingRights()) {
197  8 return this.doc;
198    } else {
199  0 return null;
200    }
201    }
202   
203    /**
204    * Get a clone of the XWikiDocument wrapped by this API.
205    *
206    * @return A clone of the XWikiDocument wrapped by this API.
207    */
 
208  27192 toggle protected XWikiDocument getDoc()
209    {
210  27192 if (this.initialDoc == this.doc) {
211  18529 this.doc = this.initialDoc.clone();
212    }
213   
214  27194 return this.doc;
215    }
216   
217    /**
218    * return the ID of the document. this ID is unique across the wiki.
219    *
220    * @return the id of the document.
221    */
 
222  0 toggle public long getId()
223    {
224  0 return this.doc.getId();
225    }
226   
227    /**
228    * returns the DocumentReference for the current document
229    *
230    * @return the DocumentReference of the current document
231    * @since 2.3M1
232    */
 
233  14240 toggle public DocumentReference getDocumentReference()
234    {
235  14239 return this.doc.getDocumentReference();
236    }
237   
238    /**
239    * return the name of a document. for example if the fullName of a document is "MySpace.Mydoc", the name is MyDoc.
240    *
241    * @return the name of the document
242    */
 
243  9101 toggle public String getName()
244    {
245  9099 return this.doc.getDocumentReference().getName();
246    }
247   
248    /**
249    * Return the full local space reference of the Document. For example a document located in sub-space
250    * <code>space11</code> of space <code>space1</code> will return <code>space1.space11</code>.
251    *
252    * @return the name of the spaces of the document
253    */
 
254  8570 toggle public String getSpace()
255    {
256  8569 return this.doc.getSpace();
257    }
258   
259    /**
260    * Get the name wiki where the document is stored.
261    *
262    * @return The name of the wiki where this document is stored.
263    * @since 1.1.2
264    * @since 1.2M2
265    */
 
266  4282 toggle public String getWiki()
267    {
268  4282 return this.doc.getDocumentReference().getWikiReference().getName();
269    }
270   
271    /**
272    * Get the fullName of the document. If a document is named "MyDoc" in space "MySpace", the fullname is
273    * "MySpace.MyDoc". In a wiki, all the documents have a different fullName.
274    *
275    * @return fullName of the document.
276    */
 
277  6460 toggle public String getFullName()
278    {
279  6460 return getLocalEntityReferenceSerializer().serialize(this.doc.getDocumentReference());
280    }
281   
282    /**
283    * Get the complete fullName of the document. The real full name of the document containing the name of the wiki
284    * where the document is stored. For a document stored in the wiki "xwiki", in space "MySpace", named "MyDoc", its
285    * complete full name is "xwiki:MySpace.MyDoc".
286    *
287    * @return The complete fullName of the document.
288    * @since 1.1.2
289    * @since 1.2M2
290    */
 
291  1476 toggle public String getPrefixedFullName()
292    {
293  1476 return getDefaultEntityReferenceSerializer().serialize(this.doc.getDocumentReference());
294    }
295   
296    /**
297    * Get a Version object representing the current version of the document.
298    *
299    * @return A Version object representing the current version of the document
300    */
 
301  852 toggle public Version getRCSVersion()
302    {
303  852 return this.doc.getRCSVersion();
304    }
305   
306    /**
307    * Get a string representing the current version of the document.
308    *
309    * @return A string representing the current version of the document.
310    */
 
311  1848 toggle public String getVersion()
312    {
313  1848 return this.doc.getVersion();
314    }
315   
316    /**
317    * Get a string representing the previous version of the document.
318    *
319    * @return A string representing the previous version of the document. If this is the first version then it returns
320    * null.
321    */
 
322  0 toggle public String getPreviousVersion()
323    {
324  0 return this.doc.getPreviousVersion();
325    }
326   
327    /**
328    * Get the value of the title field of the document.
329    *
330    * @return The value of the title field of the document.
331    */
 
332  454 toggle public String getTitle()
333    {
334  454 return this.doc.getTitle();
335    }
336   
337    /**
338    * Get document title. If a title has not been provided through the title field, it looks for a section title in the
339    * document's content and if not found return the page name. The returned title is also interpreted which means it's
340    * allowed to use Velocity, Groovy, etc syntax within a title.
341    *
342    * @return The document title as XHTML
343    */
 
344  15896 toggle public String getDisplayTitle()
345    {
346  15896 return this.doc.getRenderedTitle(getXWikiContext());
347    }
348   
349    /**
350    * Returns the document title as plain text
351    *
352    * @return the document title as plain text (all markup removed)
353    * @since 3.0M1
354    */
 
355  2493 toggle public String getPlainTitle()
356    {
357  2493 return this.doc.getRenderedTitle(Syntax.PLAIN_1_0, getXWikiContext());
358    }
359   
360    /**
361    * Returns the title of the document rendered through wiki syntax and velocity
362    *
363    * @return the title rendered through wiki syntax and velocity
364    * @see XWikiDocument#getRenderedTitle(Syntax, XWikiContext)
365    */
 
366  373 toggle public String getRenderedTitle(String syntaxId) throws XWikiException
367    {
368  373 try {
369  373 return this.doc.getRenderedTitle(Utils.getComponent(SyntaxFactory.class).createSyntaxFromIdString(syntaxId),
370    getXWikiContext());
371    } catch (ParseException e) {
372  0 LOGGER.error("Failed to parse provided syntax identifier [" + syntaxId + "]", e);
373   
374  0 throw new XWikiException(XWikiException.MODULE_XWIKI_RENDERING, XWikiException.ERROR_XWIKI_UNKNOWN,
375    "Failed to parse syntax identifier [" + syntaxId + "]", e);
376    } catch (Exception e) {
377  0 LOGGER.error("Failed to render document [" + getPrefixedFullName() + "] title content", e);
378   
379  0 throw new XWikiException(XWikiException.MODULE_XWIKI_RENDERING, XWikiException.ERROR_XWIKI_UNKNOWN,
380    "Failed to render document [" + getPrefixedFullName() + "] content title", e);
381    }
382    }
383   
384    /**
385    * TODO document this or mark it deprecated
386    */
 
387  0 toggle public String getFormat()
388    {
389  0 return this.doc.getFormat();
390    }
391   
392    /**
393    * Get fullName of the profile document of the author of the current version of the document. Example: XWiki.Admin.
394    *
395    * @return The fullName of the profile document of the author of the current version of the document.
396    */
 
397  1202 toggle public String getAuthor()
398    {
399  1202 return this.doc.getAuthor();
400    }
401   
402    /**
403    * @return the document author reference
404    * @since 6.4RC1
405    */
 
406  84 toggle public DocumentReference getAuthorReference()
407    {
408  84 return this.doc.getAuthorReference();
409    }
410   
411    /**
412    * Get fullName of the profile document of the author of the content modification of this document version. Example:
413    * XWiki.Admin.
414    *
415    * @return The fullName of the profile document of the author of the content modification in this document version.
416    */
 
417  428 toggle public String getContentAuthor()
418    {
419  428 return this.doc.getContentAuthor();
420    }
421   
422    /**
423    * @return the document content author reference
424    * @since 6.4RC1
425    */
 
426  6 toggle public DocumentReference getContentAuthorReference()
427    {
428  6 return this.doc.getContentAuthorReference();
429    }
430   
431    /**
432    * @return The date when this document version has been modified.
433    */
 
434  520 toggle public Date getDate()
435    {
436  520 return this.doc.getDate();
437    }
438   
439    /**
440    * Get the date when the content modification has been done on this document version. A content update excludes
441    * modifications to meta data fields or comments of the document.
442    *
443    * @return The date where the content modification has been done on this document version.
444    */
 
445  415 toggle public Date getContentUpdateDate()
446    {
447  415 return this.doc.getContentUpdateDate();
448    }
449   
450    /**
451    * @return the original creation date of the document.
452    */
 
453  868 toggle public Date getCreationDate()
454    {
455  868 return this.doc.getCreationDate();
456    }
457   
458    /**
459    * Get the name of the parent of this document.
460    *
461    * @return The name of the parent of this document.
462    */
 
463  7668 toggle public String getParent()
464    {
465  7667 return this.doc.getParent();
466    }
467   
468    /**
469    * @return the parent reference or null if the parent is not set
470    * @since 7.3M1
471    */
 
472  553 toggle public DocumentReference getParentReference()
473    {
474  553 return this.doc.getParentReference();
475    }
476   
477    /**
478    * Get fullName of the profile document of the document creator.
479    *
480    * @return The fullName of the profile document of the document creator.
481    */
 
482  833 toggle public String getCreator()
483    {
484  833 return this.doc.getCreator();
485    }
486   
487    /**
488    * @return the document creator reference
489    * @since 6.4RC1
490    */
 
491  84 toggle public DocumentReference getCreatorReference()
492    {
493  84 return this.doc.getCreatorReference();
494    }
495   
496    /**
497    * Get raw content of the document, i.e. the content that is visible through the wiki editor.
498    *
499    * @return The raw content of the document.
500    */
 
501  479 toggle public String getContent()
502    {
503  479 return this.doc.getContent();
504    }
505   
506    /**
507    * NOTE: This method caches the XDOM and returns a clone that can be safely modified.
508    *
509    * @return the XDOM corresponding to the document's string content
510    * @since 7.0RC1
511    */
 
512  0 toggle public XDOM getXDOM()
513    {
514  0 return this.doc.getXDOM();
515    }
516   
517    /**
518    * @return The syntax representing the syntax used for the document's content
519    * @since 2.3M1
520    */
 
521  4033 toggle public Syntax getSyntax()
522    {
523  4032 return this.doc.getSyntax();
524    }
525   
526    /**
527    * Get the Syntax id representing the syntax used for the document. For example "xwiki/1.0" represents the first
528    * version XWiki syntax while "xwiki/2.0" represents version 2.0 of the XWiki Syntax.
529    *
530    * @return The syntax id representing the syntax used for the document.
531    * @deprecated since 2.3M1 use {@link #getSyntax()} instead
532    */
 
533  3 toggle @Deprecated
534    public String getSyntaxId()
535    {
536  3 return this.doc.getSyntax().toIdString();
537    }
538   
539    /**
540    * Same as {@link #getLocale()} but as String.
541    *
542    * @return the locale of the document.
543    * @deprecated since 5.4M1 use {@link #getLocale()} instead
544    */
 
545  0 toggle @Deprecated
546    public String getLanguage()
547    {
548  0 return this.doc.getLanguage();
549    }
550   
551    /**
552    * Get the locale of the document. If the document is a translation it returns the locale set for it, otherwise, it
553    * returns the root locale.
554    *
555    * @return the locale of the document
556    * @since 5.4M1
557    */
 
558  720 toggle public Locale getLocale()
559    {
560  718 return this.doc.getLocale();
561    }
562   
563    /**
564    * TODO document this or mark it deprecated
565    */
 
566  0 toggle public String getTemplate()
567    {
568  0 String templateReferenceAsString = "";
569  0 DocumentReference templateDocumentReference = this.doc.getTemplateDocumentReference();
570  0 if (templateDocumentReference != null) {
571  0 templateReferenceAsString = getLocalEntityReferenceSerializer().serialize(templateDocumentReference);
572    }
573  0 return templateReferenceAsString;
574    }
575   
576    /**
577    * Same as {@link #getRealLocale()} but as String.
578    *
579    * @return the real locale
580    * @deprecated since 8.0M1, use {@link #getRealLocale()} instead
581    */
 
582  22 toggle @Deprecated
583    public String getRealLanguage() throws XWikiException
584    {
585  22 return this.doc.getRealLanguage(getXWikiContext());
586    }
587   
588    /**
589    * Gets the real locale of the document. The real locale is either the default locale field when the locale field is
590    * empty (when the document is the default document) or the locale field otherwise when the document is a
591    * translation document
592    *
593    * @return the actual locale of the document
594    * @since 8.0M1
595    */
 
596  772 toggle public Locale getRealLocale()
597    {
598  772 return this.doc.getRealLocale();
599    }
600   
601    /**
602    * Same as {@link #getDefaultLocale()} but as String.
603    *
604    * @return the locale of the default document
605    * @deprecated since 8.0M1, use {@link #getDefaultLocale()} instead
606    */
 
607  11 toggle @Deprecated
608    public String getDefaultLanguage()
609    {
610  11 return this.doc.getDefaultLanguage();
611    }
612   
613    /**
614    * @return the Locale of the default version of the document (usually {@link Locale#ROOT} or {@link Locale#ENGLISH})
615    * @since 8.0M1
616    */
 
617  0 toggle public Locale getDefaultLocale()
618    {
619  0 return this.doc.getDefaultLocale();
620    }
621   
622    /**
623    * TODO document this or mark it deprecated
624    */
 
625  0 toggle public String getDefaultTemplate()
626    {
627  0 return this.doc.getDefaultTemplate();
628    }
629   
630    /**
631    * @return the comment of of the document version
632    */
 
633  419 toggle public String getComment()
634    {
635  419 return this.doc.getComment();
636    }
637   
638    /**
639    * @return true if the this document version was a minor edit.
640    */
 
641  0 toggle public boolean isMinorEdit()
642    {
643  0 return this.doc.isMinorEdit();
644    }
645   
646    /**
647    * @return the list of existing translations for this document.
648    */
 
649  553 toggle public List<String> getTranslationList() throws XWikiException
650    {
651  553 return this.doc.getTranslationList(getXWikiContext());
652    }
653   
654    /**
655    * @return the translated document's content if the wiki is multilingual, the locale is first checked in the URL,
656    * the cookie, the user profile and finally the wiki configuration if not, the locale is the one on the wiki
657    * configuration.
658    */
 
659  158 toggle public String getTranslatedContent() throws XWikiException
660    {
661  158 return this.doc.getTranslatedContent(getXWikiContext());
662    }
663   
664    /**
665    * @return the translated content in the given locale
666    */
 
667  0 toggle public String getTranslatedContent(String locale) throws XWikiException
668    {
669  0 return this.doc.getTranslatedContent(locale, getXWikiContext());
670    }
671   
672    /**
673    * @return the translated document in the given locale
674    */
 
675  0 toggle public Document getTranslatedDocument(String locale) throws XWikiException
676    {
677  0 return this.doc.getTranslatedDocument(locale, getXWikiContext()).newDocument(getXWikiContext());
678    }
679   
680    /**
681    * @return the tranlated Document if the wiki is multilingual, the locale is first checked in the URL, the cookie,
682    * the user profile and finally the wiki configuration if not, the locale is the one on the wiki
683    * configuration.
684    */
 
685  14861 toggle public Document getTranslatedDocument() throws XWikiException
686    {
687  14861 return this.doc.getTranslatedDocument(getXWikiContext()).newDocument(getXWikiContext());
688    }
689   
690    /**
691    * @return the content of the document rendered.
692    */
 
693  592 toggle public String getRenderedContent() throws XWikiException
694    {
695  592 return this.doc.getRenderedContent(getXWikiContext());
696    }
697   
698    /**
699    * Execute and render the document in the current context.
700    * <p>
701    * The code is executed with right of this document content author.
702    *
703    * @param transformationContextIsolated see {@link DocumentDisplayerParameters#isTransformationContextIsolated()}
704    * @return the result
705    * @throws XWikiException when failing to display the document
706    * @since 8.4RC1
707    */
 
708  0 toggle public String getRenderedContent(boolean transformationContextIsolated) throws XWikiException
709    {
710  0 return this.doc.getRenderedContent(transformationContextIsolated, getXWikiContext());
711    }
712   
713    /**
714    * @param text the text to render
715    * @return the given text rendered in the context of this document
716    * @deprecated since 1.6M1 use {@link #getRenderedContent(String, String)}
717    */
 
718  0 toggle @Deprecated
719    public String getRenderedContent(String text) throws XWikiException
720    {
721  0 return getRenderedContent(text, Syntax.XWIKI_1_0.toIdString());
722    }
723   
724    /**
725    * @param text the text to render
726    * @param syntaxId the id of the Syntax used by the passed text (for example: "xwiki/1.0")
727    * @return the given text rendered in the context of this document using the passed Syntax
728    * @since 1.6M1
729    */
 
730  12 toggle public String getRenderedContent(String text, String syntaxId) throws XWikiException
731    {
732  12 return getRenderedContent(text, syntaxId, false);
733    }
734   
735    /**
736    * Render a text in a restricted mode, where script macros are completely disabled.
737    *
738    * @param text the text to render
739    * @param syntaxId the id of the Syntax used by the passed text (for example: "xwiki/1.0")
740    * @return the given text rendered in the context of this document using the passed Syntax
741    * @since 4.2M1
742    */
 
743  18 toggle public String getRenderedContentRestricted(String text, String syntaxId) throws XWikiException
744    {
745  18 return getRenderedContent(text, syntaxId, true);
746    }
747   
748    /**
749    * Render a text in a restricted mode, where script macros are completely disabled.
750    *
751    * @param text the text to render
752    * @param syntaxId the id of the Syntax used by the passed text (for example: "xwiki/1.0")
753    * @param restrictedTransformationContext see {@link DocumentDisplayerParameters#isTransformationContextRestricted}.
754    * @return the given text rendered in the context of this document using the passed Syntax
755    */
 
756  30 toggle private String getRenderedContent(String text, String syntaxId, boolean restricted) throws XWikiException
757    {
758    // Make sure we keep using current author as passed content author
759  30 return this.doc.getRenderedContent(text, syntaxId, restricted, getCallerDocument(getXWikiContext()),
760    getXWikiContext());
761    }
762   
763    /**
764    * @param text the text to render
765    * @param sourceSyntaxId the id of the Syntax used by the passed text (for example: "xwiki/1.0")
766    * @param targetSyntaxId the id of the syntax in which to render the document content
767    * @return the given text rendered in the context of this document using the passed Syntax
768    * @since 2.0M3
769    */
 
770  4 toggle public String getRenderedContent(String text, String sourceSyntaxId, String targetSyntaxId) throws XWikiException
771    {
772    // Make sure we keep using current author as passed content author
773  4 return this.doc.getRenderedContent(text, sourceSyntaxId, targetSyntaxId, false,
774    getCallerDocument(getXWikiContext()), getXWikiContext());
775    }
776   
 
777  34 toggle private XWikiDocument getCallerDocument(XWikiContext xcontext)
778    {
779  34 XWikiDocument sdoc = (XWikiDocument) xcontext.get("sdoc");
780  34 if (sdoc == null) {
781  7 sdoc = xcontext.getDoc();
782    }
783   
784  34 return sdoc;
785    }
786   
787    /**
788    * @param targetSyntax the syntax in which to render the document content
789    * @return the rendered content
790    * @throws XWikiException error when rendering content
791    */
 
792  5207 toggle public String getRenderedContent(Syntax targetSyntax) throws XWikiException
793    {
794  5207 return this.doc.getRenderedContent(targetSyntax, getXWikiContext());
795    }
796   
797    /**
798    * Get the document's content XML-escaped.
799    *
800    * @return an XML-escaped version of the content of this document.
801    */
 
802  0 toggle public String getEscapedContent() throws XWikiException
803    {
804  0 return this.doc.getEscapedContent(getXWikiContext());
805    }
806   
807    /**
808    * @return the archive of this document's history in string format
809    */
 
810  0 toggle public String getArchive() throws XWikiException
811    {
812  0 return this.doc.getDocumentArchive(getXWikiContext()).getArchive(getXWikiContext());
813    }
814   
815    /**
816    * Get the archive of this document's history. This function is accessible only if you have the programming rights.
817    *
818    * @return the archive of this document's history as an {@link XWikiDocumentArchive}.
819    */
 
820  0 toggle public XWikiDocumentArchive getDocumentArchive() throws XWikiException
821    {
822  0 if (hasProgrammingRights()) {
823  0 return this.doc.getDocumentArchive(getXWikiContext());
824    }
825  0 return null;
826    }
827   
828    /**
829    * @return true if the document is a new one (ie it has never been saved) or false otherwise
830    */
 
831  9189 toggle public boolean isNew()
832    {
833  9186 return this.doc.isNew();
834    }
835   
836    /**
837    * Return the relative URL of download for the the given attachment name.
838    *
839    * @param filename the name of the attachment
840    * @return A String with the URL or null if the file name is empty
841    */
 
842  10 toggle public String getAttachmentURL(String filename)
843    {
844  10 return this.doc.getAttachmentURL(filename, getXWikiContext());
845    }
846   
847    /**
848    * Get the relative URL of the given action for the the given attachment name.
849    *
850    * @param filename the name of the attachment.
851    * @param action what to do to the file for example "delattachment", "download" or "downloadrev".
852    * @return a string representation of a URL to do the given operation or null if the file name is empty
853    */
 
854  3 toggle public String getAttachmentURL(String filename, String action)
855    {
856  3 return this.doc.getAttachmentURL(filename, action, getXWikiContext());
857    }
858   
859    /**
860    * Get the relative URL of an action on an attachment. the given action for the the given attachment name with
861    * "queryString" parameters
862    *
863    * @param filename the name of the attachment.
864    * @param action what to do to the file for example "delattachment", "download" or "downloadrev"
865    * @param queryString parameters added to the URL, the "rev" parameter is used to specify a revision if using the
866    * "downloadrev" action. The query string must not begin with an ? character.
867    * @return a string representation of a URL to do the given operation or null if the file name is empty
868    */
 
869  24 toggle public String getAttachmentURL(String filename, String action, String queryString)
870    {
871  24 return this.doc.getAttachmentURL(filename, action, queryString, getXWikiContext());
872    }
873   
874    /**
875    * Get an old revision of an attachment.
876    *
877    * @param filename the name of the attachment.
878    * @param version a revision number such as "1.1" or "1.2".
879    * @return the URL for accessing to the archive of the attachment "filename" at the version "version" or null if the
880    * file name is empty
881    */
 
882  0 toggle public String getAttachmentRevisionURL(String filename, String version)
883    {
884  0 return this.doc.getAttachmentRevisionURL(filename, version, getXWikiContext());
885    }
886   
887    /**
888    * Get an old revision of an attachment.
889    *
890    * @param filename the name of the attachment.
891    * @param version a revision number such as "1.1" or "1.2".
892    * @param queryString additional query parameters to pass in the request.
893    * @return the URL for accessing to the archive of the attachment "filename" at the version "version" with the given
894    * queryString parameters or null if the file name is empty
895    */
 
896  0 toggle public String getAttachmentRevisionURL(String filename, String version, String queryString)
897    {
898  0 return this.doc.getAttachmentRevisionURL(filename, version, queryString, getXWikiContext());
899    }
900   
901    /**
902    * Get the URL of this document.
903    *
904    * @return the URL to view this document, this will be a relitive URL for example: /xwiki/bin/view/Main/WebHome
905    * @see #getExternalURL() for an absolute URL which can used outside of the site.
906    */
 
907  7226 toggle public String getURL()
908    {
909  7226 return this.doc.getURL("view", getXWikiContext());
910    }
911   
912    /**
913    * Get the URL to do a given action on this document.
914    *
915    * @param action what to do to the document for example "view", "edit" or "inline".
916    * @return the URL of this document with the given action.
917    * @see #getExternalURL(String) for an absolute URL which can used outside of the site.
918    */
 
919  21415 toggle public String getURL(String action)
920    {
921  21414 return this.doc.getURL(action, getXWikiContext());
922    }
923   
924    /**
925    * Get the URL to do a given action on this document.
926    *
927    * @param action what to do to the document for example "view", "edit" or "inline".
928    * @param queryString parameters to pass in the request eg: {@code paramA=value1&paramB=value2}
929    * @return the URL of this document with the given action and queryString as parameters.
930    * @see #getExternalURL(String, String) for an absolute URL which can used outside of the site.
931    */
 
932  13478 toggle public String getURL(String action, String queryString)
933    {
934  13477 return this.doc.getURL(action, queryString, getXWikiContext());
935    }
936   
937    /**
938    * Get the external URL to do a given action on this document.
939    *
940    * @return the full URL of the document, sutable for use at external websites for example:
941    * http://www.xwiki.org/xwiki/bin/view/Main/WebHome
942    * @see #getURL() for a reletive URL which can only be used inside of the site.
943    */
 
944  17 toggle public String getExternalURL()
945    {
946  17 return this.doc.getExternalURL("view", getXWikiContext());
947    }
948   
949    /**
950    * Get the external URL to do a given action on this document.
951    *
952    * @param action what to do to the document for example "view", "edit" or "inline".
953    * @return the URL of this document with the given action.
954    * @see #getURL() for a relative URL which can only be used inside of the site.
955    */
 
956  553 toggle public String getExternalURL(String action)
957    {
958  553 return this.doc.getExternalURL(action, getXWikiContext());
959    }
960   
961    /**
962    * Get the URL to do a given action on this document.
963    *
964    * @param action what to do to the document for example "view", "edit" or "inline".
965    * @param queryString parameters to pass in the request eg: {@code paramA=value1&paramB=value2}
966    * @return the URL of this document with the given action and queryString as parameters.
967    * @see #getURL() for a relative URL which can only be used inside of the site.
968    */
 
969  25 toggle public String getExternalURL(String action, String queryString)
970    {
971  25 return this.doc.getExternalURL(action, queryString, getXWikiContext());
972    }
973   
974    /**
975    * @return the relative URL of the parent document of this document
976    */
 
977  0 toggle public String getParentURL() throws XWikiException
978    {
979  0 return this.doc.getParentURL(getXWikiContext());
980    }
981   
982    /**
983    * @return the XClass associated to this document when the document represents an XWiki Class
984    */
 
985  585 toggle public Class getxWikiClass()
986    {
987  585 BaseClass bclass = this.getDoc().getXClass();
988  585 if (bclass == null) {
989  0 return null;
990    } else {
991  585 return new Class(bclass, getXWikiContext());
992    }
993    }
994   
995    /**
996    * @return the array of XClasses representing the objects of this document
997    */
 
998  44 toggle public Class[] getxWikiClasses()
999    {
1000  44 List<BaseClass> list = this.getDoc().getXClasses(getXWikiContext());
1001  44 if (list == null) {
1002  0 return null;
1003    }
1004  44 Class[] result = new Class[list.size()];
1005  112 for (int i = 0; i < list.size(); i++) {
1006  68 result[i] = new Class(list.get(i), getXWikiContext());
1007    }
1008  44 return result;
1009    }
1010   
1011    /**
1012    * Creates a New XWiki Object of the given classname
1013    *
1014    * @param classname the classname used
1015    * @return the number of the object created
1016    */
 
1017  80 toggle public int createNewObject(String classname) throws XWikiException
1018    {
1019  80 int index = getDoc().createNewObject(classname, getXWikiContext());
1020   
1021  80 updateAuthor();
1022   
1023  80 return index;
1024    }
1025   
1026    /**
1027    * Creates a New XWiki Object of the given classname
1028    *
1029    * @param classname the classname used
1030    * @return the object created
1031    */
 
1032  77 toggle public Object newObject(String classname) throws XWikiException
1033    {
1034  77 int nb = createNewObject(classname);
1035  77 return getObject(classname, nb);
1036    }
1037   
1038    /**
1039    * @return true of the document has been loaded from cache
1040    */
 
1041  0 toggle public boolean isFromCache()
1042    {
1043  0 return this.doc.isFromCache();
1044    }
1045   
1046    /**
1047    * @param classname the classname used
1048    * @return the number of objects available for a given classname
1049    */
 
1050  0 toggle public int getObjectNumbers(String classname)
1051    {
1052  0 return this.doc.getObjectNumbers(classname);
1053    }
1054   
1055    /**
1056    * Get the list of all objects available in this document organized in a Map by classname
1057    *
1058    * @return the map of objects
1059    */
 
1060  642 toggle public Map<String, Vector<Object>> getxWikiObjects()
1061    {
1062  642 Map<DocumentReference, List<BaseObject>> map = this.getDoc().getXObjects();
1063  642 Map<String, Vector<Object>> resultmap = new HashMap<String, Vector<Object>>();
1064  642 for (Map.Entry<DocumentReference, List<BaseObject>> entry : map.entrySet()) {
1065  308 List<BaseObject> objects = entry.getValue();
1066  308 if (objects != null) {
1067  308 resultmap.put(getLocalEntityReferenceSerializer().serialize(entry.getKey()), getXObjects(objects));
1068    }
1069    }
1070  642 return resultmap;
1071    }
1072   
 
1073  2513 toggle protected Vector<Object> getXObjects(List<BaseObject> objects)
1074    {
1075  2513 if (objects == null) {
1076  1522 return new Vector<Object>(0);
1077    }
1078  991 Vector<Object> result = new Vector<Object>(objects.size());
1079  991 for (BaseObject bobj : objects) {
1080  1220 if (bobj != null) {
1081  1200 result.add(newObjectApi(bobj, getXWikiContext()));
1082    }
1083    }
1084  991 return result;
1085    }
1086   
1087    /**
1088    * Get the list of objects for a given classname classname
1089    *
1090    * @return the vector of objects
1091    */
 
1092  1355 toggle public Vector<Object> getObjects(String className)
1093    {
1094  1355 List<BaseObject> objects = this.getDoc().getXObjects(this.doc.resolveClassReference(className));
1095  1355 return getXObjects(objects);
1096    }
1097   
1098    /**
1099    * Get the first object that contains the given fieldname
1100    *
1101    * @param fieldname name of the field to find in the object
1102    * @return the XWiki Object
1103    */
 
1104  3 toggle public Object getFirstObject(String fieldname)
1105    {
1106  3 try {
1107  3 BaseObject obj = this.getDoc().getFirstObject(fieldname, getXWikiContext());
1108  3 if (obj == null) {
1109  0 return null;
1110    } else {
1111  3 return newObjectApi(obj, getXWikiContext());
1112    }
1113    } catch (Exception e) {
1114  0 return null;
1115    }
1116    }
1117   
1118    /**
1119    * Get the first object of a given classname that has a field name matching the given value
1120    *
1121    * @param classname name of the class of the object to look for
1122    * @param key name of the field to find in the object
1123    * @param value value of the field to find in the object
1124    * @param failover true if the first object will be given when none found
1125    * @return the XWiki Object
1126    */
 
1127  1 toggle public Object getObject(String classname, String key, String value, boolean failover)
1128    {
1129  1 try {
1130  1 BaseObject obj = this.getDoc().getObject(classname, key, value, failover);
1131  1 if (obj == null) {
1132  0 return null;
1133    } else {
1134  1 return newObjectApi(obj, getXWikiContext());
1135    }
1136    } catch (Exception e) {
1137  0 return null;
1138    }
1139    }
1140   
1141    /**
1142    * Select a subset of objects from a given class, filtered on a "key = value" criteria.
1143    *
1144    * @param classname The type of objects to return.
1145    * @param key The name of the property used for filtering.
1146    * @param value The required value.
1147    * @return A Vector of {@link Object objects} matching the criteria. If no objects are found, or if the key is an
1148    * empty String, then an empty vector is returned.
1149    */
 
1150  15 toggle public Vector<Object> getObjects(String classname, String key, String value)
1151    {
1152  15 Vector<Object> result = new Vector<Object>();
1153  15 if (StringUtils.isBlank(key) || value == null) {
1154  0 return getObjects(classname);
1155    }
1156  15 try {
1157  15 Vector<BaseObject> allObjects = this.getDoc().getObjects(classname);
1158  15 if (allObjects == null || allObjects.size() == 0) {
1159  0 return result;
1160    } else {
1161  15 for (BaseObject obj : allObjects) {
1162  40 if (obj != null) {
1163  34 BaseProperty prop = (BaseProperty) obj.get(key);
1164  34 if (prop == null || prop.getValue() == null) {
1165  20 continue;
1166    }
1167  14 if (value.equals(prop.getValue().toString())) {
1168  9 result.add(newObjectApi(obj, getXWikiContext()));
1169    }
1170    }
1171    }
1172    }
1173    } catch (Exception e) {
1174    }
1175  15 return result;
1176    }
1177   
1178    /**
1179    * Get the first object of a given classname that has a field name matching the given value When none found this
1180    * method will return null
1181    *
1182    * @param classname name of the class of the object to look for
1183    * @param key name of the field to find in the object
1184    * @param value value of the field to find in the object
1185    * @return the XWiki Object
1186    */
 
1187  238 toggle public Object getObject(String classname, String key, String value)
1188    {
1189  238 try {
1190  238 BaseObject obj = this.getDoc().getObject(classname, key, value);
1191  238 if (obj == null) {
1192  64 return null;
1193    } else {
1194  174 return newObjectApi(obj, getXWikiContext());
1195    }
1196    } catch (Exception e) {
1197  0 return null;
1198    }
1199    }
1200   
1201    /**
1202