1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.rendering.internal.resolver

File AbstractResourceReferenceEntityReferenceResolver.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

26
49
11
1
234
149
30
0.61
4.45
11
2.73

Classes

Class Line # Actions
AbstractResourceReferenceEntityReferenceResolver 46 49 0% 30 7
0.918604791.9%
 

Contributing tests

This file is covered by 8 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 org.xwiki.rendering.internal.resolver;
21   
22    import java.util.List;
23    import java.util.Objects;
24   
25    import javax.inject.Inject;
26    import javax.inject.Named;
27    import javax.inject.Provider;
28   
29    import org.xwiki.bridge.DocumentAccessBridge;
30    import org.xwiki.model.EntityType;
31    import org.xwiki.model.reference.DocumentReference;
32    import org.xwiki.model.reference.EntityReference;
33    import org.xwiki.model.reference.EntityReferenceProvider;
34    import org.xwiki.model.reference.EntityReferenceResolver;
35    import org.xwiki.model.reference.SpaceReference;
36    import org.xwiki.model.reference.WikiReference;
37    import org.xwiki.rendering.listener.reference.ResourceReference;
38    import org.xwiki.rendering.listener.reference.ResourceType;
39   
40    /**
41    * Base class helper for EntityReferenceResolver<ResourceReference> implementations.
42    *
43    * @version $Id: e577b8ec37ba8aa534d044d543d64b7c0ce4b6de $
44    * @since 7.4.1
45    */
 
46    public abstract class AbstractResourceReferenceEntityReferenceResolver
47    implements EntityReferenceResolver<ResourceReference>
48    {
49    @Inject
50    @Named("current")
51    protected EntityReferenceResolver<String> currentEntityReferenceResolver;
52   
53    @Inject
54    protected EntityReferenceResolver<EntityReference> defaultEntityReferenceResolver;
55   
56    @Inject
57    @Named("current")
58    protected Provider<DocumentReference> currentDocumentProvider;
59   
60    @Inject
61    protected EntityReferenceProvider defaultReferenceProvider;
62   
63    @Inject
64    protected DocumentAccessBridge documentAccessBridge;
65   
66    protected ResourceType resourceType;
67   
68    /**
69    * Default constructor with an unset resourceType.
70    */
 
71  0 toggle public AbstractResourceReferenceEntityReferenceResolver()
72    {
73    }
74   
75    /**
76    * @param type the resource type that this resolver will support
77    */
 
78  51 toggle public AbstractResourceReferenceEntityReferenceResolver(ResourceType type)
79    {
80  51 this.resourceType = type;
81    }
82   
 
83  908 toggle @Override
84    public EntityReference resolve(ResourceReference resourceReference, EntityType entityType, Object... parameters)
85    {
86  908 if (resourceReference == null) {
87  0 return null;
88    }
89   
90  908 if (this.resourceType != null && !resourceReference.getType().equals(this.resourceType)) {
91  0 throw new IllegalArgumentException(
92    String.format("You must pass a resource reference of type [%s]. [%s] was passed", this.resourceType,
93    resourceReference));
94    }
95   
96  908 EntityReference baseReference = getBaseReference(resourceReference, parameters);
97   
98  908 EntityReference entityReference;
99   
100  908 if (resourceReference.isTyped()) {
101  36 entityReference = resolveTyped(resourceReference, baseReference);
102    } else {
103  872 entityReference = resolveUntyped(resourceReference, baseReference);
104    }
105   
106  908 return convertReference(entityReference, entityType);
107    }
108   
 
109  274 toggle protected EntityReference resolveUntyped(ResourceReference resourceReference, EntityReference baseReference)
110    {
111  274 return resolveTyped(resourceReference, baseReference);
112    }
113   
114    protected abstract EntityReference resolveTyped(ResourceReference resourceReference, EntityReference baseReference);
115   
 
116  908 toggle protected EntityReference getBaseReference(ResourceReference resourceReference, Object... parameters)
117    {
118  908 EntityReference baseReference = (parameters.length > 0 && parameters[0] instanceof EntityReference)
119    ? (EntityReference) parameters[0] : null;
120   
121  908 if (!resourceReference.getBaseReferences().isEmpty()) {
122    // If the passed reference has a base reference, resolve it first with a current resolver (it should
123    // normally be absolute but who knows what the API caller has specified...)
124  787 baseReference = resolveBaseReference(resourceReference.getBaseReferences(), baseReference);
125    }
126   
127  908 if (baseReference == null) {
128  111 baseReference = this.currentDocumentProvider.get();
129    }
130   
131  908 return baseReference;
132    }
133   
 
134  787 toggle protected EntityReference resolveBaseReference(List<String> baseReferences, EntityReference defaultBaseReference)
135    {
136  787 EntityReference resolvedBaseReference = defaultBaseReference;
137  787 for (String baseReference : baseReferences) {
138  787 resolvedBaseReference =
139    this.currentEntityReferenceResolver.resolve(baseReference, EntityType.DOCUMENT, resolvedBaseReference);
140    }
141   
142  787 return resolvedBaseReference;
143    }
144   
 
145  908 toggle protected EntityReference convertReference(EntityReference entityReference, EntityType entityType)
146    {
147    // Convert the entity reference if needed
148  908 if (entityReference != null && entityType != null && entityReference.getType() != entityType) {
149  0 return this.defaultEntityReferenceResolver.resolve(entityReference, entityType);
150    }
151   
152  908 return entityReference;
153    }
154   
 
155  881 toggle protected DocumentReference resolveDocumentReference(EntityReference sourceReference, DocumentReference reference,
156    EntityReference baseReference)
157    {
158  881 DocumentReference finalReference = reference;
159   
160    // If same as base reference, no fallback
161  881 if (!Objects.equals(reference, baseReference)) {
162    // If already a space home page, no fallback
163  854 String defaultDocumentName =
164    this.defaultReferenceProvider.getDefaultReference(EntityType.DOCUMENT).getName();
165  854 if (!reference.getName().equals(defaultDocumentName)) {
166  811 finalReference =
167    resolveDocumentReference(sourceReference, finalReference, baseReference, true, defaultDocumentName);
168    }
169    }
170   
171  881 return finalReference;
172    }
173   
 
174  819 toggle protected DocumentReference resolveDocumentReference(EntityReference sourceReference, DocumentReference reference,
175    EntityReference baseReference, boolean trySpaceSibling, String defaultDocumentName)
176    {
177  819 DocumentReference finalReference = reference;
178   
179  819 if (!this.documentAccessBridge.exists(reference)) {
180    // It does not exist, make it a space home page.
181  81 SpaceReference spaceReference =
182    new SpaceReference(reference.getName(), (SpaceReference) reference.getParent());
183  81 finalReference = new DocumentReference(defaultDocumentName, spaceReference);
184   
185  81 if (trySpaceSibling
186    && trySpaceSiblingFallback(sourceReference, finalReference, baseReference, defaultDocumentName)) {
187    // Try as a space sibling.
188  18 DocumentReference siblingReference =
189    resolveSiblingSpaceDocumentReference(sourceReference, reference, baseReference,
190    defaultDocumentName);
191   
192    // We accept the resolved sibling reference only if it is a terminal document (i.e. an exists check was
193    // already performed for it) OR, in the case of a non-terminal document, if it actually exists (by
194    // performing the exists check now). Otherwise, the default will remain the child non-terminal document.
195  18 if (!siblingReference.getName().equals(defaultDocumentName)
196    || documentAccessBridge.exists(siblingReference)) {
197  2 finalReference = siblingReference;
198    }
199    }
200    }
201   
202  819 return finalReference;
203    }
204   
 
205  18 toggle protected DocumentReference resolveSiblingSpaceDocumentReference(EntityReference sourceReference,
206    DocumentReference reference, EntityReference baseReference, String defaultDocumentName)
207    {
208  18 DocumentReference finalReference;
209   
210    // Create space sibling
211  18 EntityReference parentReference = reference.getParent().getParent();
212  18 if (parentReference instanceof SpaceReference) {
213  8 finalReference = new DocumentReference(reference.getName(), (SpaceReference) parentReference);
214   
215  8 finalReference =
216    resolveDocumentReference(sourceReference, finalReference, baseReference, false, defaultDocumentName);
217    } else {
218  10 SpaceReference spaceReference = new SpaceReference(reference.getName(), (WikiReference) parentReference);
219  10 finalReference = new DocumentReference(defaultDocumentName, spaceReference);
220    }
221   
222  18 return finalReference;
223    }
224   
 
225  75 toggle protected boolean trySpaceSiblingFallback(EntityReference sourceReference, DocumentReference finalReference,
226    EntityReference baseReference, String defaultDocumentName)
227    {
228    // If not relative, no space sibling fallback
229    // If base reference not a space home page, no space sibling fallback
230    // If finalReference exist, no space sibling fallback
231  75 return sourceReference.getParent() == null && baseReference != null
232    && baseReference.getName().equals(defaultDocumentName) && !this.documentAccessBridge.exists(finalReference);
233    }
234    }