KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > alfresco > web > bean > AdvancedSearchBean


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.bean;
18
19 import java.io.Serializable JavaDoc;
20 import java.text.MessageFormat JavaDoc;
21 import java.text.SimpleDateFormat JavaDoc;
22 import java.util.ArrayList JavaDoc;
23 import java.util.Date JavaDoc;
24 import java.util.HashMap JavaDoc;
25 import java.util.List JavaDoc;
26 import java.util.Map JavaDoc;
27
28 import javax.faces.component.UISelectBoolean;
29 import javax.faces.context.FacesContext;
30 import javax.faces.event.ActionEvent;
31 import javax.faces.model.DataModel;
32 import javax.faces.model.ListDataModel;
33 import javax.faces.model.SelectItem;
34 import javax.transaction.UserTransaction JavaDoc;
35
36 import org.alfresco.model.ContentModel;
37 import org.alfresco.repo.cache.ExpiringValueCache;
38 import org.alfresco.repo.content.MimetypeMap;
39 import org.alfresco.repo.security.permissions.AccessDeniedException;
40 import org.alfresco.service.ServiceRegistry;
41 import org.alfresco.service.cmr.dictionary.AspectDefinition;
42 import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
43 import org.alfresco.service.cmr.dictionary.DictionaryService;
44 import org.alfresco.service.cmr.dictionary.PropertyDefinition;
45 import org.alfresco.service.cmr.dictionary.TypeDefinition;
46 import org.alfresco.service.cmr.repository.ChildAssociationRef;
47 import org.alfresco.service.cmr.repository.ContentReader;
48 import org.alfresco.service.cmr.repository.ContentService;
49 import org.alfresco.service.cmr.repository.ContentWriter;
50 import org.alfresco.service.cmr.repository.MimetypeService;
51 import org.alfresco.service.cmr.repository.NodeRef;
52 import org.alfresco.service.cmr.repository.NodeService;
53 import org.alfresco.service.cmr.search.SearchService;
54 import org.alfresco.service.cmr.security.AccessStatus;
55 import org.alfresco.service.cmr.security.PermissionService;
56 import org.alfresco.service.namespace.NamespaceService;
57 import org.alfresco.service.namespace.QName;
58 import org.alfresco.service.namespace.RegexQNamePattern;
59 import org.alfresco.util.CachingDateFormat;
60 import org.alfresco.web.app.Application;
61 import org.alfresco.web.bean.SearchContext.RangeProperties;
62 import org.alfresco.web.bean.repository.MapNode;
63 import org.alfresco.web.bean.repository.Node;
64 import org.alfresco.web.bean.repository.Repository;
65 import org.alfresco.web.bean.repository.User;
66 import org.alfresco.web.config.AdvancedSearchConfigElement;
67 import org.alfresco.web.config.AdvancedSearchConfigElement.CustomProperty;
68 import org.alfresco.web.data.IDataContainer;
69 import org.alfresco.web.data.QuickSort;
70 import org.alfresco.web.ui.common.Utils;
71 import org.alfresco.web.ui.common.component.UIModeList;
72 import org.alfresco.web.ui.common.component.UIPanel.ExpandedEvent;
73 import org.alfresco.web.ui.repo.component.UICategorySelector;
74 import org.alfresco.web.ui.repo.component.UISearchCustomProperties;
75
76 /**
77  * Provides the form state and action event handling for the Advanced Search UI.
78  * <p>
79  * Integrates with the web-client ConfigService to retrieve configuration of custom
80  * meta-data searching fields. Custom fields can be configured to appear in the UI
81  * and they are they automatically added to the search query by this bean.
82  *
83  * @author Kevin Roast
84  */

85 public class AdvancedSearchBean
86 {
87    /**
88     * Default constructor
89     */

90    public AdvancedSearchBean()
91    {
92       // initial state of progressive panels that don't use the default
93
panels.put(PANEL_CATEGORIES, false);
94       panels.put(PANEL_ATTRS, false);
95       panels.put(PANEL_CUSTOM, false);
96    }
97    
98    
99    // ------------------------------------------------------------------------------
100
// Bean property getters and setters
101

102    /**
103     * @param navigator The NavigationBean to set.
104     */

105    public void setNavigator(NavigationBean navigator)
106    {
107       this.navigator = navigator;
108    }
109
110    /**
111     * @param nodeService The NodeService to set.
112     */

113    public void setNodeService(NodeService nodeService)
114    {
115       this.nodeService = nodeService;
116    }
117
118    /**
119     * @param namespaceService The NamespaceService to set.
120     */

121    public void setNamespaceService(NamespaceService namespaceService)
122    {
123       this.namespaceService = namespaceService;
124    }
125    
126    /**
127     * @param searchService the search service
128     */

129    public void setSearchService(SearchService searchService)
130    {
131       this.searchService = searchService;
132    }
133    
134    /**
135     * @param permissionService The PermissionService to set.
136     */

137    public void setPermissionService(PermissionService permissionService)
138    {
139       this.permissionService = permissionService;
140    }
141    
142    /**
143     * @return Returns the progressive panels expanded state map.
144     */

145    public Map JavaDoc<String JavaDoc, Boolean JavaDoc> getPanels()
146    {
147       return this.panels;
148    }
149
150    /**
151     * @param panels The progressive panels expanded state map.
152     */

153    public void setPanels(Map JavaDoc<String JavaDoc, Boolean JavaDoc> panels)
154    {
155       this.panels = panels;
156    }
157    
158    /**
159     * @return Returns the saved search Description.
160     */

161    public String JavaDoc getSearchDescription()
162    {
163       return this.searchDescription;
164    }
165
166    /**
167     * @param searchDescription The saved search Description to set.
168     */

169    public void setSearchDescription(String JavaDoc searchDescription)
170    {
171       this.searchDescription = searchDescription;
172    }
173
174    /**
175     * @return Returns the saved search Name.
176     */

177    public String JavaDoc getSearchName()
178    {
179       return this.searchName;
180    }
181
182    /**
183     * @param searchName The saved search Name to set.
184     */

185    public void setSearchName(String JavaDoc searchName)
186    {
187       this.searchName = searchName;
188    }
189
190    /**
191     * @return ID of the last saved search selected by the user
192     */

193    public String JavaDoc getSavedSearch()
194    {
195       return this.savedSearch;
196    }
197
198    /**
199     * @param savedSearch ID of the saved search selected by the user
200     */

201    public void setSavedSearch(String JavaDoc savedSearch)
202    {
203       this.savedSearch = savedSearch;
204    }
205    
206    /**
207     * @return name of the saved search to edit
208     */

209    public String JavaDoc getEditSearchName()
210    {
211       return this.editSearchName;
212    }
213
214    /**
215     * @param editSearchName name of the saved search to edit
216     */

217    public void setEditSearchName(String JavaDoc editSearchName)
218    {
219       this.editSearchName = editSearchName;
220    }
221    
222    /**
223     * @return Returns the searchSaveGlobal.
224     */

225    public boolean isSearchSaveGlobal()
226    {
227       return this.searchSaveGlobal;
228    }
229
230    /**
231     * @param searchSaveGlobal The searchSaveGlobal to set.
232     */

233    public void setSearchSaveGlobal(boolean searchSaveGlobal)
234    {
235       this.searchSaveGlobal = searchSaveGlobal;
236    }
237
238    /**
239     * @return Returns the folder to search, null for all.
240     */

241    public String JavaDoc getLookin()
242    {
243       return this.lookin;
244    }
245    
246    /**
247     * @param lookin The folder to search in or null for all.
248     */

249    public void setLookin(String JavaDoc lookIn)
250    {
251       this.lookin = lookIn;
252    }
253    
254    /**
255     * @return Returns the location.
256     */

257    public NodeRef getLocation()
258    {
259       return this.location;
260    }
261    
262    /**
263     * @param location The location to set.
264     */

265    public void setLocation(NodeRef location)
266    {
267       this.location = location;
268    }
269    
270    /**
271     * @return Returns the search mode.
272     */

273    public String JavaDoc getMode()
274    {
275       return this.mode;
276    }
277    
278    /**
279     * @param mode The search mode to set.
280     */

281    public void setMode(String JavaDoc mode)
282    {
283       this.mode = mode;
284    }
285    
286    /**
287     * @return Returns the savedSearchMode.
288     */

289    public String JavaDoc getSavedSearchMode()
290    {
291       return this.savedSearchMode;
292    }
293
294    /**
295     * @param savedSearchMode The savedSearchMode to set.
296     */

297    public void setSavedSearchMode(String JavaDoc savedSearchMode)
298    {
299       this.savedSearchMode = savedSearchMode;
300    }
301    
302    /**
303     * @return Returns the allow Edit mode.
304     */

305    public boolean isAllowEdit()
306    {
307       boolean allow = (this.savedSearch != null && NO_SELECTION.equals(this.savedSearch) == false);
308       if (allow)
309       {
310          NodeRef savedSearchRef = new NodeRef(Repository.getStoreRef(), this.savedSearch);
311          allow = (permissionService.hasPermission(savedSearchRef, PermissionService.WRITE) == AccessStatus.ALLOWED);
312       }
313       return allow;
314    }
315
316    /**
317     * @param allowEdit The allow Edit mode to set.
318     */

319    public void setAllowEdit(boolean allowEdit)
320    {
321       // dummy method for Bean interface compliance
322
}
323    
324    /**
325     * @return Returns the text to search for.
326     */

327    public String JavaDoc getText()
328    {
329       return this.text;
330    }
331    
332    /**
333     * @param text The text to set.
334     */

335    public void setText(String JavaDoc text)
336    {
337       this.text = text;
338    }
339    
340    /**
341     * Returns the properties for current categories JSF DataModel
342     *
343     * @return JSF DataModel representing the current categories to search against
344     */

345    public DataModel getCategoriesDataModel()
346    {
347       if (this.categoriesDataModel == null)
348       {
349          this.categoriesDataModel = new ListDataModel();
350       }
351       
352       this.categoriesDataModel.setWrappedData(this.categories);
353       
354       return this.categoriesDataModel;
355    }
356    
357    /**
358     * @return Returns true to search location children, false for just the specified location.
359     */

360    public boolean getLocationChildren()
361    {
362       return this.locationChildren;
363    }
364    
365    /**
366     * @param locationChildren True to search location children, false for just the specified location.
367     */

368    public void setLocationChildren(boolean locationChildren)
369    {
370       this.locationChildren = locationChildren;
371    }
372    
373    /**
374     * @return Returns the createdDateFrom.
375     */

376    public Date JavaDoc getCreatedDateFrom()
377    {
378       return this.createdDateFrom;
379    }
380
381    /**
382     * @param createdDateFrom The createdDateFrom to set.
383     */

384    public void setCreatedDateFrom(Date JavaDoc createdDate)
385    {
386       this.createdDateFrom = createdDate;
387    }
388
389    /**
390     * @return Returns the description.
391     */

392    public String JavaDoc getDescription()
393    {
394       return this.description;
395    }
396
397    /**
398     * @param description The description to set.
399     */

400    public void setDescription(String JavaDoc description)
401    {
402       this.description = description;
403    }
404
405    /**
406     * @return Returns the modifiedDateFrom.
407     */

408    public Date JavaDoc getModifiedDateFrom()
409    {
410       return this.modifiedDateFrom;
411    }
412
413    /**
414     * @param modifiedDateFrom The modifiedDateFrom to set.
415     */

416    public void setModifiedDateFrom(Date JavaDoc modifiedDate)
417    {
418       this.modifiedDateFrom = modifiedDate;
419    }
420    
421    /**
422     * @return Returns the createdDateTo.
423     */

424    public Date JavaDoc getCreatedDateTo()
425    {
426       return this.createdDateTo;
427    }
428
429    /**
430     * @param createdDateTo The createdDateTo to set.
431     */

432    public void setCreatedDateTo(Date JavaDoc createdDateTo)
433    {
434       this.createdDateTo = createdDateTo;
435    }
436
437    /**
438     * @return Returns the modifiedDateTo.
439     */

440    public Date JavaDoc getModifiedDateTo()
441    {
442       return this.modifiedDateTo;
443    }
444
445    /**
446     * @param modifiedDateTo The modifiedDateTo to set.
447     */

448    public void setModifiedDateTo(Date JavaDoc modifiedDateTo)
449    {
450       this.modifiedDateTo = modifiedDateTo;
451    }
452
453    /**
454     * @return Returns the title.
455     */

456    public String JavaDoc getTitle()
457    {
458       return this.title;
459    }
460
461    /**
462     * @param title The title to set.
463     */

464    public void setTitle(String JavaDoc title)
465    {
466       this.title = title;
467    }
468    
469    /**
470     * @return Returns the author.
471     */

472    public String JavaDoc getAuthor()
473    {
474       return this.author;
475    }
476
477    /**
478     * @param author The author to set.
479     */

480    public void setAuthor(String JavaDoc author)
481    {
482       this.author = author;
483    }
484    
485    /**
486     * @return Returns the modifiedDateChecked.
487     */

488    public boolean isModifiedDateChecked()
489    {
490       return this.modifiedDateChecked;
491    }
492
493    /**
494     * @param modifiedDateChecked The modifiedDateChecked to set.
495     */

496    public void setModifiedDateChecked(boolean modifiedDateChecked)
497    {
498       this.modifiedDateChecked = modifiedDateChecked;
499    }
500
501    /**
502     * @return Returns the createdDateChecked.
503     */

504    public boolean isCreatedDateChecked()
505    {
506       return this.createdDateChecked;
507    }
508    
509    /**
510     * @return Returns the content type currenty selected
511     */

512    public String JavaDoc getContentType()
513    {
514       return this.contentType;
515    }
516
517    /**
518     * @param contentType Sets the currently selected content type
519     */

520    public void setContentType(String JavaDoc contentType)
521    {
522       this.contentType = contentType;
523    }
524    
525    /**
526     * @return Returns the contentFormat.
527     */

528    public String JavaDoc getContentFormat()
529    {
530       return this.contentFormat;
531    }
532
533    /**
534     * @param contentFormat The contentFormat to set.
535     */

536    public void setContentFormat(String JavaDoc contentFormat)
537    {
538       this.contentFormat = contentFormat;
539    }
540    
541    /**
542     * @return Returns the custom properties Map.
543     */

544    public Map JavaDoc<String JavaDoc, Object JavaDoc> getCustomProperties()
545    {
546       return this.customProperties;
547    }
548
549    /**
550     * @param customProperties The custom properties Map to set.
551     */

552    public void setCustomProperties(Map JavaDoc<String JavaDoc, Object JavaDoc> customProperties)
553    {
554       this.customProperties = customProperties;
555    }
556
557    /**
558     * @param createdDateChecked The createdDateChecked to set.
559     */

560    public void setCreatedDateChecked(boolean createdDateChecked)
561    {
562       this.createdDateChecked = createdDateChecked;
563    }
564    
565    /**
566     * @return Returns a list of content object types to allow the user to select from
567     */

568    public List JavaDoc<SelectItem> getContentTypes()
569    {
570       if (this.contentTypes == null)
571       {
572          FacesContext context = FacesContext.getCurrentInstance();
573          
574          // add the well known cm:content object type by default
575
this.contentTypes = new ArrayList JavaDoc<SelectItem>(5);
576          this.contentTypes.add(new SelectItem(ContentModel.TYPE_CONTENT.toString(),
577                Application.getMessage(context, MSG_CONTENT)));
578          
579          // add any configured content sub-types to the list
580
List JavaDoc<String JavaDoc> types = getSearchConfig().getContentTypes();
581          if (types != null)
582          {
583             DictionaryService dictionaryService = Repository.getServiceRegistry(context).getDictionaryService();
584             for (String JavaDoc type : types)
585             {
586                QName idQName = Repository.resolveToQName(type);
587                TypeDefinition typeDef = dictionaryService.getType(idQName);
588                
589                if (typeDef != null && dictionaryService.isSubClass(typeDef.getName(), ContentModel.TYPE_CONTENT))
590                {
591                   // try and get label from the dictionary
592
String JavaDoc label = typeDef.getTitle();
593                   
594                   // else just use the localname
595
if (label == null)
596                   {
597                      label = idQName.getLocalName();
598                   }
599                   
600                   this.contentTypes.add(new SelectItem(idQName.toString(), label));
601                }
602             }
603             
604             // make sure the list is sorted by the label
605
QuickSort sorter = new QuickSort(this.contentTypes, "label", true, IDataContainer.SORT_CASEINSENSITIVE);
606             sorter.sort();
607          }
608       }
609       
610       return this.contentTypes;
611    }
612    
613    /**
614     * @return Returns a list of content formats to allow the user to select from
615     */

616    public List JavaDoc<SelectItem> getContentFormats()
617    {
618       if (this.contentFormats == null)
619       {
620          this.contentFormats = new ArrayList JavaDoc<SelectItem>(80);
621          ServiceRegistry registry = Repository.getServiceRegistry(FacesContext.getCurrentInstance());
622          MimetypeService mimetypeService = registry.getMimetypeService();
623          
624          // get the mime type display names
625
Map JavaDoc<String JavaDoc, String JavaDoc> mimeTypes = mimetypeService.getDisplaysByMimetype();
626          for (String JavaDoc mimeType : mimeTypes.keySet())
627          {
628             this.contentFormats.add(new SelectItem(mimeType, mimeTypes.get(mimeType)));
629          }
630          
631          // make sure the list is sorted by the values
632
QuickSort sorter = new QuickSort(this.contentFormats, "label", true, IDataContainer.SORT_CASEINSENSITIVE);
633          sorter.sort();
634          
635          // add the "All Formats" constant marker at the top of the list (default selection)
636
this.contentFormats.add(0, new SelectItem("", Application.getMessage(FacesContext.getCurrentInstance(), MSG_ALL_FORMATS)));
637       }
638       
639       return this.contentFormats;
640    }
641    
642    
643    // ------------------------------------------------------------------------------
644
// Action event handlers
645

646    /**
647     * Handler to clear the advanced search screen form details
648     */

649    public void reset(ActionEvent event)
650    {
651       resetFields();
652       this.savedSearch = null;
653    }
654    
655    private void resetFields()
656    {
657       this.text = "";
658       this.mode = MODE_ALL;
659       this.lookin = LOOKIN_ALL;
660       this.contentType = null;
661       this.contentFormat = null;
662       this.location = null;
663       this.locationChildren = true;
664       this.categories = new ArrayList JavaDoc<Node>(2);
665       this.title = null;
666       this.description = null;
667       this.author = null;
668       this.createdDateFrom = null;
669       this.createdDateTo = null;
670       this.modifiedDateFrom = null;
671       this.modifiedDateTo = null;
672       this.createdDateChecked = false;
673       this.modifiedDateChecked = false;
674       this.customProperties.clear();
675    }
676    
677    /**
678     * Handler to perform a search based on the current criteria
679     */

680    public String JavaDoc search()
681    {
682       // construct the Search Context and set on the navigation bean
683
// then simply navigating to the browse screen will cause it pickup the Search Context
684
SearchContext search = new SearchContext();
685       
686       // set the full-text/name field value
687
search.setText(this.text);
688       
689       // set whether to force AND operation on text terms
690
search.setForceAndTerms(Application.getClientConfig(FacesContext.getCurrentInstance()).getForceAndTerms());
691       
692       if (this.mode.equals(MODE_ALL))
693       {
694          search.setMode(SearchContext.SEARCH_ALL);
695       }
696       else if (this.mode.equals(MODE_FILES_TEXT))
697       {
698          search.setMode(SearchContext.SEARCH_FILE_NAMES_CONTENTS);
699       }
700       else if (this.mode.equals(MODE_FILES))
701       {
702          search.setMode(SearchContext.SEARCH_FILE_NAMES);
703       }
704       else if (this.mode.equals(MODE_FOLDERS))
705       {
706          search.setMode(SearchContext.SEARCH_SPACE_NAMES);
707       }
708       
709       // additional attributes search
710
if (this.description != null && this.description.length() != 0)
711       {
712          search.addAttributeQuery(ContentModel.PROP_DESCRIPTION, this.description);
713       }
714       if (this.title != null && this.title.length() != 0)
715       {
716          search.addAttributeQuery(ContentModel.PROP_TITLE, this.title);
717       }
718       if (this.author != null && this.author.length() != 0)
719       {
720          search.addAttributeQuery(ContentModel.PROP_AUTHOR, this.author);
721       }
722       if (this.contentFormat != null && this.contentFormat.length() != 0)
723       {
724          search.setMimeType(this.contentFormat);
725       }
726       if (this.createdDateChecked == true)
727       {
728          SimpleDateFormat JavaDoc df = CachingDateFormat.getDateFormat();
729          String JavaDoc strCreatedDate = df.format(this.createdDateFrom);
730          String JavaDoc strCreatedDateTo = df.format(this.createdDateTo);
731          search.addRangeQuery(ContentModel.PROP_CREATED, strCreatedDate, strCreatedDateTo, true);
732       }
733       if (this.modifiedDateChecked == true)
734       {
735          SimpleDateFormat JavaDoc df = CachingDateFormat.getDateFormat();
736          String JavaDoc strModifiedDate = df.format(this.modifiedDateFrom);
737          String JavaDoc strModifiedDateTo = df.format(this.modifiedDateTo);
738          search.addRangeQuery(ContentModel.PROP_MODIFIED, strModifiedDate, strModifiedDateTo, true);
739       }
740       
741       // walk each of the custom properties add add them as additional attributes
742
for (String JavaDoc qname : this.customProperties.keySet())
743       {
744          Object JavaDoc value = this.customProperties.get(qname);
745          DataTypeDefinition typeDef = getCustomPropertyLookup().get(qname);
746          if (typeDef != null)
747          {
748             QName typeName = typeDef.getName();
749             if (DataTypeDefinition.DATE.equals(typeName) || DataTypeDefinition.DATETIME.equals(typeName))
750             {
751                // only apply date to search if the user has checked the enable checkbox
752
if (value != null && Boolean.valueOf(value.toString()) == true)
753                {
754                   SimpleDateFormat JavaDoc df = CachingDateFormat.getDateFormat();
755                   String JavaDoc strDateFrom = df.format(this.customProperties.get(
756                         UISearchCustomProperties.PREFIX_DATE_FROM + qname));
757                   String JavaDoc strDateTo = df.format(this.customProperties.get(
758                         UISearchCustomProperties.PREFIX_DATE_TO + qname));
759                   search.addRangeQuery(QName.createQName(qname), strDateFrom, strDateTo, true);
760                }
761             }
762             else if (DataTypeDefinition.BOOLEAN.equals(typeName))
763             {
764                if (((Boolean JavaDoc)value) == true)
765                {
766                   search.addFixedValueQuery(QName.createQName(qname), value.toString());
767                }
768             }
769             else if (DataTypeDefinition.NODE_REF.equals(typeName) || DataTypeDefinition.CATEGORY.equals(typeName))
770             {
771                if (value != null)
772                {
773                   search.addFixedValueQuery(QName.createQName(qname), value.toString());
774                }
775             }
776             else if (DataTypeDefinition.INT.equals(typeName) || DataTypeDefinition.LONG.equals(typeName) ||
777                      DataTypeDefinition.FLOAT.equals(typeName) || DataTypeDefinition.DOUBLE.equals(typeName))
778             {
779                String JavaDoc strVal = value.toString();
780                if (strVal != null && strVal.length() != 0)
781                {
782                   search.addFixedValueQuery(QName.createQName(qname), strVal);
783                }
784             }
785             else
786             {
787                // by default use toString() value - this is for text fields and unknown types
788
String JavaDoc strVal = value.toString();
789                if (strVal != null && strVal.length() != 0)
790                {
791                   search.addAttributeQuery(QName.createQName(qname), strVal);
792                }
793             }
794          }
795       }
796       
797       // location path search
798
if (this.lookin.equals(LOOKIN_OTHER) && this.location != null)
799       {
800          search.setLocation(SearchContext.getPathFromSpaceRef(this.location, this.locationChildren));
801       }
802       
803       // category path search
804
if (this.categories.size() != 0)
805       {
806          String JavaDoc[] paths = new String JavaDoc[this.categories.size()];
807          for (int i=0; i<paths.length; i++)
808          {
809             Node category = this.categories.get(i);
810             boolean includeChildren = (Boolean JavaDoc)category.getProperties().get(INCLUDE_CHILDREN);
811             paths[i] = SearchContext.getPathFromSpaceRef(category.getNodeRef(), includeChildren);
812          }
813          search.setCategories(paths);
814       }
815       
816       // content type restriction
817
if (this.contentType != null)
818       {
819          search.setContentType(this.contentType);
820       }
821       
822       // set the Search Context onto the top-level navigator bean
823
// this causes the browse screen to switch into search results view
824
this.navigator.setSearchContext(search);
825       
826       return OUTCOME_BROWSE;
827    }
828    
829    /**
830     * Action handler called to initiate the saved search screen for Create
831     */

832    public String JavaDoc saveNewSearch()
833    {
834       this.searchDescription = null;
835       this.searchName = null;
836       this.searchSaveGlobal = false;
837       
838       return "saveNewSearch";
839    }
840    
841    /**
842     * Action handler called to initiate the saved search screen for Edit
843     */

844    public String JavaDoc saveEditSearch()
845    {
846       this.searchDescription = null;
847       this.searchName = null;
848       this.editSearchName = null;
849       
850       // load previously selected search for overwrite
851
try
852       {
853          NodeRef searchRef = new NodeRef(Repository.getStoreRef(), this.savedSearch);
854          Node searchNode = new Node(searchRef);
855          if (this.nodeService.exists(searchRef) && searchNode.hasPermission(PermissionService.WRITE))
856          {
857             Node node = new Node(searchRef);
858             this.searchName = node.getName();
859             this.editSearchName = this.searchName;
860             this.searchDescription = (String JavaDoc)node.getProperties().get(ContentModel.PROP_DESCRIPTION);
861          }
862          else
863          {
864             // unable to overwrite existing saved search
865
this.savedSearch = null;
866          }
867       }
868       catch (Throwable JavaDoc err)
869       {
870          // unable to overwrite existing saved search for some other reason
871
this.savedSearch = null;
872       }
873       
874       return "saveEditSearch";
875    }
876    
877    /**
878     * Action handler called to save a new search
879     */

880    public String JavaDoc saveNewSearchOK()
881    {
882       String JavaDoc outcome = OUTCOME_BROWSE;
883       
884       NodeRef searchesRef;
885       if (isSearchSaveGlobal() == true)
886       {
887          searchesRef = getGlobalSearchesRef();
888       }
889       else
890       {
891          searchesRef = getUserSearchesRef();
892       }
893       
894       SearchContext search = this.navigator.getSearchContext();
895       if (searchesRef != null && search != null)
896       {
897          UserTransaction JavaDoc tx = null;
898          try
899          {
900             FacesContext context = FacesContext.getCurrentInstance();
901             tx = Repository.getUserTransaction(context);
902             tx.begin();
903             
904             // create new content node as the saved search object
905
Map JavaDoc<QName, Serializable JavaDoc> props = new HashMap JavaDoc<QName, Serializable JavaDoc>(2, 1.0f);
906             props.put(ContentModel.PROP_NAME, this.searchName);
907             props.put(ContentModel.PROP_DESCRIPTION, this.searchDescription);
908             ChildAssociationRef childRef = this.nodeService.createNode(
909                   searchesRef,
910                   ContentModel.ASSOC_CONTAINS,
911                   QName.createQName(NamespaceService.ALFRESCO_URI, QName.createValidLocalName(this.searchName)),
912                   ContentModel.TYPE_CONTENT,
913                   props);
914             
915             ContentService contentService = Repository.getServiceRegistry(context).getContentService();
916             ContentWriter writer = contentService.getWriter(childRef.getChildRef(), ContentModel.PROP_CONTENT, true);
917             
918             // get a writer to our new node ready for XML content
919
writer.setMimetype(MimetypeMap.MIMETYPE_XML);
920             writer.setEncoding("UTF-8");
921             
922             // output an XML serialized version of the SearchContext object
923
writer.putContent(search.toXML());
924             
925             tx.commit();
926             
927             this.cachedSavedSearches.clear();
928             this.savedSearch = null;
929          }
930          catch (Throwable JavaDoc e)
931          {
932             try { if (tx != null) {tx.rollback();} } catch (Exception JavaDoc ex) {}
933             Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
934                   FacesContext.getCurrentInstance(), MSG_ERROR_SAVE_SEARCH), e.getMessage()), e);
935             outcome = null;
936          }
937       }
938       
939       return outcome;
940    }
941    
942    /**
943     * Action handler called to save an existing search
944     */

945    public String JavaDoc saveEditSearchOK()
946    {
947       String JavaDoc outcome = OUTCOME_BROWSE;
948       
949       SearchContext search = this.navigator.getSearchContext();
950       if (search != null)
951       {
952          UserTransaction JavaDoc tx = null;
953          try
954          {
955             FacesContext context = FacesContext.getCurrentInstance();
956             tx = Repository.getUserTransaction(context);
957             tx.begin();
958             
959             // handle Edit e.g. Overwrite of existing search
960
// detect if was previously selected saved search (e.g. NodeRef not null)
961
NodeRef searchRef = new NodeRef(Repository.getStoreRef(), this.savedSearch);
962             if (this.nodeService.exists(searchRef))
963             {
964                Map JavaDoc<QName, Serializable JavaDoc> props = this.nodeService.getProperties(searchRef);
965                props.put(ContentModel.PROP_NAME, this.searchName);
966                props.put(ContentModel.PROP_DESCRIPTION, this.searchDescription);
967                this.nodeService.setProperties(searchRef, props);
968                
969                ContentService contentService = Repository.getServiceRegistry(context).getContentService();
970                ContentWriter writer = contentService.getWriter(searchRef, ContentModel.PROP_CONTENT, true);
971                
972                // get a writer to our new node ready for XML content
973
writer.setMimetype(MimetypeMap.MIMETYPE_XML);
974                writer.setEncoding("UTF-8");
975                
976                // output an XML serialized version of the SearchContext object
977
writer.putContent(search.toXML());
978                
979                tx.commit();
980             }
981             
982             this.cachedSavedSearches.clear();
983             this.savedSearch = null;
984          }
985          catch (Throwable JavaDoc e)
986          {
987             try { if (tx != null) {tx.rollback();} } catch (Exception JavaDoc ex) {}
988             Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
989                   FacesContext.getCurrentInstance(), MSG_ERROR_SAVE_SEARCH), e.getMessage()), e);
990             outcome = null;
991          }
992       }
993       
994       return outcome;
995    }
996    
997    /**
998     * @return list of saved searches as SelectItem objects
999     */

1000   public List JavaDoc<SelectItem> getSavedSearches()
1001   {
1002      List JavaDoc<SelectItem> savedSearches = cachedSavedSearches.get();
1003      if (savedSearches == null)
1004      {
1005         FacesContext fc = FacesContext.getCurrentInstance();
1006         ServiceRegistry services = Repository.getServiceRegistry(fc);
1007         
1008         // get the searches list from the current user or global searches location
1009
NodeRef searchesRef = null;
1010         if (SAVED_SEARCHES_USER.equals(getSavedSearchMode()) == true)
1011         {
1012            searchesRef = getUserSearchesRef();
1013         }
1014         else if (SAVED_SEARCHES_GLOBAL.equals(getSavedSearchMode()) == true)
1015         {
1016            searchesRef = getGlobalSearchesRef();
1017         }
1018         
1019         // read the content nodes under the folder
1020
if (searchesRef != null)
1021         {
1022            DictionaryService dd = services.getDictionaryService();
1023            
1024            List JavaDoc<ChildAssociationRef> childRefs = nodeService.getChildAssocs(
1025                  searchesRef,
1026                  ContentModel.ASSOC_CONTAINS,
1027                  RegexQNamePattern.MATCH_ALL);
1028            
1029            savedSearches = new ArrayList JavaDoc<SelectItem>(childRefs.size() + 1);
1030            if (childRefs.size() != 0)
1031            {
1032               for (ChildAssociationRef ref : childRefs)
1033               {
1034                  Node childNode = new Node(ref.getChildRef());
1035                  if (dd.isSubClass(childNode.getType(), ContentModel.TYPE_CONTENT))
1036                  {
1037                     savedSearches.add(new SelectItem(childNode.getId(), childNode.getName()));
1038                  }
1039               }
1040               
1041               // make sure the list is sorted by the label
1042
QuickSort sorter = new QuickSort(savedSearches, "label", true, IDataContainer.SORT_CASEINSENSITIVE);
1043               sorter.sort();
1044            }
1045         }
1046         else
1047         {
1048            // handle missing/access denied folder case
1049
savedSearches = new ArrayList JavaDoc<SelectItem>(1);
1050         }
1051         
1052         // add an entry (at the start) to instruct the user to select a saved search
1053
savedSearches.add(0, new SelectItem(NO_SELECTION,
1054               Application.getMessage(FacesContext.getCurrentInstance(), MSG_SELECT_SAVED_SEARCH)));
1055         
1056         // store in the cache (will auto-expire)
1057
cachedSavedSearches.put(savedSearches);
1058      }
1059      
1060      return savedSearches;
1061   }
1062   
1063   /**
1064    * Change the current saved searches list mode based on user selection
1065    */

1066   public void savedSearchModeChanged(ActionEvent event)
1067   {
1068      UIModeList savedModeList = (UIModeList)event.getComponent();
1069      
1070      // get the saved searches list mode
1071
String JavaDoc viewMode = savedModeList.getValue().toString();
1072      
1073      // persist
1074
setSavedSearchMode(viewMode);
1075      
1076      // clear existing caches and values
1077
// the values will be re-queried when the client requests the saved searches list
1078
this.cachedSavedSearches.clear();
1079      this.savedSearch = null;
1080   }
1081   
1082   /**
1083    * Action handler called when a saved search is selected by the user
1084    */

1085   public void selectSearch(ActionEvent event)
1086   {
1087      if (NO_SELECTION.equals(savedSearch) == false)
1088      {
1089         // read an XML serialized version of the SearchContext object
1090
NodeRef searchSearchRef = new NodeRef(Repository.getStoreRef(), savedSearch);
1091         ServiceRegistry services = Repository.getServiceRegistry(FacesContext.getCurrentInstance());
1092         ContentService cs = services.getContentService();
1093         try
1094         {
1095            if (services.getNodeService().exists(searchSearchRef))
1096            {
1097               ContentReader reader = cs.getReader(searchSearchRef, ContentModel.PROP_CONTENT);
1098               SearchContext search = new SearchContext().fromXML(reader.getContentString());
1099               
1100               // if we get here we read the serialized object successfully
1101
// now setup the UI to match the new SearchContext object
1102
initialiseFromContext(search);
1103            }
1104         }
1105         catch (Throwable JavaDoc err)
1106         {
1107            Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
1108                  FacesContext.getCurrentInstance(), MSG_ERROR_RESTORE_SEARCH), err.getMessage()), err);
1109         }
1110      }
1111   }
1112   
1113   /**
1114    * Initialise the Advanced Search UI screen from a SearchContext
1115    *
1116    * @param search the SearchContext to retrieve state from
1117    */

1118   private void initialiseFromContext(SearchContext search)
1119   {
1120      resetFields();
1121      
1122      this.text = search.getText();
1123      
1124      switch (search.getMode())
1125      {
1126         case SearchContext.SEARCH_ALL:
1127            this.mode = MODE_ALL;
1128            break;
1129         case SearchContext.SEARCH_FILE_NAMES_CONTENTS:
1130            this.mode = MODE_FILES_TEXT;
1131            break;
1132         case SearchContext.SEARCH_FILE_NAMES:
1133            this.mode = MODE_FILES;
1134            break;
1135         case SearchContext.SEARCH_SPACE_NAMES:
1136            this.mode = MODE_FOLDERS;
1137            break;
1138      }
1139      this.panels.put(PANEL_RESTRICT, true);
1140      
1141      if (search.getLocation() != null)
1142      {
1143         this.locationChildren = search.getLocation().endsWith("//*");
1144         this.location = findNodeRefFromPath(search.getLocation());
1145         this.lookin = LOOKIN_OTHER;
1146         this.panels.put(PANEL_LOCATION, true);
1147      }
1148      
1149      String JavaDoc[] categories = search.getCategories();
1150      if (categories != null && categories.length != 0)
1151      {
1152         for (String JavaDoc category : categories)
1153         {
1154            NodeRef categoryRef = findNodeRefFromPath(category);
1155            if (categoryRef != null)
1156            {
1157               Node categoryNode = new MapNode(categoryRef);
1158               // add a value bound propery used to indicate if searching across children is selected
1159
categoryNode.getProperties().put(INCLUDE_CHILDREN, category.endsWith("//*"));
1160               this.categories.add(categoryNode);
1161            }
1162         }
1163         this.panels.put(PANEL_CATEGORIES, true);
1164      }
1165      
1166      this.contentType = search.getContentType();
1167      this.contentFormat = search.getMimeType();
1168      
1169      this.description = search.getAttributeQuery(ContentModel.PROP_DESCRIPTION);
1170      this.title = search.getAttributeQuery(ContentModel.PROP_TITLE);
1171      this.author = search.getAttributeQuery(ContentModel.PROP_AUTHOR);
1172      if (this.contentType != null || this.contentFormat != null ||
1173          this.description != null || this.title != null || this.author != null)
1174      {
1175         this.panels.put(PANEL_ATTRS, true);
1176      }
1177      
1178      RangeProperties createdDate = search.getRangeProperty(ContentModel.PROP_CREATED);
1179      if (createdDate != null)
1180      {
1181         this.createdDateFrom = Utils.parseXMLDateFormat(createdDate.lower);
1182         this.createdDateTo = Utils.parseXMLDateFormat(createdDate.upper);
1183         this.createdDateChecked = true;
1184         this.panels.put(PANEL_ATTRS, true);
1185      }
1186      RangeProperties modifiedDate = search.getRangeProperty(ContentModel.PROP_MODIFIED);
1187      if (modifiedDate != null)
1188      {
1189         this.modifiedDateFrom = Utils.parseXMLDateFormat(modifiedDate.lower);
1190         this.modifiedDateTo = Utils.parseXMLDateFormat(modifiedDate.upper);
1191         this.modifiedDateChecked = true;
1192         this.panels.put(PANEL_ATTRS, true);
1193      }
1194      
1195      // custom fields - calculate which are required to set through the custom properties lookup table
1196
for (String JavaDoc qname : getCustomPropertyLookup().keySet())
1197      {
1198         DataTypeDefinition typeDef = getCustomPropertyLookup().get(qname);
1199         if (typeDef != null)
1200         {
1201            QName typeName = typeDef.getName();
1202            if (DataTypeDefinition.DATE.equals(typeName) || DataTypeDefinition.DATETIME.equals(typeName))
1203            {
1204               RangeProperties dateProps = search.getRangeProperty(QName.createQName(qname));
1205               if (dateProps != null)
1206               {
1207                  this.customProperties.put(UISearchCustomProperties.PREFIX_DATE_FROM + qname,
1208                        Utils.parseXMLDateFormat(dateProps.lower));
1209                  this.customProperties.put(UISearchCustomProperties.PREFIX_DATE_TO + qname,
1210                        Utils.parseXMLDateFormat(dateProps.upper));
1211                  this.customProperties.put(qname, true);
1212                  this.panels.put(PANEL_CUSTOM, true);
1213               }
1214            }
1215            else if (DataTypeDefinition.BOOLEAN.equals(typeName))
1216            {
1217               String JavaDoc strBool = search.getFixedValueQuery(QName.createQName(qname));
1218               if (strBool != null)
1219               {
1220                  this.customProperties.put(qname, Boolean.parseBoolean(strBool));
1221                  this.panels.put(PANEL_CUSTOM, true);
1222               }
1223            }
1224            else if (DataTypeDefinition.NODE_REF.equals(typeName) || DataTypeDefinition.CATEGORY.equals(typeName))
1225            {
1226               String JavaDoc strNodeRef = search.getFixedValueQuery(QName.createQName(qname));
1227               if (strNodeRef != null)
1228               {
1229                  this.customProperties.put(qname, new NodeRef(strNodeRef));
1230                  this.panels.put(PANEL_CUSTOM, true);
1231               }
1232            }
1233            else if (DataTypeDefinition.INT.equals(typeName) || DataTypeDefinition.LONG.equals(typeName) ||
1234                     DataTypeDefinition.FLOAT.equals(typeName) || DataTypeDefinition.DOUBLE.equals(typeName))
1235            {
1236               // currently numbers are rendered as text in UISearchCustomProperties component
1237
// this code will need updating if that changes!
1238
this.customProperties.put(qname, search.getFixedValueQuery(QName.createQName(qname)));
1239               this.panels.put(PANEL_CUSTOM, true);
1240            }
1241            else
1242            {
1243               this.customProperties.put(qname, search.getAttributeQuery(QName.createQName(qname)));
1244               this.panels.put(PANEL_CUSTOM, true);
1245            }
1246         }
1247      }
1248   }
1249   
1250   /**
1251    * Return NodeRef to the last Node referenced on the end of the specified xpath value
1252    *
1253    * @param xpath XPath - note that any /* or //* will be removed to find trailing node
1254    *
1255    * @return NodeRef if found null otherwise
1256    */

1257   private NodeRef findNodeRefFromPath(String JavaDoc xpath)
1258   {
1259      if (xpath.endsWith("//*"))
1260      {
1261         xpath = xpath.substring(0, xpath.lastIndexOf("//*"));
1262      }
1263      else if (xpath.endsWith("/*"))
1264      {
1265         xpath = xpath.substring(0, xpath.lastIndexOf("/*"));
1266      }
1267      NodeRef rootRef = new NodeRef(Repository.getStoreRef(), Application.getCompanyRootId());
1268      List JavaDoc<NodeRef> results = null;
1269      try
1270      {
1271         results = searchService.selectNodes(
1272               rootRef,
1273               xpath,
1274               null,
1275               namespaceService,
1276               false);
1277      }
1278      catch (AccessDeniedException err)
1279      {
1280         // ignore and return null
1281
}
1282      
1283      return (results != null && results.size() == 1) ? results.get(0) : null;
1284   }
1285   
1286   /**
1287    * @return the cached reference to the shared Saved Searches folder
1288    */

1289   private NodeRef getUserSearchesRef()
1290   {
1291      if (userSearchesRef == null)
1292      {
1293         NodeRef globalRef = getGlobalSearchesRef();
1294         if (globalRef != null)
1295         {
1296            FacesContext fc = FacesContext.getCurrentInstance();
1297            User user = Application.getCurrentUser(fc);
1298            String JavaDoc xpath = NamespaceService.APP_MODEL_PREFIX + ":" + QName.createValidLocalName(user.getUserName());
1299            
1300            List JavaDoc<NodeRef> results = null;
1301            try
1302            {
1303               results = searchService.selectNodes(
1304                     globalRef,
1305                     xpath,
1306                     null,
1307                     namespaceService,
1308                     false);
1309            }
1310            catch (AccessDeniedException err)
1311            {
1312               // ignore and return null
1313
}
1314            
1315            if (results != null)
1316            {
1317               if (results.size() == 1)
1318               {
1319                  userSearchesRef = results.get(0);
1320               }
1321               else if (results.size() == 0 && new Node(globalRef).hasPermission(PermissionService.ADD_CHILDREN))
1322               {
1323                  // attempt to create folder for this user for first time
1324
// create the preferences Node for this user
1325
Map JavaDoc<QName, Serializable JavaDoc> props = new HashMap JavaDoc<QName, Serializable JavaDoc>(2, 1.0f);
1326                  props.put(ContentModel.PROP_NAME, user.getUserName());
1327                  ChildAssociationRef childRef = nodeService.createNode(
1328                        globalRef,
1329                        ContentModel.ASSOC_CONTAINS,
1330                        QName.createQName(NamespaceService.APP_MODEL_1_0_URI, QName.createValidLocalName(user.getUserName())),
1331                        ContentModel.TYPE_FOLDER,
1332                        props);
1333                  
1334                  userSearchesRef = childRef.getChildRef();
1335               }
1336            }
1337         }
1338      }
1339      
1340      return userSearchesRef;
1341   }
1342   
1343   /**
1344    * @return the cached reference to the global Saved Searches folder
1345    */

1346   private NodeRef getGlobalSearchesRef()
1347   {
1348      if (globalSearchesRef == null)
1349      {
1350         FacesContext fc = FacesContext.getCurrentInstance();
1351         String JavaDoc xpath = Application.getRootPath(fc) + "/" +
1352                        Application.getGlossaryFolderName(fc) + "/" +
1353                        Application.getSavedSearchesFolderName(fc);
1354         
1355         List JavaDoc<NodeRef> results = null;
1356         try
1357         {
1358            results = searchService.selectNodes(
1359                  nodeService.getRootNode(Repository.getStoreRef()),
1360                  xpath,
1361                  null,
1362                  namespaceService,
1363                  false);
1364         }
1365         catch (AccessDeniedException err)
1366         {
1367            // ignore and return null
1368
}
1369         
1370         if (results != null && results.size() == 1)
1371         {
1372            globalSearchesRef = results.get(0);
1373         }
1374      }
1375      
1376      return globalSearchesRef;
1377   }
1378   
1379   /**
1380    * Action handler called when the Add button is pressed to add the current Category selection
1381    */

1382   public void addCategory(ActionEvent event)
1383   {
1384      UICategorySelector selector = (UICategorySelector)event.getComponent().findComponent("catSelector");
1385      UISelectBoolean chkChildren = (UISelectBoolean)event.getComponent().findComponent("chkCatChildren");
1386      
1387      NodeRef categoryRef = (NodeRef)selector.getValue();
1388      if (categoryRef != null)
1389      {
1390         Node categoryNode = new MapNode(categoryRef);
1391         // add a value bound propery used to indicate if searching across children is selected
1392
categoryNode.getProperties().put(INCLUDE_CHILDREN, chkChildren.isSelected());
1393         this.categories.add(categoryNode);
1394      }
1395   }
1396   
1397   /**
1398    * Action handler called when the Remove button is pressed to remove a category
1399    */

1400   public void removeCategory(ActionEvent event)
1401   {
1402      Node node = (Node)this.categoriesDataModel.getRowData();
1403      if (node != null)
1404      {
1405         this.categories.remove(node);
1406      }
1407   }
1408   
1409   /**
1410    * @return ClientConfigElement
1411    */

1412   private AdvancedSearchConfigElement getSearchConfig()
1413   {
1414      if (searchConfigElement == null)
1415      {
1416         searchConfigElement = (AdvancedSearchConfigElement)Application.getConfigService(
1417               FacesContext.getCurrentInstance()).getConfig("Advanced Search").
1418               getConfigElement(AdvancedSearchConfigElement.CONFIG_ELEMENT_ID);
1419      }
1420      
1421      return searchConfigElement;
1422   }
1423   
1424   /**
1425    * Helper map to lookup custom property QName strings against a DataTypeDefinition
1426    *
1427    * @return custom property lookup Map
1428    */

1429   private Map JavaDoc<String JavaDoc, DataTypeDefinition> getCustomPropertyLookup()
1430   {
1431      if (customPropertyLookup == null)
1432      {
1433         customPropertyLookup = new HashMap JavaDoc<String JavaDoc, DataTypeDefinition>(7, 1.0f);
1434         List JavaDoc<CustomProperty> customProps = getSearchConfig().getCustomProperties();
1435         if (customProps != null)
1436         {
1437            DictionaryService dd = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getDictionaryService();
1438            for (CustomProperty customProp : customProps)
1439            {
1440               PropertyDefinition propDef = null;
1441               QName propQName = Repository.resolveToQName(customProp.Property);
1442               if (customProp.Type != null)
1443               {
1444                  QName type = Repository.resolveToQName(customProp.Type);
1445                  TypeDefinition typeDef = dd.getType(type);
1446                  propDef = typeDef.getProperties().get(propQName);
1447               }
1448               else if (customProp.Aspect != null)
1449               {
1450                  QName aspect = Repository.resolveToQName(customProp.Aspect);
1451                  AspectDefinition aspectDef = dd.getAspect(aspect);
1452                  propDef = aspectDef.getProperties().get(propQName);
1453               }
1454               customPropertyLookup.put(propQName.toString(), propDef.getDataType());
1455            }
1456         }
1457      }
1458      return customPropertyLookup;
1459   }
1460   
1461   /**
1462    * Save the state of the progressive panel that was expanded/collapsed
1463    */

1464   public void expandPanel(ActionEvent event)
1465   {
1466      if (event instanceof ExpandedEvent)
1467      {
1468         this.panels.put(event.getComponent().getId(), ((ExpandedEvent)event).State);
1469      }
1470   }
1471   
1472   
1473   // ------------------------------------------------------------------------------
1474
// Private data
1475

1476   private static final String JavaDoc MSG_CONTENT = "content";
1477   private static final String JavaDoc MSG_ALL_FORMATS = "all_formats";
1478   private static final String JavaDoc MSG_ERROR_SAVE_SEARCH = "error_save_search";
1479   private static final String JavaDoc MSG_ERROR_RESTORE_SEARCH = "error_restore_search";
1480   private static final String JavaDoc MSG_SELECT_SAVED_SEARCH = "select_saved_search";
1481   
1482   private static final String JavaDoc OUTCOME_BROWSE = "browse";
1483   
1484   private static final String JavaDoc PANEL_CUSTOM = "custom-panel";
1485   private static final String JavaDoc PANEL_ATTRS = "attrs-panel";
1486   private static final String JavaDoc PANEL_CATEGORIES = "categories-panel";
1487   private static final String JavaDoc PANEL_RESTRICT = "restrict-panel";
1488   private static final String JavaDoc PANEL_LOCATION = "location-panel";
1489   
1490   private static final String JavaDoc INCLUDE_CHILDREN = "includeChildren";
1491   
1492   private static final String JavaDoc MODE_ALL = "all";
1493   private static final String JavaDoc MODE_FILES_TEXT = "files_text";
1494   private static final String JavaDoc MODE_FILES = "files";
1495   private static final String JavaDoc MODE_FOLDERS = "folders";
1496   
1497   private static final String JavaDoc LOOKIN_ALL = "all";
1498   private static final String JavaDoc LOOKIN_OTHER = "other";
1499   
1500   private static final String JavaDoc SAVED_SEARCHES_USER = "user";
1501   private static final String JavaDoc SAVED_SEARCHES_GLOBAL = "global";
1502   
1503   private static final String JavaDoc NO_SELECTION = "NONE";
1504   
1505   /** The NodeService to be used by the bean */
1506   protected NodeService nodeService;
1507   
1508   /** The NamespaceService to be used by the bean */
1509   protected NamespaceService namespaceService;
1510   
1511   /** The NavigationBean reference */
1512   protected NavigationBean navigator;
1513   
1514   /** SearchService bean reference */
1515   protected SearchService searchService;
1516   
1517   /** PermissionService */
1518   protected PermissionService permissionService;
1519   
1520   /** Client Config reference */
1521   protected AdvancedSearchConfigElement searchConfigElement = null;
1522   
1523   /** Progressive panel UI state */
1524   private Map JavaDoc<String JavaDoc, Boolean JavaDoc> panels = new HashMap JavaDoc(5, 1.0f);
1525   
1526   /** Saved search properties */
1527   private String JavaDoc searchName;
1528   private String JavaDoc searchDescription;
1529   
1530   /** custom property names to values */
1531   private Map JavaDoc<String JavaDoc, Object JavaDoc> customProperties = new HashMap JavaDoc(5, 1.0f);
1532   
1533   /** lookup of custom property QName string to DataTypeDefinition for the property */
1534   private Map JavaDoc<String JavaDoc, DataTypeDefinition> customPropertyLookup = null;
1535   
1536   /** content types to for restricting searches */
1537   private List JavaDoc<SelectItem> contentTypes;
1538   
1539   /** content format list restricting searches */
1540   private List JavaDoc<SelectItem> contentFormats;
1541   
1542   /** content type selection */
1543   private String JavaDoc contentType;
1544   
1545   /** content format selection */
1546   private String JavaDoc contentFormat;
1547   
1548   /** the text to search for */
1549   private String JavaDoc text = "";
1550   
1551   /** search mode */
1552   private String JavaDoc mode = MODE_ALL;
1553   
1554   /** folder lookin mode */
1555   private String JavaDoc lookin = LOOKIN_ALL;
1556   
1557   /** Space Selector location */
1558   private NodeRef location = null;
1559   
1560   /** categories to search */
1561   private List JavaDoc<Node> categories = new ArrayList JavaDoc<Node>(2);
1562   
1563   /** datamodel for table of categories to search */
1564   private DataModel categoriesDataModel = null;
1565   
1566   /** title attribute to search */
1567   private String JavaDoc title = null;
1568   
1569   /** description attribute to search */
1570   private String JavaDoc description = null;
1571   
1572   /** created attribute to search from */
1573   private Date JavaDoc createdDateFrom = null;
1574   
1575   /** created attribute to search to */
1576   private Date JavaDoc createdDateTo = null;
1577   
1578   /** modified attribute to search from */
1579   private Date JavaDoc modifiedDateFrom = null;
1580   
1581   /** modified attribute to search to */
1582   private Date JavaDoc modifiedDateTo = null;
1583   
1584   /** true to search location children as well as location */
1585   private boolean locationChildren = true;
1586   
1587   /** author (creator) attribute to search */
1588   private String JavaDoc author = null;
1589   
1590   private boolean modifiedDateChecked = false;
1591   private boolean createdDateChecked = false;
1592   
1593   /** cached ref to the global saved searches folder */
1594   private NodeRef globalSearchesRef = null;
1595   
1596   /** cached ref to the current users saved searches folder */
1597   private NodeRef userSearchesRef = null;
1598   
1599   /** ID to the last selected saved search */
1600   private String JavaDoc savedSearch = null;
1601   
1602   /** ModeList component value for selecting user/global searches */
1603   private String JavaDoc savedSearchMode = SAVED_SEARCHES_USER;
1604   
1605   /** name of the saved search to edit */
1606   private String JavaDoc editSearchName = null;
1607   
1608   /** form field for saving search as user/global */
1609   private boolean searchSaveGlobal = false;
1610   
1611   /** auto-expiring cache of the list of saved searches */
1612   private ExpiringValueCache<List JavaDoc<SelectItem>> cachedSavedSearches = new ExpiringValueCache<List JavaDoc<SelectItem>>();
1613}
1614
Popular Tags