KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > web > ui > repo > component > shelf > UIShortcutsShelfItem


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.component.shelf;
18
19 import java.io.IOException JavaDoc;
20 import java.util.List 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.faces.context.ResponseWriter;
27 import javax.faces.el.MethodBinding;
28 import javax.faces.el.ValueBinding;
29 import javax.faces.event.AbortProcessingException;
30 import javax.faces.event.ActionEvent;
31 import javax.faces.event.FacesEvent;
32
33 import org.alfresco.model.ContentModel;
34 import org.alfresco.service.cmr.dictionary.DictionaryService;
35 import org.alfresco.web.app.Application;
36 import org.alfresco.web.bean.repository.Node;
37 import org.alfresco.web.bean.repository.Repository;
38 import org.alfresco.web.ui.common.Utils;
39 import org.alfresco.web.ui.repo.WebResources;
40
41 /**
42  * JSF Component providing UI for a list of user defined shortcuts to favorite nodes.
43  *
44  * @author Kevin Roast
45  */

46 public class UIShortcutsShelfItem extends UIShelfItem
47 {
48    // ------------------------------------------------------------------------------
49
// Component Impl
50

51    /**
52     * @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
53     */

54    public void restoreState(FacesContext context, Object JavaDoc state)
55    {
56       Object JavaDoc values[] = (Object JavaDoc[])state;
57       // standard component attributes are restored by the super class
58
super.restoreState(context, values[0]);
59       this.value = values[1];
60       this.clickActionListener = (MethodBinding)values[2];
61       this.removeActionListener = (MethodBinding)values[3];
62    }
63    
64    /**
65     * @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
66     */

67    public Object JavaDoc saveState(FacesContext context)
68    {
69       Object JavaDoc values[] = new Object JavaDoc[4];
70       // standard component attributes are saved by the super class
71
values[0] = super.saveState(context);
72       values[1] = this.value;
73       values[2] = this.clickActionListener;
74       values[3] = this.removeActionListener;
75       
76       return (values);
77    }
78    
79    /**
80     * Get the value (for this component the value is used as the List of shortcut nodes)
81     *
82     * @return the value
83     */

84    public Object JavaDoc getValue()
85    {
86       if (this.value == null)
87       {
88          ValueBinding vb = getValueBinding("value");
89          if (vb != null)
90          {
91             this.value = vb.getValue(getFacesContext());
92          }
93       }
94       return this.value;
95    }
96
97    /**
98     * Set the value (for this component the value is used as the List of shortcut nodes)
99     *
100     * @param value the value
101     */

102    public void setValue(Object JavaDoc value)
103    {
104       this.value = value;
105    }
106    
107    /**
108     * @param binding The MethodBinding to call when Click is performed by the user
109     */

110    public void setClickActionListener(MethodBinding binding)
111    {
112       this.clickActionListener = binding;
113    }
114    
115    /**
116     * @return The MethodBinding to call when Click is performed by the user
117     */

118    public MethodBinding getClickActionListener()
119    {
120       return this.clickActionListener;
121    }
122    
123    /**
124     * @param binding The MethodBinding to call when Remove is performed by the user
125     */

126    public void setRemoveActionListener(MethodBinding binding)
127    {
128       this.removeActionListener = binding;
129    }
130    
131    /**
132     * @return The MethodBinding to call when Remove is performed by the user
133     */

134    public MethodBinding getRemoveActionListener()
135    {
136       return this.removeActionListener;
137    }
138    
139    /**
140     * @see javax.faces.component.UIComponentBase#decode(javax.faces.context.FacesContext)
141     */

142    public void decode(FacesContext context)
143    {
144       Map JavaDoc requestMap = context.getExternalContext().getRequestParameterMap();
145       String JavaDoc fieldId = getHiddenFieldName();
146       String JavaDoc value = (String JavaDoc)requestMap.get(fieldId);
147       
148       if (value != null && value.length() != 0)
149       {
150          // decode the values - we are expecting an action identifier and an index
151
int sepIndex = value.indexOf(NamingContainer.SEPARATOR_CHAR);
152          int action = Integer.parseInt(value.substring(0, sepIndex));
153          int index = Integer.parseInt(value.substring(sepIndex + 1));
154          
155          // raise an event to process the action later in the lifecycle
156
ShortcutEvent event = new ShortcutEvent(this, action, index);
157          this.queueEvent(event);
158       }
159    }
160    
161    /**
162     * @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext)
163     */

164    public void encodeBegin(FacesContext context) throws IOException JavaDoc
165    {
166       if (isRendered() == false)
167       {
168          return;
169       }
170       
171       ResponseWriter out = context.getResponseWriter();
172       List JavaDoc<Node> items = (List JavaDoc<Node>)getValue();
173       out.write(SHELF_START);
174       if (items != null)
175       {
176          DictionaryService dd = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getDictionaryService();
177          
178          for (int i=0; i<items.size(); i++)
179          {
180             Node item = items.get(i);
181             
182             out.write("<tr><td>");
183             if (dd.isSubClass(item.getType(), ContentModel.TYPE_FOLDER))
184             {
185                // start row with Space icon
186
out.write(Utils.buildImageTag(context, WebResources.IMAGE_SPACE, 16, 16, null, null, "absmiddle"));
187             }
188             else if (dd.isSubClass(item.getType(), ContentModel.TYPE_CONTENT))
189             {
190                String JavaDoc image = Utils.getFileTypeImage(item.getName(), true);
191                out.write(Utils.buildImageTag(context, image, 16, 16, null, null, "absmiddle"));
192             }
193             
194             // output cropped item label - we also output with no breaks, this is ok
195
// as the copped label will ensure a sensible maximum width
196
out.write("</td><td width=100%><nobr>&nbsp;");
197             out.write(buildActionLink(ACTION_CLICK_ITEM, i, item.getName()));
198             
199             // output actions
200
out.write("</nobr></td><td align=right><nobr>");
201             out.write(buildActionLink(ACTION_REMOVE_ITEM, i, Application.getMessage(context, MSG_REMOVE_ITEM), WebResources.IMAGE_REMOVE));
202             // TODO: add view details action here?
203

204             // end actions cell and end row
205
out.write("</nobr></td></tr>");
206          }
207       }
208       
209       out.write(SHELF_END);
210    }
211    
212    /**
213     * @see javax.faces.component.UIComponentBase#broadcast(javax.faces.event.FacesEvent)
214     */

215    public void broadcast(FacesEvent event) throws AbortProcessingException
216    {
217       if (event instanceof ShortcutEvent)
218       {
219          // found an event we should handle
220
ShortcutEvent shortcutEvent = (ShortcutEvent)event;
221          
222          List JavaDoc<Node> items = (List JavaDoc<Node>)getValue();
223          if (items != null && items.size() > shortcutEvent.Index)
224          {
225             // process the action
226
switch (shortcutEvent.Action)
227             {
228                case ACTION_CLICK_ITEM:
229                   Utils.processActionMethod(getFacesContext(), getClickActionListener(), shortcutEvent);
230                   break;
231                case ACTION_REMOVE_ITEM:
232                   Utils.processActionMethod(getFacesContext(), getRemoveActionListener(), shortcutEvent);
233                   break;
234             }
235          }
236       }
237       else
238       {
239          super.broadcast(event);
240       }
241    }
242    
243    
244    // ------------------------------------------------------------------------------
245
// Private helpers
246

247    /**
248     * We use a hidden field name on the assumption that only one Shortcut Shelf item
249     * instance is present on a single page.
250     *
251     * @return hidden field name
252     */

253    private String JavaDoc getHiddenFieldName()
254    {
255       return getClientId(getFacesContext());
256    }
257    
258    /**
259     * Build HTML for an link representing a Shortcut action
260     *
261     * @param action action indentifier to represent
262     * @param index index of the Node item this action relates too
263     * @param text of the action to display
264     *
265     * @return HTML for action link
266     */

267    private String JavaDoc buildActionLink(int action, int index, String JavaDoc text)
268    {
269       FacesContext context = getFacesContext();
270       
271       StringBuilder JavaDoc buf = new StringBuilder JavaDoc(200);
272       
273       buf.append("<a HREF='#' onclick=\"");
274       // generate JavaScript to set a hidden form field and submit
275
// a form which request attributes that we can decode
276
buf.append(Utils.generateFormSubmit(context, this, getHiddenFieldName(), encodeValues(action, index)));
277       buf.append("\">");
278       
279       buf.append(Utils.cropEncode(text));
280       
281       buf.append("</a>");
282       
283       return buf.toString();
284    }
285    
286    /**
287     * Build HTML for an link representing a clipboard action
288     *
289     * @param action action indentifier to represent
290     * @param index index of the clipboard item this action relates too
291     * @param text of the action to display
292     * @param image image icon to display
293     *
294     * @return HTML for action link
295     */

296    private String JavaDoc buildActionLink(int action, int index, String JavaDoc text, String JavaDoc image)
297    {
298       FacesContext context = getFacesContext();
299       
300       StringBuilder JavaDoc buf = new StringBuilder JavaDoc(256);
301       
302       buf.append("<a HREF='#' onclick=\"");
303       // generate JavaScript to set a hidden form field and submit
304
// a form which request attributes that we can decode
305
buf.append(Utils.generateFormSubmit(context, this, getHiddenFieldName(), encodeValues(action, index)));
306       buf.append("\">");
307       
308       if (image != null)
309       {
310          buf.append(Utils.buildImageTag(context, image, text));
311       }
312       else
313       {
314          buf.append(Utils.encode(text));
315       }
316       
317       buf.append("</a>");
318       
319       return buf.toString();
320    }
321    
322    /**
323     * Encode the specified values for output to a hidden field
324     *
325     * @param action Action identifer
326     * @param index Index of the Node item the action is for
327     *
328     * @return encoded values
329     */

330    private static String JavaDoc encodeValues(int action, int index)
331    {
332       return Integer.toString(action) + NamingContainer.SEPARATOR_CHAR + Integer.toString(index);
333    }
334    
335    
336    // ------------------------------------------------------------------------------
337
// Inner classes
338

339    /**
340     * Class representing the an action relevant to the Shortcut element.
341     */

342    public static class ShortcutEvent extends ActionEvent
343    {
344       public ShortcutEvent(UIComponent component, int action, int index)
345       {
346          super(component);
347          Action = action;
348          Index = index;
349       }
350       
351       public int Action;
352       public int Index;
353    }
354    
355    
356    // ------------------------------------------------------------------------------
357
// Private data
358

359    /** I18N messages */
360    private static final String JavaDoc MSG_REMOVE_ITEM = "remove_item";
361    
362    private final static int ACTION_CLICK_ITEM = 0;
363    private final static int ACTION_REMOVE_ITEM = 1;
364    
365    /** for this component the value is used as the List of shortcut Nodes */
366    private Object JavaDoc value = null;
367    
368    /** action listener called when a Click action occurs */
369    private MethodBinding clickActionListener;
370    
371    /** action listener called when a Remove action occurs */
372    private MethodBinding removeActionListener;
373 }
374
Popular Tags