KickJava   Java API By Example, From Geeks To Geeks.

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


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.web.bean.repository.Node;
34 import org.alfresco.web.ui.common.Utils;
35 import org.alfresco.web.ui.repo.WebResources;
36
37 /**
38  * JSF Component providing UI for a real-time updated list of the most recently visited Spaces.
39  *
40  * @author Kevin Roast
41  */

42 public class UIRecentSpacesShelfItem extends UIShelfItem
43 {
44    // ------------------------------------------------------------------------------
45
// Component Impl
46

47    /**
48     * @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
49     */

50    public void restoreState(FacesContext context, Object JavaDoc state)
51    {
52       Object JavaDoc values[] = (Object JavaDoc[])state;
53       // standard component attributes are restored by the super class
54
super.restoreState(context, values[0]);
55       this.value = values[1];
56       this.navigateActionListener = (MethodBinding)values[2];
57    }
58    
59    /**
60     * @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
61     */

62    public Object JavaDoc saveState(FacesContext context)
63    {
64       Object JavaDoc values[] = new Object JavaDoc[3];
65       // standard component attributes are saved by the super class
66
values[0] = super.saveState(context);
67       values[1] = this.value;
68       values[2] = this.navigateActionListener;
69       
70       return (values);
71    }
72    
73    /**
74     * Get the value (for this component the value is used as the List of recent Space Nodes)
75     *
76     * @return the value
77     */

78    public Object JavaDoc getValue()
79    {
80       if (this.value == null)
81       {
82          ValueBinding vb = getValueBinding("value");
83          if (vb != null)
84          {
85             this.value = vb.getValue(getFacesContext());
86          }
87       }
88       return this.value;
89    }
90
91    /**
92     * Set the value (for this component the value is used as the List of recent Space Nodes)
93     *
94     * @param value the value
95     */

96    public void setValue(Object JavaDoc value)
97    {
98       this.value = value;
99    }
100    
101    /**
102     * @param binding The MethodBinding to call when Navigate is performed by the user
103     */

104    public void setNavigateActionListener(MethodBinding binding)
105    {
106       this.navigateActionListener = binding;
107    }
108    
109    /**
110     * @return The MethodBinding to call when Navigate is performed by the user
111     */

112    public MethodBinding getNavigateActionListener()
113    {
114       return this.navigateActionListener;
115    }
116    
117    /**
118     * @see javax.faces.component.UIComponentBase#decode(javax.faces.context.FacesContext)
119     */

120    public void decode(FacesContext context)
121    {
122       Map JavaDoc requestMap = context.getExternalContext().getRequestParameterMap();
123       String JavaDoc fieldId = getHiddenFieldName();
124       String JavaDoc value = (String JavaDoc)requestMap.get(fieldId);
125       
126       if (value != null && value.length() != 0)
127       {
128          // decode the values - we are expecting an action identifier and an index
129
int sepIndex = value.indexOf(NamingContainer.SEPARATOR_CHAR);
130          int action = Integer.parseInt(value.substring(0, sepIndex));
131          int index = Integer.parseInt(value.substring(sepIndex + 1));
132          
133          // raise an event to process the action later in the lifecycle
134
RecentSpacesEvent event = new RecentSpacesEvent(this, action, index);
135          this.queueEvent(event);
136       }
137    }
138    
139    /**
140     * @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext)
141     */

142    public void encodeBegin(FacesContext context) throws IOException JavaDoc
143    {
144       if (isRendered() == false)
145       {
146          return;
147       }
148       
149       ResponseWriter out = context.getResponseWriter();
150       List JavaDoc<Node> items = (List JavaDoc<Node>)getValue();
151       out.write(SHELF_START);
152       for (int i=0; i<items.size(); i++)
153       {
154          Node item = items.get(i);
155          
156          // start row with Space icon
157
out.write("<tr><td>");
158          out.write(Utils.buildImageTag(context, WebResources.IMAGE_SPACE, 16, 16, null, null, "absmiddle"));
159          
160          // output cropped item label - we also output with no breaks, this is ok
161
// as the copped label will ensure a sensible maximum width
162
out.write("</td><td width=100%><nobr>&nbsp;");
163          out.write(buildActionLink(ACTION_NAVIGATE_ITEM, i, item.getName()));
164          
165          // end actions cell and end row
166
out.write("</nobr></td></tr>");
167       }
168       
169       out.write(SHELF_END);
170    }
171    
172    /**
173     * @see javax.faces.component.UIComponentBase#broadcast(javax.faces.event.FacesEvent)
174     */

175    public void broadcast(FacesEvent event) throws AbortProcessingException
176    {
177       if (event instanceof RecentSpacesEvent)
178       {
179          // found an event we should handle
180
RecentSpacesEvent spaceEvent = (RecentSpacesEvent)event;
181          
182          List JavaDoc<Node> items = (List JavaDoc<Node>)getValue();
183          if (items.size() > spaceEvent.Index)
184          {
185             // process the action
186
switch (spaceEvent.Action)
187             {
188                case ACTION_NAVIGATE_ITEM:
189                   Utils.processActionMethod(getFacesContext(), getNavigateActionListener(), spaceEvent);
190                   break;
191             }
192          }
193       }
194       else
195       {
196          super.broadcast(event);
197       }
198    }
199    
200    
201    // ------------------------------------------------------------------------------
202
// Private helpers
203

204    /**
205     * We use a hidden field name on the assumption that only one Recent Spaces shelf item
206     * instance is present on a single page.
207     *
208     * @return hidden field name
209     */

210    private String JavaDoc getHiddenFieldName()
211    {
212       return getClientId(getFacesContext());
213    }
214    
215    /**
216     * Build HTML for an link representing a Recent Space action
217     *
218     * @param action action indentifier to represent
219     * @param index index of the Node item this action relates too
220     * @param text of the action to display
221     *
222     * @return HTML for action link
223     */

224    private String JavaDoc buildActionLink(int action, int index, String JavaDoc text)
225    {
226       FacesContext context = getFacesContext();
227       
228       StringBuilder JavaDoc buf = new StringBuilder JavaDoc(200);
229       
230       buf.append("<a HREF='#' onclick=\"");
231       // generate JavaScript to set a hidden form field and submit
232
// a form which request attributes that we can decode
233
buf.append(Utils.generateFormSubmit(context, this, getHiddenFieldName(), encodeValues(action, index)));
234       buf.append("\">");
235       
236       buf.append(Utils.cropEncode(text));
237       
238       buf.append("</a>");
239       
240       return buf.toString();
241    }
242    
243    /**
244     * Encode the specified values for output to a hidden field
245     *
246     * @param action Action identifer
247     * @param index Index of the Node item the action is for
248     *
249     * @return encoded values
250     */

251    private static String JavaDoc encodeValues(int action, int index)
252    {
253       return Integer.toString(action) + NamingContainer.SEPARATOR_CHAR + Integer.toString(index);
254    }
255    
256    
257    // ------------------------------------------------------------------------------
258
// Inner classes
259

260    /**
261     * Class representing the an action relevant to the Recent Spaces element.
262     */

263    public static class RecentSpacesEvent extends ActionEvent
264    {
265       public RecentSpacesEvent(UIComponent component, int action, int index)
266       {
267          super(component);
268          Action = action;
269          Index = index;
270       }
271       
272       public int Action;
273       public int Index;
274    }
275    
276    
277    // ------------------------------------------------------------------------------
278
// Private data
279

280    private final static int ACTION_NAVIGATE_ITEM = 0;
281    
282    /** for this component the value is used as the List of recent Space Nodes */
283    private Object JavaDoc value = null;
284    
285    /** action listener called when a Navigate action occurs */
286    private MethodBinding navigateActionListener;
287 }
288
Popular Tags