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

File BaseObject.java

 

Coverage histogram

../../../../img/srcFileCovDistChart8.png
54% of files have more coverage

Code metrics

58
109
27
1
395
273
63
0.58
4.04
27
2.33

Classes

Class Line # Actions
BaseObject 43 109 0% 63 46
0.762886676.3%
 

Contributing tests

This file is covered by 116 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.objects;
21   
22    import java.io.Serializable;
23    import java.util.ArrayList;
24    import java.util.List;
25    import java.util.UUID;
26   
27    import org.dom4j.Element;
28    import org.xwiki.model.EntityType;
29    import org.xwiki.model.reference.DocumentReference;
30    import org.xwiki.model.reference.DocumentReferenceResolver;
31    import org.xwiki.model.reference.EntityReference;
32    import org.xwiki.model.reference.SpaceReference;
33   
34    import com.xpn.xwiki.XWikiContext;
35    import com.xpn.xwiki.XWikiException;
36    import com.xpn.xwiki.doc.XWikiDocument;
37    import com.xpn.xwiki.doc.merge.MergeConfiguration;
38    import com.xpn.xwiki.doc.merge.MergeResult;
39    import com.xpn.xwiki.objects.classes.BaseClass;
40    import com.xpn.xwiki.objects.classes.PropertyClass;
41    import com.xpn.xwiki.web.Utils;
42   
 
43    public class BaseObject extends BaseCollection<BaseObjectReference> implements ObjectInterface, Serializable, Cloneable
44    {
45    private String guid = UUID.randomUUID().toString();
46   
47    /**
48    * Used to resolve a string into a proper Document Reference using the current document's reference to fill the
49    * blanks, except for the page name for which the default page name is used instead and for the wiki name for which
50    * the current wiki is used instead of the current document reference's wiki.
51    */
52    private DocumentReferenceResolver<String> currentMixedDocumentReferenceResolver2;
53   
 
54  4857 toggle private DocumentReferenceResolver<String> getCurrentMixedDocumentReferenceResolver()
55    {
56  4857 if (this.currentMixedDocumentReferenceResolver2 == null) {
57  4856 this.currentMixedDocumentReferenceResolver2 =
58    Utils.getComponent(DocumentReferenceResolver.TYPE_STRING, "currentmixed");
59    }
60   
61  4857 return this.currentMixedDocumentReferenceResolver2;
62    }
63   
64    /**
65    * {@inheritDoc}
66    * <p>
67    * Note: This method is overridden to add the deprecation warning so that code using it can see it's deprecated.
68    * </p>
69    *
70    * @deprecated since 2.2M2 use {@link #getDocumentReference()}
71    */
 
72  17090 toggle @Deprecated
73    @Override
74    public String getName()
75    {
76  17090 return super.getName();
77    }
78   
79    /**
80    * {@inheritDoc}
81    * <p>
82    * Note: BaseElement.setName() does not support setting reference anymore since 2.4M2.
83    * </p>
84    *
85    * @deprecated since 2.2M2 use {@link #setDocumentReference(org.xwiki.model.reference.DocumentReference)}
86    */
 
87  4859 toggle @Deprecated
88    @Override
89    public void setName(String name)
90    {
91  4859 DocumentReference reference = getDocumentReference();
92   
93  4856 if (reference != null) {
94  2 EntityReference relativeReference = getRelativeEntityReferenceResolver().resolve(name, EntityType.DOCUMENT);
95  2 reference = new DocumentReference(relativeReference.extractReference(EntityType.DOCUMENT).getName(),
96    new SpaceReference(relativeReference.extractReference(EntityType.SPACE).getName(),
97    reference.getParent().getParent()));
98    } else {
99  4857 reference = getCurrentMixedDocumentReferenceResolver().resolve(name);
100    }
101  4860 setDocumentReference(reference);
102    }
103   
 
104  21095 toggle @Override
105    protected BaseObjectReference createReference()
106    {
107  21092 BaseObjectReference reference;
108   
109  21095 if (getXClassReference() != null && getDocumentReference() != null) {
110  21092 reference = new BaseObjectReference(getXClassReference(), getNumber(), getDocumentReference());
111    } else {
112  2 reference = null;
113    }
114   
115  21092 return reference;
116    }
117   
 
118  85505 toggle @Override
119    public void setNumber(int number)
120    {
121  85506 super.setNumber(number);
122   
123    // Reset reference cache
124  85499 this.referenceCache = null;
125    }
126   
 
127  52626 toggle @Override
128    public void setXClassReference(EntityReference xClassReference)
129    {
130  52627 super.setXClassReference(xClassReference);
131   
132    // Reset reference cache
133  52626 this.referenceCache = null;
134    }
135   
 
136  0 toggle public void displayHidden(StringBuffer buffer, String name, String prefix, XWikiContext context)
137    {
138  0 ((PropertyClass) getXClass(context).get(name)).displayHidden(buffer, name, prefix, this, context);
139    }
140   
 
141  0 toggle public void displayView(StringBuffer buffer, String name, String prefix, XWikiContext context)
142    {
143  0 ((PropertyClass) getXClass(context).get(name)).displayView(buffer, name, prefix, this, context);
144    }
145   
 
146  0 toggle public void displayEdit(StringBuffer buffer, String name, String prefix, XWikiContext context)
147    {
148  0 ((PropertyClass) getXClass(context).get(name)).displayEdit(buffer, name, prefix, this, context);
149    }
150   
 
151  0 toggle public String displayHidden(String name, String prefix, XWikiContext context)
152    {
153  0 StringBuffer buffer = new StringBuffer();
154  0 ((PropertyClass) getXClass(context).get(name)).displayHidden(buffer, name, prefix, this, context);
155   
156  0 return buffer.toString();
157    }
158   
 
159  0 toggle public String displayView(String name, String prefix, XWikiContext context)
160    {
161  0 StringBuffer buffer = new StringBuffer();
162  0 ((PropertyClass) getXClass(context).get(name)).displayView(buffer, name, prefix, this, context);
163   
164  0 return buffer.toString();
165    }
166   
 
167  0 toggle public String displayEdit(String name, String prefix, XWikiContext context)
168    {
169  0 StringBuffer buffer = new StringBuffer();
170  0 ((PropertyClass) getXClass(context).get(name)).displayEdit(buffer, name, prefix, this, context);
171   
172  0 return buffer.toString();
173    }
174   
 
175  0 toggle public String displayHidden(String name, XWikiContext context)
176    {
177  0 return displayHidden(name, "", context);
178    }
179   
 
180  0 toggle public String displayView(String name, XWikiContext context)
181    {
182  0 return displayView(name, "", context);
183    }
184   
 
185  0 toggle public String displayEdit(String name, XWikiContext context)
186    {
187  0 return displayEdit(name, "", context);
188    }
189   
 
190  31336 toggle @Override
191    public BaseObject clone()
192    {
193  31333 BaseObject object = (BaseObject) super.clone();
194  31338 object.setGuid(getGuid());
195   
196  31338 return object;
197    }
198   
199    /**
200    * Similar to {@link #clone()} but whereas a clone is an exact copy (with the same GUID), a duplicate keeps the same
201    * data but with a different identity.
202    *
203    * @since 2.2.3
204    */
 
205  134 toggle public BaseObject duplicate()
206    {
207  134 BaseObject object = clone();
208    // Set a new GUID for the duplicate
209  134 object.setGuid(UUID.randomUUID().toString());
210   
211  134 return object;
212    }
213   
214    /**
215    * @since 2.2.3
216    */
 
217  102 toggle public BaseObject duplicate(DocumentReference documentReference)
218    {
219  102 BaseObject object = duplicate();
220  102 object.setDocumentReference(documentReference);
221  102 return object;
222    }
223   
 
224  142 toggle @Override
225    public boolean equals(Object obj)
226    {
227    // Same Java object, they sure are equal
228  142 if (this == obj) {
229  114 return true;
230    }
231   
232  28 if (!super.equals(obj)) {
233  4 return false;
234    }
235   
236  24 if (getNumber() != ((BaseObject) obj).getNumber()) {
237  0 return false;
238    }
239   
240  24 return true;
241    }
242   
 
243  0 toggle @Override
244    public void fromXML(Element oel) throws XWikiException
245    {
246  0 super.fromXML(oel);
247    }
248   
 
249  779 toggle @Override
250    public List<ObjectDiff> getDiff(Object oldEntity, XWikiContext context)
251    {
252  779 ArrayList<ObjectDiff> difflist = new ArrayList<ObjectDiff>();
253  779 BaseObject oldObject = (BaseObject) oldEntity;
254    // Iterate over the new properties first, to handle changed and added objects
255  779 for (String propertyName : this.getPropertyList()) {
256  3415 BaseProperty newProperty = (BaseProperty) this.getField(propertyName);
257  3415 BaseProperty oldProperty = (BaseProperty) oldObject.getField(propertyName);
258  3415 BaseClass bclass = getXClass(context);
259  3415 PropertyClass pclass = (PropertyClass) ((bclass == null) ? null : bclass.getField(propertyName));
260  3415 String propertyType = (pclass == null) ? "" : pclass.getClassType();
261   
262  3415 if (oldProperty == null) {
263    // The property exist in the new object, but not in the old one
264  504 if ((newProperty != null) && (!newProperty.toText().equals(""))) {
265  207 String newPropertyValue = (newProperty.getValue() instanceof String || pclass == null)
266    ? newProperty.toText() : pclass.displayView(propertyName, this, context);
267  207 difflist.add(new ObjectDiff(getXClassReference(), getNumber(), getGuid(),
268    ObjectDiff.ACTION_PROPERTYADDED, propertyName, propertyType, "", newPropertyValue));
269    }
270  2911 } else if (!oldProperty.toText().equals(((newProperty == null) ? "" : newProperty.toText()))) {
271    // The property exists in both objects and is different
272  113 if (pclass != null) {
273    // Put the values as they would be displayed in the interface
274  108 String newPropertyValue = (newProperty.getValue() instanceof String) ? newProperty.toText()
275    : pclass.displayView(propertyName, this, context);
276  108 String oldPropertyValue = (oldProperty.getValue() instanceof String) ? oldProperty.toText()
277    : pclass.displayView(propertyName, oldObject, context);
278  108 difflist.add(
279    new ObjectDiff(getXClassReference(), getNumber(), getGuid(), ObjectDiff.ACTION_PROPERTYCHANGED,
280    propertyName, propertyType, oldPropertyValue, newPropertyValue));
281    } else {
282    // Cannot get property definition, so use the plain value
283  5 difflist.add(
284    new ObjectDiff(getXClassReference(), getNumber(), getGuid(), ObjectDiff.ACTION_PROPERTYCHANGED,
285    propertyName, propertyType, oldProperty.toText(), newProperty.toText()));
286    }
287    }
288    }
289   
290    // Iterate over the old properties, in case there are some removed properties
291  779 for (String propertyName : oldObject.getPropertyList()) {
292  3001 BaseProperty newProperty = (BaseProperty) this.getField(propertyName);
293  3001 BaseProperty oldProperty = (BaseProperty) oldObject.getField(propertyName);
294  3001 BaseClass bclass = getXClass(context);
295  3001 PropertyClass pclass = (PropertyClass) ((bclass == null) ? null : bclass.getField(propertyName));
296  3001 String propertyType = (pclass == null) ? "" : pclass.getClassType();
297   
298  3001 if (newProperty == null) {
299    // The property exists in the old object, but not in the new one
300  90 if ((oldProperty != null) && (!oldProperty.toText().equals(""))) {
301  63 if (pclass != null) {
302    // Put the values as they would be displayed in the interface
303  19 String oldPropertyValue = (oldProperty.getValue() instanceof String) ? oldProperty.toText()
304    : pclass.displayView(propertyName, oldObject, context);
305  19 difflist.add(
306    new ObjectDiff(oldObject.getXClassReference(), oldObject.getNumber(), oldObject.getGuid(),
307    ObjectDiff.ACTION_PROPERTYREMOVED, propertyName, propertyType, oldPropertyValue, ""));
308    } else {
309    // Cannot get property definition, so use the plain value
310  44 difflist.add(new ObjectDiff(oldObject.getXClassReference(), oldObject.getNumber(),
311    oldObject.getGuid(), ObjectDiff.ACTION_PROPERTYREMOVED, propertyName, propertyType,
312    oldProperty.toText(), ""));
313    }
314    }
315    }
316    }
317   
318  779 return difflist;
319    }
320   
 
321  6612 toggle public com.xpn.xwiki.api.Object newObjectApi(BaseObject obj, XWikiContext context)
322    {
323  6611 return new com.xpn.xwiki.api.Object(obj, context);
324    }
325   
 
326  666 toggle public void set(String fieldname, java.lang.Object value, XWikiContext context)
327    {
328  666 BaseClass bclass = getXClass(context);
329  666 PropertyClass pclass = (PropertyClass) bclass.get(fieldname);
330  666 BaseProperty prop = (BaseProperty) safeget(fieldname);
331  666 if ((value instanceof String) && (pclass != null)) {
332  593 prop = pclass.fromString((String) value);
333    } else {
334  73 if ((prop == null) && (pclass != null)) {
335  62 prop = pclass.newProperty();
336    }
337  73 if (prop != null) {
338  73 prop.setValue(value);
339    }
340    }
341   
342  666 if (prop != null) {
343  666 prop.setOwnerDocument(getOwnerDocument());
344  666 safeput(fieldname, prop);
345    }
346    }
347   
 
348  58633 toggle public String getGuid()
349    {
350  58632 return this.guid;
351    }
352   
 
353  44423 toggle public void setGuid(String guid)
354    {
355  44423 this.guid = guid;
356    }
357   
358    /**
359    * Set the owner document of this base object.
360    *
361    * @param ownerDocument The owner document.
362    * @since 4.3M2
363    */
 
364  104010 toggle @Override
365    public void setOwnerDocument(XWikiDocument ownerDocument)
366    {
367  104010 super.setOwnerDocument(ownerDocument);
368   
369  104013 if (this.ownerDocument != null) {
370  103895 setDocumentReference(this.ownerDocument.getDocumentReference());
371    }
372    }
373   
 
374  0 toggle @Override
375    protected void mergeField(PropertyInterface currentElement, ElementInterface previousElement,
376    ElementInterface newElement, MergeConfiguration configuration, XWikiContext context, MergeResult mergeResult)
377    {
378  0 BaseClass baseClass = getXClass(context);
379  0 if (baseClass != null) {
380  0 PropertyClass propertyClass = (PropertyClass) baseClass.get(currentElement.getName());
381  0 if (propertyClass != null) {
382  0 try {
383  0 propertyClass.mergeProperty((BaseProperty) currentElement, (BaseProperty) previousElement,
384    (BaseProperty) newElement, configuration, context, mergeResult);
385    } catch (Exception e) {
386  0 mergeResult.getLog().error("Failed to merge field [{}]", currentElement.getName(), e);
387    }
388   
389  0 return;
390    }
391    }
392   
393  0 super.mergeField(currentElement, previousElement, newElement, configuration, context, mergeResult);
394    }
395    }