KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > web > ui > repo > renderer > NodePathLinkRenderer


1 /*
2  * Copyright (C) 2005 Alfresco, Inc.
3  *
4  * Licensed under the Mozilla Public License version 1.1
5  * with a permitted attribution clause. You may obtain a
6  * copy of the License at
7  *
8  * http://www.alfresco.org/legal/license.txt
9  *
10  * Unless required by applicable law or agreed to in writing,
11  * software distributed under the License is distributed on an
12  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
13  * either express or implied. See the License for the specific
14  * language governing permissions and limitations under the
15  * License.
16  */

17 package org.alfresco.web.ui.repo.renderer;
18
19 import java.io.IOException JavaDoc;
20 import java.io.Writer JavaDoc;
21 import java.util.Map JavaDoc;
22
23 import javax.faces.component.NamingContainer;
24 import javax.faces.component.UIComponent;
25 import javax.faces.context.FacesContext;
26 import javax.transaction.UserTransaction JavaDoc;
27
28 import org.alfresco.repo.security.permissions.AccessDeniedException;
29 import org.alfresco.service.cmr.repository.ChildAssociationRef;
30 import org.alfresco.service.cmr.repository.InvalidNodeRefException;
31 import org.alfresco.service.cmr.repository.NodeRef;
32 import org.alfresco.service.cmr.repository.NodeService;
33 import org.alfresco.service.cmr.repository.Path;
34 import org.alfresco.web.bean.repository.Repository;
35 import org.alfresco.web.ui.common.Utils;
36 import org.alfresco.web.ui.common.renderer.BaseRenderer;
37 import org.alfresco.web.ui.repo.component.UINodeDescendants;
38 import org.alfresco.web.ui.repo.component.UINodePath;
39
40 /**
41  * @author Kevin Roast
42  */

43 public class NodePathLinkRenderer extends BaseRenderer
44 {
45    // ------------------------------------------------------------------------------
46
// Renderer implementation
47

48    /**
49     * @see javax.faces.render.Renderer#decode(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
50     */

51    public void decode(FacesContext context, UIComponent component)
52    {
53       Map JavaDoc requestMap = context.getExternalContext().getRequestParameterMap();
54       String JavaDoc fieldId = getHiddenFieldName(context, component);
55       String JavaDoc value = (String JavaDoc)requestMap.get(fieldId);
56       
57       // we encoded the value to start with our Id
58
if (value != null && value.startsWith(component.getClientId(context) + NamingContainer.SEPARATOR_CHAR))
59       {
60          // found a new selected value for this component
61
// queue an event to represent the change
62
String JavaDoc selectedNodeId = value.substring(component.getClientId(context).length() + 1);
63          NodeRef ref = new NodeRef(Repository.getStoreRef(), selectedNodeId);
64          
65          UINodePath.PathElementEvent event = new UINodePath.PathElementEvent(component, ref);
66          component.queueEvent(event);
67       }
68    }
69    
70    /**
71     * @see javax.faces.render.Renderer#encodeEnd(javax.faces.context.FacesContext, javax.faces.component.UIComponent)
72     */

73    public void encodeEnd(FacesContext context, UIComponent component) throws IOException JavaDoc
74    {
75       // always check for this flag - as per the spec
76
if (component.isRendered() == false)
77       {
78          return;
79       }
80       
81       Writer JavaDoc out = context.getResponseWriter();
82       
83       // make sure we have a NodeRef or Path from the 'value' property ValueBinding
84
Path path = null;
85       NodeRef nodeRef = null;
86       Object JavaDoc val = ((UINodePath)component).getValue();
87       if (val instanceof NodeRef == true)
88       {
89          nodeRef = (NodeRef)val;
90       }
91       else if (val instanceof Path == true)
92       {
93          path = (Path)val;
94       }
95       else
96       {
97          throw new IllegalArgumentException JavaDoc("UINodePath component 'value' property must resolve to a NodeRef or Path!");
98       }
99       
100       boolean isBreadcrumb = false;
101       Boolean JavaDoc breadcrumb = (Boolean JavaDoc)component.getAttributes().get("breadcrumb");
102       if (breadcrumb != null)
103       {
104          isBreadcrumb = breadcrumb.booleanValue();
105       }
106       
107       boolean isDisabled = false;
108       Boolean JavaDoc disabled = (Boolean JavaDoc)component.getAttributes().get("disabled");
109       if (disabled != null)
110       {
111          isDisabled = disabled.booleanValue();
112       }
113       
114       boolean showLeaf = false;
115       Boolean JavaDoc showLeafBool = (Boolean JavaDoc)component.getAttributes().get("showLeaf");
116       if (showLeafBool != null)
117       {
118          showLeaf = showLeafBool.booleanValue();
119       }
120       
121       // use Spring JSF integration to get the node service bean
122
NodeService service = getNodeService(context);
123       UserTransaction JavaDoc tx = null;
124       try
125       {
126          tx = Repository.getUserTransaction(FacesContext.getCurrentInstance(), true);
127          tx.begin();
128          
129          if (path == null)
130          {
131             path = service.getPath(nodeRef);
132          }
133          
134          if (isBreadcrumb == false || isDisabled == true)
135          {
136             out.write(buildPathAsSingular(context, component, path, showLeaf, isDisabled));
137          }
138          else
139          {
140             out.write(buildPathAsBreadcrumb(context, component, path, showLeaf));
141          }
142          
143          tx.commit();
144       }
145       catch (InvalidNodeRefException refErr)
146       {
147          // this error simple means we cannot output the path
148
try { if (tx != null) {tx.rollback();} } catch (Exception JavaDoc tex) {}
149       }
150       catch (AccessDeniedException accessErr)
151       {
152          // this error simple means we cannot output the path
153
try { if (tx != null) {tx.rollback();} } catch (Exception JavaDoc tex) {}
154       }
155       catch (Throwable JavaDoc err)
156       {
157          try { if (tx != null) {tx.rollback();} } catch (Exception JavaDoc tex) {}
158          throw new RuntimeException JavaDoc(err);
159       }
160    }
161    
162    /**
163     * Return the path with each element as a single clickable link e.g. breadcrumb style
164     *
165     * @param context FacesContext
166     * @param component UIComponent to get display attribute from
167     * @param path Node Path to use
168     *
169     * @return the path with each individual element clickable
170     */

171    private String JavaDoc buildPathAsBreadcrumb(FacesContext context, UIComponent component, Path path, boolean showLeaf)
172    {
173       StringBuilder JavaDoc buf = new StringBuilder JavaDoc(1024);
174       
175       int size = (showLeaf ? path.size() : path.size() - 1);
176       for (int i=0; i<size; i++)
177       {
178          Path.Element element = path.get(i);
179          String JavaDoc elementString = null;
180          if (element instanceof Path.ChildAssocElement)
181          {
182             ChildAssociationRef elementRef = ((Path.ChildAssocElement)element).getRef();
183             if (elementRef.getParentRef() != null)
184             {
185                String JavaDoc name = Repository.getNameForNode(getNodeService(context), elementRef.getChildRef());
186                elementString = renderPathElement(context, component, elementRef.getChildRef(), name);
187             }
188          }
189          else
190          {
191             elementString = element.getElementString();
192          }
193          
194          if (elementString != null)
195          {
196             buf.append("/");
197             buf.append(elementString);
198          }
199       }
200       
201       return buf.toString();
202    }
203    
204    /**
205     * Return the path with the entire path as a single clickable link
206     *
207     * @param context FacesContext
208     * @param component UIComponent to get display attribute from
209     * @param path Node Path to use
210     *
211     * @return the entire path as a single clickable link
212     */

213    private String JavaDoc buildPathAsSingular(FacesContext context, UIComponent component, Path path, boolean showLeaf, boolean disabled)
214    {
215       StringBuilder JavaDoc buf = new StringBuilder JavaDoc(512);
216       
217       NodeRef lastElementRef = null;
218       int size = (showLeaf ? path.size() : path.size() - 1);
219       for (int i=0; i<size; i++)
220       {
221          Path.Element element = path.get(i);
222          String JavaDoc elementString = null;
223          if (element instanceof Path.ChildAssocElement)
224          {
225             ChildAssociationRef elementRef = ((Path.ChildAssocElement)element).getRef();
226             if (elementRef.getParentRef() != null)
227             {
228                elementString = Repository.getNameForNode(getNodeService(context), elementRef.getChildRef());
229             }
230             if (i == path.size() - 2)
231             {
232                lastElementRef = elementRef.getChildRef();
233             }
234          }
235          else
236          {
237             elementString = element.getElementString();
238          }
239          
240          if (elementString != null)
241          {
242             buf.append("/");
243             buf.append(elementString);
244          }
245       }
246       
247       if (disabled == false)
248       {
249          return renderPathElement(context, component, lastElementRef, buf.toString());
250       }
251       else
252       {
253          return buf.toString();
254       }
255    }
256    
257    /**
258     * Render a path element as a clickable link
259     *
260     * @param context FacesContext
261     * @param control UIComponent to get attributes from
262     * @param nodeRef NodeRef of the path element
263     * @param label Display label to output with this link
264     *
265     * @return HTML for a descendant link
266     */

267    private String JavaDoc renderPathElement(FacesContext context, UIComponent control, NodeRef nodeRef, String JavaDoc label)
268    {
269       StringBuilder JavaDoc buf = new StringBuilder JavaDoc(256);
270       
271       buf.append("<a HREF='#' onclick=\"");
272       // build an HTML param that contains the client Id of this control, followed by the node Id
273
String JavaDoc param = control.getClientId(context) + NamingContainer.SEPARATOR_CHAR + nodeRef.getId();
274       buf.append(Utils.generateFormSubmit(context, control, getHiddenFieldName(context, control), param));
275       buf.append('"');
276       Map JavaDoc attrs = control.getAttributes();
277       if (attrs.get("style") != null)
278       {
279          buf.append(" style=\"")
280             .append(attrs.get("style"))
281             .append('"');
282       }
283       if (attrs.get("styleClass") != null)
284       {
285          buf.append(" class=")
286             .append(attrs.get("styleClass"));
287       }
288       buf.append('>');
289       
290       buf.append(Utils.encode(label));
291       
292       buf.append("</a>");
293       
294       return buf.toString();
295    }
296
297    
298    // ------------------------------------------------------------------------------
299
// Private helpers
300

301    /**
302     * Get the hidden field name for this node path component.
303     * Build a shared field name from the parent form name and the string "npath".
304     *
305     * @return hidden field name shared by all node path components within the Form.
306     */

307    private static String JavaDoc getHiddenFieldName(FacesContext context, UIComponent component)
308    {
309       return Utils.getParentForm(context, component).getClientId(context) + NamingContainer.SEPARATOR_CHAR + "npath";
310    }
311    
312    /**
313     * Use Spring JSF integration to return the node service bean instance
314     *
315     * @param context FacesContext
316     *
317     * @return node service bean instance or throws runtime exception if not found
318     */

319    private static NodeService getNodeService(FacesContext context)
320    {
321       NodeService service = Repository.getServiceRegistry(context).getNodeService();
322       if (service == null)
323       {
324          throw new IllegalStateException JavaDoc("Unable to obtain NodeService bean reference.");
325       }
326       
327       return service;
328    }
329 }
330
Popular Tags