KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > web > ui > repo > component > UISimpleSearch


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;
18
19 import java.io.IOException JavaDoc;
20 import java.util.Map JavaDoc;
21 import java.util.ResourceBundle JavaDoc;
22
23 import javax.faces.component.NamingContainer;
24 import javax.faces.component.UICommand;
25 import javax.faces.component.UIComponent;
26 import javax.faces.context.FacesContext;
27 import javax.faces.context.ResponseWriter;
28 import javax.faces.event.AbortProcessingException;
29 import javax.faces.event.ActionEvent;
30 import javax.faces.event.FacesEvent;
31
32 import org.alfresco.web.app.Application;
33 import org.alfresco.web.bean.SearchContext;
34 import org.alfresco.web.ui.common.Utils;
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37 /**
38  * @author Kevin Roast
39  */

40 public class UISimpleSearch extends UICommand
41 {
42    // ------------------------------------------------------------------------------
43
// Component implementation
44

45    /**
46     * Default Constructor
47     */

48    public UISimpleSearch()
49    {
50       // specifically set the renderer type to null to indicate to the framework
51
// that this component renders itself - there is no abstract renderer class
52
setRendererType(null);
53    }
54    
55    /**
56     * @see javax.faces.component.UIComponent#getFamily()
57     */

58    public String JavaDoc getFamily()
59    {
60       return "org.alfresco.faces.SimpleSearch";
61    }
62
63    /**
64     * @see javax.faces.component.StateHolder#restoreState(javax.faces.context.FacesContext, java.lang.Object)
65     */

66    public void restoreState(FacesContext context, Object JavaDoc state)
67    {
68       Object JavaDoc values[] = (Object JavaDoc[])state;
69       // standard component attributes are restored by the super class
70
super.restoreState(context, values[0]);
71       this.search = (SearchContext)values[1];
72    }
73    
74    /**
75     * @see javax.faces.component.StateHolder#saveState(javax.faces.context.FacesContext)
76     */

77    public Object JavaDoc saveState(FacesContext context)
78    {
79       Object JavaDoc values[] = new Object JavaDoc[2];
80       // standard component attributes are saved by the super class
81
values[0] = super.saveState(context);
82       values[1] = this.search;
83       return (values);
84    }
85    
86    /**
87     * @see javax.faces.component.UIComponentBase#decode(javax.faces.context.FacesContext)
88     */

89    public void decode(FacesContext context)
90    {
91       Map JavaDoc requestMap = context.getExternalContext().getRequestParameterMap();
92       String JavaDoc fieldId = Utils.getActionHiddenFieldName(context, this);
93       String JavaDoc value = (String JavaDoc)requestMap.get(fieldId);
94       // we are clicked if the hidden field contained our client id
95
if (value != null)
96       {
97          if (value.equals(this.getClientId(context)))
98          {
99             String JavaDoc searchText = (String JavaDoc)requestMap.get(getClientId(context));
100             
101             if (searchText.length() != 0)
102             {
103                if (logger.isDebugEnabled())
104                   logger.debug("Search text submitted: " + searchText);
105                int option = -1;
106                String JavaDoc optionFieldName = getClientId(context) + NamingContainer.SEPARATOR_CHAR + OPTION_PARAM;
107                String JavaDoc optionStr = (String JavaDoc)requestMap.get(optionFieldName);
108                if (optionStr.length() != 0)
109                {
110                   option = Integer.parseInt(optionStr);
111                }
112                if (logger.isDebugEnabled())
113                   logger.debug("Search option submitted: " + option);
114                
115                // queue event so system can perform a search and update the component
116
SearchEvent event = new SearchEvent(this, searchText, option);
117                this.queueEvent(event);
118             }
119          }
120          else if (value.equals(ADVSEARCH_PARAM))
121          {
122             // found advanced search navigation action
123
// TODO: TEMP: set this outcome from a component attribute!
124
AdvancedSearchEvent event = new AdvancedSearchEvent(this, "advSearch");
125             this.queueEvent(event);
126          }
127       }
128    }
129    
130    /**
131     * @see javax.faces.component.UICommand#broadcast(javax.faces.event.FacesEvent)
132     */

133    public void broadcast(FacesEvent event) throws AbortProcessingException
134    {
135       FacesContext fc = getFacesContext();
136       if (event instanceof SearchEvent)
137       {
138          // update the component parameters from the search event details
139
SearchEvent searchEvent = (SearchEvent)event;
140          
141          // construct the Search Context object
142
SearchContext context = new SearchContext();
143          context.setText(searchEvent.SearchText);
144          context.setMode(searchEvent.SearchMode);
145          context.setForceAndTerms(Application.getClientConfig(fc).getForceAndTerms());
146          this.search = context;
147          
148          super.broadcast(event);
149       }
150       else if (event instanceof AdvancedSearchEvent)
151       {
152          // special case to navigate to the advanced search screen
153
AdvancedSearchEvent searchEvent = (AdvancedSearchEvent)event;
154          fc.getApplication().getNavigationHandler().handleNavigation(fc, null, searchEvent.Outcome);
155          
156          // NOTE: we don't call super() here so that our nav outcome is the one that occurs!
157
}
158    }
159
160    /**
161     * @see javax.faces.component.UIComponentBase#encodeBegin(javax.faces.context.FacesContext)
162     */

163    public void encodeBegin(FacesContext context) throws IOException JavaDoc
164    {
165       if (isRendered() == false)
166       {
167          return;
168       }
169       
170       ResponseWriter out = context.getResponseWriter();
171       
172       ResourceBundle JavaDoc bundle = (ResourceBundle JavaDoc)Application.getBundle(context);
173       
174       // script for dynamic simple search menu drop-down options
175
out.write("<script>");
176       out.write("function _noenter(event) {" +
177                 "if (event && event.keyCode == 13) {" +
178                 " _searchSubmit();return false; }" +
179                 "else {" +
180                 " return true; } }");
181       out.write("function _searchSubmit() {");
182       out.write(Utils.generateFormSubmit(context, this, Utils.getActionHiddenFieldName(context, this), getClientId(context)));
183       out.write("}");
184       out.write("</script>");
185       
186       // outer table containing search drop-down icon, text box and search Go image button
187
out.write("<table cellspacing=4 cellpadding=0>");
188       out.write("<tr><td style='padding-top:2px'>");
189       
190       String JavaDoc searchImage = Utils.buildImageTag(context, "/images/icons/search_icon.gif", 15, 15,
191             bundle.getString(MSG_GO), "_searchSubmit();");
192       
193       out.write(Utils.buildImageTag(context, "/images/icons/search_controls.gif", 27, 13,
194             bundle.getString(MSG_OPTIONS), "javascript:_toggleMenu(event, '_alfsearch');"));
195       
196       // dynamic DIV area containing search options
197
out.write("<br><div id='_alfsearch' style='position:absolute;display:none'>");
198       out.write("<table border=0 bgcolor='#eeeeee' style='border-top:thin solid #FFFFFF;border-left:thin solid #FFFFFF;border-right:thin solid #444444;border-bottom:thin solid #444444;' cellspacing=4 cellpadding=0>");
199       
200       // output each option - setting the current one to CHECKED
201
String JavaDoc optionFieldName = getClientId(context) + NamingContainer.SEPARATOR_CHAR + OPTION_PARAM;
202       String JavaDoc radioOption = "<tr><td class='userInputForm'><input type='radio' name='" + optionFieldName + "'";
203       out.write(radioOption);
204       out.write(" VALUE='0'");
205       int searchMode = getSearchMode();
206       if (searchMode == 0) out.write(" CHECKED");
207       out.write("><nobr>" + bundle.getString(MSG_ALL_ITEMS) + "</nobr></td></tr>");
208       out.write(radioOption);
209       out.write(" VALUE='1'");
210       if (searchMode == 1) out.write(" CHECKED");
211       out.write("><nobr>" + bundle.getString(MSG_FILE_NAMES_CONTENTS) + "</nobr></td></tr>");
212       out.write(radioOption);
213       out.write(" VALUE='2'");
214       if (searchMode == 2) out.write(" CHECKED");
215       out.write("><nobr>" + bundle.getString(MSG_FILE_NAMES_ONLY) + "</nobr></td></tr>");
216       out.write(radioOption);
217       out.write(" VALUE='3'");
218       if (searchMode == 3) out.write(" CHECKED");
219       out.write("><nobr>" + bundle.getString(MSG_SPACE_NAMES_ONLY) + "</nobr></td></tr>");
220       
221       // row with table containing advanced search link and Search Go button
222
out.write("<tr><td><table width=100%><tr><td>");
223       // generate a link that will cause an action event to navigate to the advanced search screen
224
out.write("<a class='small' HREF='#' onclick=\"");
225       out.write(Utils.generateFormSubmit(context, this, Utils.getActionHiddenFieldName(context, this), ADVSEARCH_PARAM));
226       out.write("\">");
227       out.write(bundle.getString(MSG_ADVANCED_SEARCH));
228       out.write("</a>");
229       out.write("</td><td align=right>");
230       out.write(searchImage);
231       out.write("</td></tr></table></td></tr>");
232       out.write("</table></div>");
233       
234       // input text box
235
out.write("</td><td>");
236       out.write("<input name='");
237       out.write(getClientId(context));
238       // TODO: style and class from component properties!
239
out.write("' onkeypress=\"return _noenter(event)\"");
240       out.write(" type='text' maxlength='1024' style='width:130px;padding-top:3px;font-size:10px' value=\"");
241       // output previous search text stored in this component!
242
out.write(Utils.replace(getLastSearch(), "\"", "&quot;"));
243       out.write("\">");
244       
245       // search Go image button
246
out.write("</td><td>");
247       out.write(searchImage);
248       
249       // end outer table
250
out.write("</td></tr></table>");
251    }
252    
253    /**
254     * Return the current Search Context
255     */

256    public SearchContext getSearchContext()
257    {
258       return this.search;
259    }
260    
261    /**
262     * @return The last set search text value
263     */

264    public String JavaDoc getLastSearch()
265    {
266       if (search != null)
267       {
268          return this.search.getText();
269       }
270       else
271       {
272          return "";
273       }
274    }
275    
276    /**
277     * @return The current search mode (see constants)
278     */

279    public int getSearchMode()
280    {
281       if (search != null)
282       {
283          return this.search.getMode();
284       }
285       else
286       {
287          return SearchContext.SEARCH_ALL;
288       }
289    }
290    
291    
292    // ------------------------------------------------------------------------------
293
// Private data
294

295    private static Log logger = LogFactory.getLog(UISimpleSearch.class);
296    
297    /** I18N message Ids */
298    private static final String JavaDoc MSG_ADVANCED_SEARCH = "advanced_search";
299    private static final String JavaDoc MSG_OPTIONS = "options";
300    private static final String JavaDoc MSG_GO = "go";
301    private static final String JavaDoc MSG_SPACE_NAMES_ONLY = "space_names";
302    private static final String JavaDoc MSG_FILE_NAMES_ONLY = "file_names";
303    private static final String JavaDoc MSG_FILE_NAMES_CONTENTS = "file_names_contents";
304    private static final String JavaDoc MSG_ALL_ITEMS = "all_items";
305    
306    private static final String JavaDoc OPTION_PARAM = "_option";
307    private static final String JavaDoc ADVSEARCH_PARAM = "_advsearch";
308    
309    /** last search context used */
310    private SearchContext search = null;
311    
312    
313    // ------------------------------------------------------------------------------
314
// Inner classes
315

316    /**
317     * Class representing a search execution from the UISimpleSearch component.
318     */

319    public static class SearchEvent extends ActionEvent
320    {
321       private static final long serialVersionUID = 3918135612344774322L;
322
323       public SearchEvent(UIComponent component, String JavaDoc text, int mode)
324       {
325          super(component);
326          SearchText = text;
327          SearchMode = mode;
328       }
329       
330       public String JavaDoc SearchText;
331       public int SearchMode;
332    }
333    
334    public static class AdvancedSearchEvent extends ActionEvent
335    {
336       public AdvancedSearchEvent(UIComponent component, String JavaDoc outcome)
337       {
338          super(component);
339          Outcome = outcome;
340       }
341       
342       public String JavaDoc Outcome;
343    }
344 }
345
Popular Tags