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

File SolrFieldStringEntityReferenceResolver.java

 

Coverage histogram

../../../../../img/srcFileCovDistChart9.png
38% of files have more coverage

Code metrics

22
44
6
1
178
108
19
0.43
7.33
6
3.17

Classes

Class Line # Actions
SolrFieldStringEntityReferenceResolver 46 44 0% 19 7
0.902777890.3%
 

Contributing tests

This file is covered by 1 test. .

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.search.solr.internal;
21   
22    import java.util.HashMap;
23    import java.util.Map;
24   
25    import javax.inject.Inject;
26    import javax.inject.Named;
27    import javax.inject.Singleton;
28   
29    import org.xwiki.component.annotation.Component;
30    import org.xwiki.model.EntityType;
31    import org.xwiki.model.internal.reference.AbstractEntityReferenceResolver;
32    import org.xwiki.model.reference.EntityReference;
33    import org.xwiki.model.reference.EntityReferenceProvider;
34    import org.xwiki.model.reference.EntityReferenceResolver;
35   
36    /**
37    * Resolves a <strong>local</strong> {@link EntityReference} that has been serialized with
38    * {@link SolrFieldStringEntityReferenceSerializer}.
39    *
40    * @version $Id: 938159cc2ff26688e4552ddd6e9d2971c7508395 $
41    * @since 5.3RC1
42    */
43    @Component
44    @Named("solr")
45    @Singleton
 
46    public class SolrFieldStringEntityReferenceResolver extends AbstractEntityReferenceResolver implements
47    EntityReferenceResolver<String>
48    {
49    /**
50    * The character used to separate the entities in the string serialization.
51    */
52    static final char SEPARATOR = '.';
53   
54    /**
55    * Map defining ordered entity types of a proper reference chain for a given entity type.
56    */
57    @SuppressWarnings("serial")
58    private static final Map<EntityType, EntityType[]> ENTITY_TYPES = new HashMap<EntityType, EntityType[]>()
59    {
 
60  1 toggle {
61  1 put(EntityType.DOCUMENT, new EntityType[]{EntityType.DOCUMENT, EntityType.SPACE, EntityType.WIKI});
62  1 put(EntityType.ATTACHMENT, new EntityType[]{EntityType.ATTACHMENT, EntityType.DOCUMENT, EntityType.SPACE,
63    EntityType.WIKI});
64  1 put(EntityType.SPACE, new EntityType[]{EntityType.SPACE, EntityType.WIKI});
65  1 put(EntityType.OBJECT, new EntityType[]{EntityType.OBJECT, EntityType.DOCUMENT, EntityType.SPACE,
66    EntityType.WIKI});
67  1 put(EntityType.OBJECT_PROPERTY, new EntityType[]{EntityType.OBJECT_PROPERTY, EntityType.OBJECT,
68    EntityType.DOCUMENT, EntityType.SPACE, EntityType.WIKI});
69  1 put(EntityType.CLASS_PROPERTY, new EntityType[]{EntityType.CLASS_PROPERTY, EntityType.DOCUMENT,
70    EntityType.SPACE, EntityType.WIKI});
71    }
72    };
73   
74    @Inject
75    @Named("current")
76    private EntityReferenceProvider currentEntityReferenceProvider;
77   
 
78  5 toggle @Override
79    public EntityReference resolve(String entityReferenceRepresentation, EntityType type, Object... parameters)
80    {
81  5 EntityType[] entityTypesForType = ENTITY_TYPES.get(type);
82  5 if (entityTypesForType == null) {
83  0 throw new RuntimeException("No parsing definition found for Entity Type [" + type + "]");
84    }
85   
86  5 EntityReference entityReference = null;
87  5 int entityTypeOffset = 0;
88  5 int offset = entityReferenceRepresentation.length() - 1;
89  22 while (offset >= 0) {
90    // Small hack in order to be able to resolve nested spaces. Basically we never read the WIKI component from
91    // the passed entity reference representation (we assume it is a space). We fill the WIKI entity reference
92    // after this while loop.
93  17 entityTypeOffset = Math.min(entityTypeOffset, entityTypesForType.length - 2);
94   
95  17 StringBuilder entityName = new StringBuilder();
96  17 offset = readEntityName(entityReferenceRepresentation, entityName, offset);
97  17 EntityReference parent = getNewEntityReference(entityName.reverse().toString(),
98    entityTypesForType[entityTypeOffset++], parameters);
99  17 entityReference = entityReference == null ? parent : entityReference.appendParent(parent);
100    }
101   
102    // Handle the case when the passed string representation is relative. Use the provided parameters in this case.
103  11 for (int i = entityTypeOffset; i < entityTypesForType.length; i++) {
104  6 EntityReference parent = resolveDefaultReference(entityTypesForType[i], parameters);
105  6 if (parent != null) {
106  6 entityReference = entityReference == null ? parent : entityReference.appendParent(parent);
107    } else {
108    // We cannot skip reference components.
109  0 break;
110    }
111    }
112   
113  5 return entityReference;
114    }
115   
116    /**
117    * Tries to read a non-separator character from the input and to write it to the output and returns the new input
118    * offset. If the read character is a separator then the input offset it not modified. If the read character is an
119    * escaped separator then the separator is written to the output and the offset is updated to skip the escaping.
120    *
121    * @param input the input string
122    * @param output the output
123    * @param offset the input offset
124    * @return the updated offset, unless the current character is a separator
125    */
 
126  108 toggle private int readCharacter(String input, StringBuilder output, int offset)
127    {
128  108 if (offset >= 0) {
129  103 char c = input.charAt(offset);
130  103 if (c == SEPARATOR) {
131  19 if (offset == 0 || (offset > 0 && input.charAt(offset - 1) != SEPARATOR)) {
132  12 return offset;
133    } else {
134  7 output.append(c);
135  7 return offset - 2;
136    }
137    } else {
138  84 output.append(c);
139  84 return offset - 1;
140    }
141    }
142  5 return offset;
143    }
144   
145    /**
146    * Reads an escaped entity name from the given string.
147    *
148    * @param input the input string to read the entity name from
149    * @param output where to write the entity name
150    * @param inputOffset the input offset
151    * @return the updated offset
152    */
 
153  17 toggle private int readEntityName(String input, StringBuilder output, int inputOffset)
154    {
155  17 int oldOffset;
156  17 int offset = inputOffset;
157  17 do {
158  108 oldOffset = offset;
159  108 offset = readCharacter(input, output, offset);
160  108 } while (offset != oldOffset);
161  17 return offset - 1;
162    }
163   
 
164  17 toggle private EntityReference getNewEntityReference(String name, EntityType type, Object... parameters)
165    {
166  17 if ("".equals(name)) {
167  0 return resolveDefaultReference(type, parameters);
168    } else {
169  17 return new EntityReference(name, type);
170    }
171    }
172   
 
173  4 toggle @Override
174    protected EntityReference getDefaultReference(EntityType type, Object... parameters)
175    {
176  4 return currentEntityReferenceProvider.getDefaultReference(type);
177    }
178    }