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

File AbstractSheetBinder.java

 

Coverage histogram

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

Code metrics

18
59
6
1
244
162
18
0.31
9.83
6
3

Classes

Class Line # Actions
AbstractSheetBinder 58 59 0% 18 18
0.7831325578.3%
 

Contributing tests

This file is covered by 14 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.internal.sheet;
21   
22    import java.util.ArrayList;
23    import java.util.Collections;
24    import java.util.List;
25   
26    import javax.inject.Inject;
27    import javax.inject.Named;
28   
29    import org.slf4j.Logger;
30    import org.xwiki.bridge.DocumentModelBridge;
31    import org.xwiki.component.phase.Initializable;
32    import org.xwiki.component.phase.InitializationException;
33    import org.xwiki.context.Execution;
34    import org.xwiki.model.EntityType;
35    import org.xwiki.model.reference.DocumentReference;
36    import org.xwiki.model.reference.DocumentReferenceResolver;
37    import org.xwiki.model.reference.EntityReference;
38    import org.xwiki.model.reference.EntityReferenceResolver;
39    import org.xwiki.model.reference.EntityReferenceSerializer;
40    import org.xwiki.query.Query;
41    import org.xwiki.query.QueryException;
42    import org.xwiki.query.QueryManager;
43    import org.xwiki.sheet.SheetBinder;
44   
45    import com.xpn.xwiki.XWikiContext;
46    import com.xpn.xwiki.XWikiException;
47    import com.xpn.xwiki.doc.XWikiDocument;
48    import com.xpn.xwiki.objects.BaseObject;
49   
50    /**
51    * Abstract {@link SheetBinder} implementation that binds a sheet to a XWiki document by adding an object to the
52    * document. The object has a property named "sheet" that holds a reference to the sheet. Concrete extension of this
53    * class must specify the type of object to be used for binding.
54    *
55    * @version $Id: 6b2b8bdb79259c374f743c9e753f1f1ac550a32d $
56    * @since 3.2M3
57    */
 
58    public abstract class AbstractSheetBinder implements SheetBinder, Initializable
59    {
60    /**
61    * The name of the property of the binding object that holds the reference to the sheet.
62    */
63    private static final String SHEET_PROPERTY = "sheet";
64   
65    /** Logging helper object. */
66    @Inject
67    private Logger logger;
68   
69    /**
70    * The component used to resolve a string document reference.
71    */
72    @Inject
73    private DocumentReferenceResolver<String> documentReferenceResolver;
74   
75    /**
76    * The component used to resolve a string relative reference.
77    */
78    @Inject
79    @Named("relative")
80    private EntityReferenceResolver<String> relativeReferenceResolver;
81   
82    /**
83    * The component used to serialize entity references as absolute string references.
84    */
85    @Inject
86    private EntityReferenceSerializer<String> defaultEntityReferenceSerializer;
87   
88    /**
89    * The component used to serialize entity references as relative string references.
90    */
91    @Inject
92    @Named("compact")
93    private EntityReferenceSerializer<String> compactEntityReferenceSerializer;
94   
95    /**
96    * Execution context handler, needed for accessing the XWikiContext.
97    */
98    @Inject
99    private Execution execution;
100   
101    /**
102    * The component used to create database queries.
103    */
104    @Inject
105    private QueryManager queryManager;
106   
107    /**
108    * The query used to retrieve the list of all sheet bindings.
109    */
110    private Query sheetBindingsQuery;
111   
 
112  34378 toggle @Override
113    public List<DocumentReference> getSheets(DocumentModelBridge document)
114    {
115  34377 DocumentReference sheetBindingClassReference =
116    this.documentReferenceResolver.resolve(getSheetBindingClass(), document.getDocumentReference());
117  34380 List<BaseObject> sheetBindingObjects = ((XWikiDocument) document).getXObjects(sheetBindingClassReference);
118  34375 if (sheetBindingObjects == null) {
119  30561 return Collections.emptyList();
120    }
121  3815 List<DocumentReference> sheets = new ArrayList<DocumentReference>();
122  3815 for (BaseObject sheetBindingObject : sheetBindingObjects) {
123    // The list of XWiki objects can contain null values due to a design flaw in the old XWiki core.
124  3816 if (sheetBindingObject != null) {
125  3781 String sheetStringRef = sheetBindingObject.getStringValue(SHEET_PROPERTY);
126  3781 DocumentReference sheetReference =
127    this.documentReferenceResolver.resolve(sheetStringRef, document.getDocumentReference());
128  3781 sheets.add(sheetReference);
129    }
130    }
131  3815 return sheets;
132    }
133   
 
134  1 toggle @Override
135    public List<DocumentReference> getDocuments(DocumentReference expectedSheetRef)
136    {
137  1 this.sheetBindingsQuery.setWiki(expectedSheetRef.getWikiReference().getName());
138  1 try {
139  1 List<Object[]> sheetBindings = this.sheetBindingsQuery.execute();
140  1 List<DocumentReference> documentReferences = new ArrayList<DocumentReference>();
141  1 for (Object[] sheetBinding : sheetBindings) {
142  2 DocumentReference docRef =
143    this.documentReferenceResolver.resolve((String) sheetBinding[0], expectedSheetRef);
144  2 DocumentReference sheetRef = this.documentReferenceResolver.resolve((String) sheetBinding[1], docRef);
145  2 if (sheetRef.equals(expectedSheetRef)) {
146  1 documentReferences.add(docRef);
147    }
148    }
149  1 return documentReferences;
150    } catch (QueryException e) {
151  0 this.logger.warn("Failed to query sheet bindings.", e);
152  0 return Collections.emptyList();
153    }
154    }
155   
 
156  1039 toggle @Override
157    public boolean bind(DocumentModelBridge document, DocumentReference sheetReference)
158    {
159  1039 EntityReference sheetBindingClassReference =
160    this.relativeReferenceResolver.resolve(getSheetBindingClass(), EntityType.DOCUMENT);
161  1039 List<BaseObject> sheetBindingObjects = ((XWikiDocument) document).getXObjects(sheetBindingClassReference);
162  1039 if (sheetBindingObjects != null) {
163  1 for (BaseObject sheetBindingObject : sheetBindingObjects) {
164    // The list of XWiki objects can contain null values due to a design flaw in the old XWiki core.
165  1 if (sheetBindingObject != null) {
166  0 String boundSheetStringRef = sheetBindingObject.getStringValue(SHEET_PROPERTY);
167  0 DocumentReference boundSheetReference =
168    this.documentReferenceResolver.resolve(boundSheetStringRef, document.getDocumentReference());
169  0 if (boundSheetReference.equals(sheetReference)) {
170  0 return false;
171    }
172    }
173    }
174    }
175  1039 String relativeSheetStringReference =
176    this.compactEntityReferenceSerializer.serialize(sheetReference, document.getDocumentReference());
177  1039 try {
178  1039 BaseObject sheetBindingObject =
179    ((XWikiDocument) document).newXObject(sheetBindingClassReference, getXWikiContext());
180  1039 sheetBindingObject.setStringValue(SHEET_PROPERTY, relativeSheetStringReference);
181    } catch (XWikiException e) {
182  0 String docStringReference =
183    this.defaultEntityReferenceSerializer.serialize(document.getDocumentReference());
184  0 String sheetStringReference = this.defaultEntityReferenceSerializer.serialize(sheetReference);
185  0 this.logger.warn("Failed to bind sheet [{}] to document [{}].", sheetStringReference, docStringReference);
186  0 return false;
187    }
188  1039 return true;
189    }
190   
 
191  94 toggle @Override
192    public boolean unbind(DocumentModelBridge document, DocumentReference sheetReference)
193    {
194  94 DocumentReference sheetBindingClassReference =
195    this.documentReferenceResolver.resolve(getSheetBindingClass(), document.getDocumentReference());
196  94 List<BaseObject> sheetBindingObjects = ((XWikiDocument) document).getXObjects(sheetBindingClassReference);
197  94 if (sheetBindingObjects == null) {
198  0 return false;
199    }
200  94 for (BaseObject sheetBindingObject : sheetBindingObjects) {
201    // The list of XWiki objects can contain null values due to a design flaw in the old XWiki core.
202  95 if (sheetBindingObject != null) {
203  94 String boundSheetStringRef = sheetBindingObject.getStringValue(SHEET_PROPERTY);
204  94 DocumentReference boundSheetReference =
205    this.documentReferenceResolver.resolve(boundSheetStringRef, document.getDocumentReference());
206  94 if (boundSheetReference.equals(sheetReference)) {
207  94 return ((XWikiDocument) document).removeXObject(sheetBindingObject);
208    }
209    }
210    }
211  0 return false;
212    }
213   
214    /**
215    * @return the XWiki context
216    * @deprecated avoid using this method; try using the document access bridge instead
217    */
 
218  1039 toggle @Deprecated
219    private XWikiContext getXWikiContext()
220    {
221  1039 return (XWikiContext) this.execution.getContext().getProperty("xwikicontext");
222    }
223   
224    /**
225    * @return the string reference of the class used to bind sheets to documents
226    */
227    protected abstract String getSheetBindingClass();
228   
 
229  141 toggle @Override
230    public void initialize() throws InitializationException
231    {
232  141 try {
233  141 String statement =
234    "select doc.fullName, prop.value from XWikiDocument doc, BaseObject obj, StringProperty prop where "
235    + "obj.className=:sheetBindingClass and obj.name=doc.fullName and obj.id=prop.id.id and "
236    + "prop.id.name=:sheetProperty order by doc.fullName";
237  141 this.sheetBindingsQuery = this.queryManager.createQuery(statement, Query.HQL);
238  141 this.sheetBindingsQuery.bindValue("sheetBindingClass", getSheetBindingClass());
239  141 this.sheetBindingsQuery.bindValue("sheetProperty", SHEET_PROPERTY);
240    } catch (QueryException e) {
241  0 throw new InitializationException("Failed to create query for retrieving the list of sheet bindings.", e);
242    }
243    }
244    }