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

File DefaultWikiMacroManager.java

 

Coverage histogram

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

Code metrics

8
48
7
2
245
140
15
0.31
6.86
3.5
2.14

Classes

Class Line # Actions
DefaultWikiMacroManager 54 44 0% 12 4
0.928571492.9%
DefaultWikiMacroManager.WikiMacroData 96 4 0% 3 0
1.0100%
 

Contributing tests

This file is covered by 17 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.macro.wikibridge;
21   
22    import java.util.HashMap;
23    import java.util.Map;
24   
25    import javax.inject.Inject;
26    import javax.inject.Singleton;
27   
28    import org.xwiki.bridge.DocumentAccessBridge;
29    import org.xwiki.component.annotation.Component;
30    import org.xwiki.component.descriptor.DefaultComponentDescriptor;
31    import org.xwiki.component.manager.ComponentLookupException;
32    import org.xwiki.component.manager.ComponentManager;
33    import org.xwiki.model.ModelContext;
34    import org.xwiki.model.reference.DocumentReference;
35    import org.xwiki.model.reference.EntityReference;
36    import org.xwiki.model.reference.EntityReferenceSerializer;
37    import org.xwiki.rendering.macro.Macro;
38    import org.xwiki.rendering.macro.wikibridge.InsufficientPrivilegesException;
39    import org.xwiki.rendering.macro.wikibridge.WikiMacro;
40    import org.xwiki.rendering.macro.wikibridge.WikiMacroDescriptor;
41    import org.xwiki.rendering.macro.wikibridge.WikiMacroException;
42    import org.xwiki.rendering.macro.wikibridge.WikiMacroFactory;
43    import org.xwiki.rendering.macro.wikibridge.WikiMacroManager;
44    import org.xwiki.rendering.macro.wikibridge.WikiMacroVisibility;
45   
46    /**
47    * Default implementation of {@link WikiMacroManager}.
48    *
49    * @version $Id: c0e17ce2514960431b4e06729c009473b8507df3 $
50    * @since 2.0M2
51    */
52    @Component
53    @Singleton
 
54    public class DefaultWikiMacroManager implements WikiMacroManager
55    {
56    /**
57    * The Root {@link ComponentManager}, used to look up specific component manager for registering Wiki Macros against
58    * the proper one (depending on the Macro visibility).
59    */
60    @Inject
61    private ComponentManager rootComponentManager;
62   
63    /**
64    * The {@link DocumentAccessBridge} component.
65    */
66    @Inject
67    private DocumentAccessBridge bridge;
68   
69    /**
70    * The {@link ModelContext} component.
71    */
72    @Inject
73    private ModelContext modelContext;
74   
75    /**
76    * Used to check the right depending of the macro visibility.
77    */
78    @Inject
79    private WikiMacroFactory wikiMacroFactory;
80   
81    /**
82    * Used to serialize references of documents.
83    */
84    @Inject
85    private EntityReferenceSerializer<String> serializer;
86   
87    /**
88    * Map of wiki macros against document names. This is used to de-register wiki macros when corresponding documents
89    * are deleted.
90    */
91    private Map<DocumentReference, WikiMacroData> wikiMacroMap = new HashMap<>();
92   
93    /**
94    * Internal helper class to hold a wiki macro component role hint and the wiki Macro definition itself.
95    */
 
96    private static class WikiMacroData
97    {
98    /**
99    * @see #getHint()
100    */
101    private String hint;
102   
103    /**
104    * @see #getWikiMacro()
105    */
106    private WikiMacro wikiMacro;
107   
108    /**
109    * @param hint see {@link #getHint()}
110    * @param wikiMacro see {@link #getWikiMacro()}
111    */
 
112  243 toggle WikiMacroData(String hint, WikiMacro wikiMacro)
113    {
114  243 this.hint = hint;
115  243 this.wikiMacro = wikiMacro;
116    }
117   
118    /**
119    * @return the wiki Macro component hint
120    */
 
121  18 toggle public String getHint()
122    {
123  18 return this.hint;
124    }
125   
126    /**
127    * @return the wiki Macro definition
128    */
 
129  42 toggle public WikiMacro getWikiMacro()
130    {
131  42 return this.wikiMacro;
132    }
133    }
134   
 
135  423 toggle @Override
136    public boolean hasWikiMacro(DocumentReference documentReference)
137    {
138  423 return (null != this.wikiMacroMap.get(documentReference));
139    }
140   
 
141  246 toggle @Override
142    public void registerWikiMacro(DocumentReference documentReference, WikiMacro wikiMacro)
143    throws InsufficientPrivilegesException, WikiMacroException
144    {
145  246 WikiMacroDescriptor macroDescriptor = (WikiMacroDescriptor) wikiMacro.getDescriptor();
146   
147    // Verify that the user has the right to register this wiki macro the chosen visibility
148  246 if (this.wikiMacroFactory.isAllowed(documentReference, macroDescriptor.getVisibility())) {
149  243 DefaultComponentDescriptor<Macro> componentDescriptor = new DefaultComponentDescriptor<>();
150  243 componentDescriptor.setRoleType(Macro.class);
151  243 componentDescriptor.setRoleHint(wikiMacro.getDescriptor().getId().getId());
152   
153    // Save current context informations
154  243 String currentUser = this.bridge.getCurrentUser();
155  243 EntityReference currentEntityReference = this.modelContext.getCurrentEntityReference();
156  243 try {
157    // Put the proper context information to let components manager use the proper keys to find
158    // components to unregister
159  243 this.bridge.setCurrentUser(this.serializer.serialize(wikiMacro.getAuthorReference() != null ? wikiMacro
160    .getAuthorReference() : this.bridge.getCurrentUserReference()));
161  243 this.modelContext.setCurrentEntityReference(documentReference);
162   
163    // Register the macro against the right Component Manager, depending on the defined macro visibility.
164  243 findComponentManager(macroDescriptor.getVisibility()).registerComponent(componentDescriptor, wikiMacro);
165  243 this.wikiMacroMap.put(documentReference,
166    new WikiMacroData(componentDescriptor.getRoleHint(), wikiMacro));
167    } catch (Exception e) {
168  0 throw new WikiMacroException(String.format("Failed to register macro [%s] in [%s] for visibility [%s]",
169    wikiMacro.getDescriptor().getId().getId(), documentReference, macroDescriptor.getVisibility()), e);
170    } finally {
171    // Restore previous context informations
172  243 this.bridge.setCurrentUser(currentUser);
173  243 this.modelContext.setCurrentEntityReference(currentEntityReference);
174    }
175    } else {
176  3 throw new InsufficientPrivilegesException(String.format(
177    "Unable to register macro [%s] in [%s] for visibility [%s] due to insufficient privileges", wikiMacro
178    .getDescriptor().getId().getId(), documentReference, macroDescriptor.getVisibility()));
179    }
180    }
181   
 
182  21 toggle @Override
183    public void unregisterWikiMacro(DocumentReference documentReference) throws WikiMacroException
184    {
185  21 WikiMacroData macroData = this.wikiMacroMap.get(documentReference);
186  21 if (macroData != null) {
187  21 WikiMacroDescriptor macroDescriptor = (WikiMacroDescriptor) macroData.getWikiMacro().getDescriptor();
188   
189    // Verify that the user has the right to unregister this wiki macro for the chosen visibility
190  21 if (this.wikiMacroFactory.isAllowed(documentReference, macroDescriptor.getVisibility())) {
191  18 String currentUser = this.bridge.getCurrentUser();
192  18 EntityReference currentEntityReference = this.modelContext.getCurrentEntityReference();
193  18 try {
194    // Put the proper context information to let components manager use the proper keys to find
195    // components to unregister
196  18 this.bridge
197    .setCurrentUser(this.serializer.serialize(macroData.getWikiMacro().getAuthorReference()));
198  18 this.modelContext.setCurrentEntityReference(documentReference);
199   
200  18 findComponentManager(macroDescriptor.getVisibility()).unregisterComponent(Macro.class,
201    macroData.getHint());
202  18 this.wikiMacroMap.remove(documentReference);
203    } catch (Exception e) {
204  0 throw new WikiMacroException(String.format("Failed to unregister macro [%s] in [%s] for "
205    + "visibility [%s]", macroData.getHint(), documentReference, macroDescriptor.getVisibility()),
206    e);
207    } finally {
208  18 this.bridge.setCurrentUser(currentUser);
209  18 this.modelContext.setCurrentEntityReference(currentEntityReference);
210    }
211    } else {
212  3 throw new WikiMacroException(String.format("Unable to unregister macro [%s] in [%s] for visibility "
213    + "[%s] due to insufficient privileges", macroData.getWikiMacro().getDescriptor().getId().getId(),
214    documentReference, macroDescriptor.getVisibility()));
215    }
216    } else {
217  0 throw new WikiMacroException(String.format("Macro in [%s] isn't registered", documentReference));
218    }
219    }
220   
221    /**
222    * @param visibility the visibility required
223    * @return the Component Manager to use to register/unregister the wiki macro. The Component Manager to use depends
224    * on the macro visibility. For example a macro that has the "current user" visibility must be registered
225    * against the User Component Manager.
226    * @throws ComponentLookupException if the Component Manager for the specified visibility cannot be found
227    */
 
228  261 toggle private ComponentManager findComponentManager(WikiMacroVisibility visibility) throws ComponentLookupException
229    {
230  261 ComponentManager cm;
231   
232  261 switch (visibility) {
233  42 case USER:
234  42 cm = this.rootComponentManager.getInstance(ComponentManager.class, "user");
235  42 break;
236  196 case WIKI:
237  196 cm = this.rootComponentManager.getInstance(ComponentManager.class, "wiki");
238  196 break;
239  23 default:
240  23 cm = this.rootComponentManager;
241    }
242   
243  261 return cm;
244    }
245    }