mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-31 17:39:05 +00:00
. First pass of the Saved Searches functionality for the web-client
. Saved Searches bootstrap folder . Document details and Space details page now show a copy-and-paste NodeRef link . Minor bug fixes to Breadcrumb and ActionLink components git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2104 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
@@ -130,6 +130,7 @@ view_in_webdav=View in WebDAV
|
|||||||
view_in_cifs=View in CIFS
|
view_in_cifs=View in CIFS
|
||||||
download_content=Download Content
|
download_content=Download Content
|
||||||
details_page_bookmark=External Access URL
|
details_page_bookmark=External Access URL
|
||||||
|
noderef_link=Alfresco Node Reference
|
||||||
links=Links
|
links=Links
|
||||||
create_shortcut=Create Shortcut
|
create_shortcut=Create Shortcut
|
||||||
navigation=Navigation
|
navigation=Navigation
|
||||||
@@ -277,6 +278,13 @@ show_results_categories=Show me results in the categories
|
|||||||
include_sub_categories=Include sub-categories
|
include_sub_categories=Include sub-categories
|
||||||
also_search_results=More search options
|
also_search_results=More search options
|
||||||
additional_options=Additional options
|
additional_options=Additional options
|
||||||
|
save_search=Save Search
|
||||||
|
saved_searches=Saved Searches
|
||||||
|
title_save_search=Save Search Query
|
||||||
|
save_search_description=Save a search query for use again later
|
||||||
|
search_props=Saved Search Properties
|
||||||
|
select_saved_search=Select a Saved Search...
|
||||||
|
saved_search_warning=This operation will attempt to overwrite the existing saved search ''{0}''
|
||||||
|
|
||||||
# Forum messages
|
# Forum messages
|
||||||
forums=Forum Space
|
forums=Forum Space
|
||||||
@@ -894,6 +902,8 @@ error_import_no_file=Can not find an ACP file to import!
|
|||||||
error_import_empty_file=You can not import an empty ACP file!
|
error_import_empty_file=You can not import an empty ACP file!
|
||||||
error_import_all=Please correct the import errors below then click OK.
|
error_import_all=Please correct the import errors below then click OK.
|
||||||
error_export_all=Please correct the export errors below then click OK.
|
error_export_all=Please correct the export errors below then click OK.
|
||||||
|
error_save_search=Failed to save search due to error: {0}
|
||||||
|
error_restore_search=Failed to restore saved search due to error: {0}
|
||||||
|
|
||||||
# Confirmations
|
# Confirmations
|
||||||
return_to_application=Return to application
|
return_to_application=Return to application
|
||||||
|
@@ -68,6 +68,7 @@ public class Application
|
|||||||
private static String glossaryFolderName;
|
private static String glossaryFolderName;
|
||||||
private static String spaceTemplatesFolderName;
|
private static String spaceTemplatesFolderName;
|
||||||
private static String contentTemplatesFolderName;
|
private static String contentTemplatesFolderName;
|
||||||
|
private static String savedSearchesFolderName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Private constructor to prevent instantiation of this class
|
* Private constructor to prevent instantiation of this class
|
||||||
@@ -261,7 +262,7 @@ public class Application
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns the root path for the application (retrieved from config service)
|
* @return Returns the root path for the application
|
||||||
*/
|
*/
|
||||||
public static String getRootPath(ServletContext context)
|
public static String getRootPath(ServletContext context)
|
||||||
{
|
{
|
||||||
@@ -269,7 +270,7 @@ public class Application
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns the root path for the application (retrieved from config service)
|
* @return Returns the root path for the application
|
||||||
*/
|
*/
|
||||||
public static String getRootPath(FacesContext context)
|
public static String getRootPath(FacesContext context)
|
||||||
{
|
{
|
||||||
@@ -277,7 +278,7 @@ public class Application
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns the glossary folder name (retrieved from config service)
|
* @return Returns the glossary folder name
|
||||||
*/
|
*/
|
||||||
public static String getGlossaryFolderName(ServletContext context)
|
public static String getGlossaryFolderName(ServletContext context)
|
||||||
{
|
{
|
||||||
@@ -285,7 +286,7 @@ public class Application
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns the glossary folder name (retrieved from config service)
|
* @return Returns the glossary folder name
|
||||||
*/
|
*/
|
||||||
public static String getGlossaryFolderName(FacesContext context)
|
public static String getGlossaryFolderName(FacesContext context)
|
||||||
{
|
{
|
||||||
@@ -293,7 +294,7 @@ public class Application
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns the Space templates folder name (retrieved from config service)
|
* @return Returns the Space templates folder name
|
||||||
*/
|
*/
|
||||||
public static String getSpaceTemplatesFolderName(ServletContext context)
|
public static String getSpaceTemplatesFolderName(ServletContext context)
|
||||||
{
|
{
|
||||||
@@ -301,7 +302,7 @@ public class Application
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns the Space templates folder name (retrieved from config service)
|
* @return Returns the Space templates folder name
|
||||||
*/
|
*/
|
||||||
public static String getSpaceTemplatesFolderName(FacesContext context)
|
public static String getSpaceTemplatesFolderName(FacesContext context)
|
||||||
{
|
{
|
||||||
@@ -309,7 +310,7 @@ public class Application
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns the Content templates folder name (retrieved from config service)
|
* @return Returns the Content templates folder name
|
||||||
*/
|
*/
|
||||||
public static String getContentTemplatesFolderName(ServletContext context)
|
public static String getContentTemplatesFolderName(ServletContext context)
|
||||||
{
|
{
|
||||||
@@ -317,13 +318,29 @@ public class Application
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns the Content templates folder name (retrieved from config service)
|
* @return Returns the Content templates folder name
|
||||||
*/
|
*/
|
||||||
public static String getContentTemplatesFolderName(FacesContext context)
|
public static String getContentTemplatesFolderName(FacesContext context)
|
||||||
{
|
{
|
||||||
return getContentTemplatesFolderName(FacesContextUtils.getRequiredWebApplicationContext(context));
|
return getContentTemplatesFolderName(FacesContextUtils.getRequiredWebApplicationContext(context));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Return the Saved Searches folder name
|
||||||
|
*/
|
||||||
|
public static String getSavedSearchesFolderName(ServletContext context)
|
||||||
|
{
|
||||||
|
return getSavedSearchesFolderName(WebApplicationContextUtils.getRequiredWebApplicationContext(context));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Return the Saved Searches folder name
|
||||||
|
*/
|
||||||
|
public static String getSavedSearchesFolderName(FacesContext context)
|
||||||
|
{
|
||||||
|
return getSavedSearchesFolderName(FacesContextUtils.getRequiredWebApplicationContext(context));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the language locale for the current user context
|
* Set the language locale for the current user context
|
||||||
*
|
*
|
||||||
@@ -530,7 +547,7 @@ public class Application
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the repository store URL (retrieved from config service)
|
* Returns the repository store URL
|
||||||
*
|
*
|
||||||
* @param context The spring context
|
* @param context The spring context
|
||||||
* @return The repository store URL to use
|
* @return The repository store URL to use
|
||||||
@@ -547,7 +564,7 @@ public class Application
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the root path for the application (retrieved from config service)
|
* Returns the root path for the application
|
||||||
*
|
*
|
||||||
* @param context The spring context
|
* @param context The spring context
|
||||||
* @return The application root path
|
* @return The application root path
|
||||||
@@ -565,7 +582,7 @@ public class Application
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the glossary folder name (retrieved from config service)
|
* Returns the glossary folder name
|
||||||
*
|
*
|
||||||
* @param context The spring context
|
* @param context The spring context
|
||||||
* @return The glossary folder name
|
* @return The glossary folder name
|
||||||
@@ -583,7 +600,7 @@ public class Application
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the Space Templates folder name (retrieved from config service)
|
* Returns the Space Templates folder name
|
||||||
*
|
*
|
||||||
* @param context The spring context
|
* @param context The spring context
|
||||||
* @return The templates folder name
|
* @return The templates folder name
|
||||||
@@ -601,7 +618,7 @@ public class Application
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the Content Templates folder name (retrieved from config service)
|
* Returns the Content Templates folder name
|
||||||
*
|
*
|
||||||
* @param context The spring context
|
* @param context The spring context
|
||||||
* @return The templates folder name
|
* @return The templates folder name
|
||||||
@@ -618,6 +635,24 @@ public class Application
|
|||||||
return contentTemplatesFolderName;
|
return contentTemplatesFolderName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Saved Searches folder name
|
||||||
|
*
|
||||||
|
* @param context The spring context
|
||||||
|
* @return The saved searches folder name
|
||||||
|
*/
|
||||||
|
private static String getSavedSearchesFolderName(WebApplicationContext context)
|
||||||
|
{
|
||||||
|
if (savedSearchesFolderName == null)
|
||||||
|
{
|
||||||
|
ImporterBootstrap bootstrap = (ImporterBootstrap)context.getBean(BEAN_IMPORTER_BOOTSTRAP);
|
||||||
|
Properties configuration = bootstrap.getConfiguration();
|
||||||
|
savedSearchesFolderName = configuration.getProperty("spaces.savedsearches.childname");
|
||||||
|
}
|
||||||
|
|
||||||
|
return savedSearchesFolderName;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Retrieves the configured error page for the application
|
* Retrieves the configured error page for the application
|
||||||
*
|
*
|
||||||
|
@@ -16,6 +16,8 @@
|
|||||||
*/
|
*/
|
||||||
package org.alfresco.web.bean;
|
package org.alfresco.web.bean;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.text.MessageFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@@ -26,25 +28,36 @@ import java.util.Map;
|
|||||||
import javax.faces.component.UISelectBoolean;
|
import javax.faces.component.UISelectBoolean;
|
||||||
import javax.faces.context.FacesContext;
|
import javax.faces.context.FacesContext;
|
||||||
import javax.faces.event.ActionEvent;
|
import javax.faces.event.ActionEvent;
|
||||||
|
import javax.faces.event.ValueChangeEvent;
|
||||||
import javax.faces.model.DataModel;
|
import javax.faces.model.DataModel;
|
||||||
import javax.faces.model.ListDataModel;
|
import javax.faces.model.ListDataModel;
|
||||||
import javax.faces.model.SelectItem;
|
import javax.faces.model.SelectItem;
|
||||||
|
import javax.transaction.UserTransaction;
|
||||||
|
|
||||||
import org.alfresco.config.ConfigService;
|
import org.alfresco.config.ConfigService;
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
|
import org.alfresco.repo.content.MimetypeMap;
|
||||||
|
import org.alfresco.repo.security.permissions.AccessDeniedException;
|
||||||
import org.alfresco.service.ServiceRegistry;
|
import org.alfresco.service.ServiceRegistry;
|
||||||
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
import org.alfresco.service.cmr.dictionary.AspectDefinition;
|
||||||
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
|
||||||
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
import org.alfresco.service.cmr.dictionary.DictionaryService;
|
||||||
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
|
||||||
import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
import org.alfresco.service.cmr.dictionary.TypeDefinition;
|
||||||
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentReader;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentService;
|
||||||
|
import org.alfresco.service.cmr.repository.ContentWriter;
|
||||||
import org.alfresco.service.cmr.repository.MimetypeService;
|
import org.alfresco.service.cmr.repository.MimetypeService;
|
||||||
import org.alfresco.service.cmr.repository.NodeRef;
|
import org.alfresco.service.cmr.repository.NodeRef;
|
||||||
import org.alfresco.service.cmr.repository.NodeService;
|
import org.alfresco.service.cmr.repository.NodeService;
|
||||||
|
import org.alfresco.service.cmr.search.SearchService;
|
||||||
|
import org.alfresco.service.cmr.security.PermissionService;
|
||||||
import org.alfresco.service.namespace.NamespaceService;
|
import org.alfresco.service.namespace.NamespaceService;
|
||||||
import org.alfresco.service.namespace.QName;
|
import org.alfresco.service.namespace.QName;
|
||||||
import org.alfresco.util.CachingDateFormat;
|
import org.alfresco.util.CachingDateFormat;
|
||||||
import org.alfresco.web.app.Application;
|
import org.alfresco.web.app.Application;
|
||||||
|
import org.alfresco.web.bean.SearchContext.RangeProperties;
|
||||||
import org.alfresco.web.bean.repository.MapNode;
|
import org.alfresco.web.bean.repository.MapNode;
|
||||||
import org.alfresco.web.bean.repository.Node;
|
import org.alfresco.web.bean.repository.Node;
|
||||||
import org.alfresco.web.bean.repository.Repository;
|
import org.alfresco.web.bean.repository.Repository;
|
||||||
@@ -52,6 +65,7 @@ import org.alfresco.web.config.ClientConfigElement;
|
|||||||
import org.alfresco.web.config.ClientConfigElement.CustomProperty;
|
import org.alfresco.web.config.ClientConfigElement.CustomProperty;
|
||||||
import org.alfresco.web.data.IDataContainer;
|
import org.alfresco.web.data.IDataContainer;
|
||||||
import org.alfresco.web.data.QuickSort;
|
import org.alfresco.web.data.QuickSort;
|
||||||
|
import org.alfresco.web.ui.common.Utils;
|
||||||
import org.alfresco.web.ui.common.component.UIPanel.ExpandedEvent;
|
import org.alfresco.web.ui.common.component.UIPanel.ExpandedEvent;
|
||||||
import org.alfresco.web.ui.repo.component.UICategorySelector;
|
import org.alfresco.web.ui.repo.component.UICategorySelector;
|
||||||
import org.alfresco.web.ui.repo.component.UISearchCustomProperties;
|
import org.alfresco.web.ui.repo.component.UISearchCustomProperties;
|
||||||
@@ -73,9 +87,9 @@ public class AdvancedSearchBean
|
|||||||
public AdvancedSearchBean()
|
public AdvancedSearchBean()
|
||||||
{
|
{
|
||||||
// initial state of progressive panels that don't use the default
|
// initial state of progressive panels that don't use the default
|
||||||
panels.put("categories-panel", false);
|
panels.put(PANEL_CATEGORIES, false);
|
||||||
panels.put("attrs-panel", false);
|
panels.put(PANEL_ATTRS, false);
|
||||||
panels.put("custom-panel", false);
|
panels.put(PANEL_CUSTOM, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -106,6 +120,14 @@ public class AdvancedSearchBean
|
|||||||
this.namespaceService = namespaceService;
|
this.namespaceService = namespaceService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param searchService the search service
|
||||||
|
*/
|
||||||
|
public void setSearchService(SearchService searchService)
|
||||||
|
{
|
||||||
|
this.searchService = searchService;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns the progressive panels expanded state map.
|
* @return Returns the progressive panels expanded state map.
|
||||||
*/
|
*/
|
||||||
@@ -122,6 +144,70 @@ public class AdvancedSearchBean
|
|||||||
this.panels = panels;
|
this.panels = panels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the saved search Description.
|
||||||
|
*/
|
||||||
|
public String getSearchDescription()
|
||||||
|
{
|
||||||
|
return this.searchDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param searchDescription The saved search Description to set.
|
||||||
|
*/
|
||||||
|
public void setSearchDescription(String searchDescription)
|
||||||
|
{
|
||||||
|
this.searchDescription = searchDescription;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Returns the saved search Name.
|
||||||
|
*/
|
||||||
|
public String getSearchName()
|
||||||
|
{
|
||||||
|
return this.searchName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param searchName The saved search Name to set.
|
||||||
|
*/
|
||||||
|
public void setSearchName(String searchName)
|
||||||
|
{
|
||||||
|
this.searchName = searchName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ID of the last saved search selected by the user
|
||||||
|
*/
|
||||||
|
public String getSavedSearch()
|
||||||
|
{
|
||||||
|
return this.savedSearch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param savedSearch ID of the saved search selected by the user
|
||||||
|
*/
|
||||||
|
public void setSavedSearch(String savedSearch)
|
||||||
|
{
|
||||||
|
this.savedSearch = savedSearch;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return name of the saved search to edit
|
||||||
|
*/
|
||||||
|
public String getEditSearchName()
|
||||||
|
{
|
||||||
|
return this.editSearchName;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param editSearchName name of the saved search to edit
|
||||||
|
*/
|
||||||
|
public void setEditSearchName(String editSearchName)
|
||||||
|
{
|
||||||
|
this.editSearchName = editSearchName;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns the folder to search, null for all.
|
* @return Returns the folder to search, null for all.
|
||||||
*/
|
*/
|
||||||
@@ -496,19 +582,28 @@ public class AdvancedSearchBean
|
|||||||
* Handler to clear the advanced search screen form details
|
* Handler to clear the advanced search screen form details
|
||||||
*/
|
*/
|
||||||
public void reset(ActionEvent event)
|
public void reset(ActionEvent event)
|
||||||
|
{
|
||||||
|
resetFields();
|
||||||
|
this.savedSearch = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetFields()
|
||||||
{
|
{
|
||||||
this.text = "";
|
this.text = "";
|
||||||
this.mode = MODE_ALL;
|
this.mode = MODE_ALL;
|
||||||
this.lookin = LOOKIN_ALL;
|
this.lookin = LOOKIN_ALL;
|
||||||
this.contentType = null;
|
this.contentType = null;
|
||||||
|
this.contentFormat = null;
|
||||||
this.location = null;
|
this.location = null;
|
||||||
this.locationChildren = false;
|
this.locationChildren = true;
|
||||||
this.categories = new ArrayList<Node>(2);
|
this.categories = new ArrayList<Node>(2);
|
||||||
this.title = null;
|
this.title = null;
|
||||||
this.description = null;
|
this.description = null;
|
||||||
this.author = null;
|
this.author = null;
|
||||||
this.createdDateFrom = null;
|
this.createdDateFrom = null;
|
||||||
|
this.createdDateTo = null;
|
||||||
this.modifiedDateFrom = null;
|
this.modifiedDateFrom = null;
|
||||||
|
this.modifiedDateTo = null;
|
||||||
this.createdDateChecked = false;
|
this.createdDateChecked = false;
|
||||||
this.modifiedDateChecked = false;
|
this.modifiedDateChecked = false;
|
||||||
this.customProperties.clear();
|
this.customProperties.clear();
|
||||||
@@ -519,8 +614,6 @@ public class AdvancedSearchBean
|
|||||||
*/
|
*/
|
||||||
public String search()
|
public String search()
|
||||||
{
|
{
|
||||||
String outcome = null;
|
|
||||||
|
|
||||||
if (this.text != null && this.text.length() != 0)
|
if (this.text != null && this.text.length() != 0)
|
||||||
{
|
{
|
||||||
// construct the Search Context and set on the navigation bean
|
// construct the Search Context and set on the navigation bean
|
||||||
@@ -637,8 +730,7 @@ public class AdvancedSearchBean
|
|||||||
// location path search
|
// location path search
|
||||||
if (this.lookin.equals(LOOKIN_OTHER) && this.location != null)
|
if (this.lookin.equals(LOOKIN_OTHER) && this.location != null)
|
||||||
{
|
{
|
||||||
search.setLocation(SearchContext.getPathFromSpaceRef(
|
search.setLocation(SearchContext.getPathFromSpaceRef(this.location, this.locationChildren));
|
||||||
new NodeRef(Repository.getStoreRef(), this.location.getId()), this.locationChildren));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// category path search
|
// category path search
|
||||||
@@ -648,7 +740,7 @@ public class AdvancedSearchBean
|
|||||||
for (int i=0; i<paths.length; i++)
|
for (int i=0; i<paths.length; i++)
|
||||||
{
|
{
|
||||||
Node category = this.categories.get(i);
|
Node category = this.categories.get(i);
|
||||||
boolean includeChildren = (Boolean)category.getProperties().get("includeChildren");
|
boolean includeChildren = (Boolean)category.getProperties().get(INCLUDE_CHILDREN);
|
||||||
paths[i] = SearchContext.getPathFromSpaceRef(category.getNodeRef(), includeChildren);
|
paths[i] = SearchContext.getPathFromSpaceRef(category.getNodeRef(), includeChildren);
|
||||||
}
|
}
|
||||||
search.setCategories(paths);
|
search.setCategories(paths);
|
||||||
@@ -663,13 +755,425 @@ public class AdvancedSearchBean
|
|||||||
// set the Search Context onto the top-level navigator bean
|
// set the Search Context onto the top-level navigator bean
|
||||||
// this causes the browse screen to switch into search results view
|
// this causes the browse screen to switch into search results view
|
||||||
this.navigator.setSearchContext(search);
|
this.navigator.setSearchContext(search);
|
||||||
|
}
|
||||||
|
|
||||||
outcome = "browse";
|
return "browse";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action handler called to initiate the saved search screen
|
||||||
|
*/
|
||||||
|
public String saveSearch()
|
||||||
|
{
|
||||||
|
this.searchDescription = null;
|
||||||
|
this.searchName = null;
|
||||||
|
this.editSearchName = null;
|
||||||
|
|
||||||
|
if (this.savedSearch != null && NO_SELECTION.equals(this.savedSearch) == false)
|
||||||
|
{
|
||||||
|
// load previous for overwrite
|
||||||
|
try
|
||||||
|
{
|
||||||
|
NodeRef searchRef = new NodeRef(Repository.getStoreRef(), this.savedSearch);
|
||||||
|
Node searchNode = new Node(searchRef);
|
||||||
|
if (this.nodeService.exists(searchRef) && searchNode.hasPermission(PermissionService.WRITE))
|
||||||
|
{
|
||||||
|
Node node = new Node(searchRef);
|
||||||
|
this.searchName = node.getName();
|
||||||
|
this.editSearchName = this.searchName;
|
||||||
|
this.searchDescription = (String)node.getProperties().get(ContentModel.PROP_DESCRIPTION);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// unable to overwrite existing saved search
|
||||||
|
this.savedSearch = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Throwable err)
|
||||||
|
{
|
||||||
|
// unable to overwrite existing saved search for some other reason
|
||||||
|
this.savedSearch = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "saveSearch";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action handler called to save the current search
|
||||||
|
*/
|
||||||
|
public String saveSearchOK()
|
||||||
|
{
|
||||||
|
String outcome = "browse";
|
||||||
|
|
||||||
|
NodeRef searchesRef = getSavedSearchesRef();
|
||||||
|
SearchContext search = this.navigator.getSearchContext();
|
||||||
|
if (searchesRef != null && search != null)
|
||||||
|
{
|
||||||
|
UserTransaction tx = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
FacesContext context = FacesContext.getCurrentInstance();
|
||||||
|
tx = Repository.getUserTransaction(context);
|
||||||
|
tx.begin();
|
||||||
|
|
||||||
|
Map<QName, Serializable> props = null;
|
||||||
|
|
||||||
|
// handle Edit e.g. Overwrite of existing search
|
||||||
|
// detect if was previously selected saved search (e.g. NodeRef not null)
|
||||||
|
boolean edit = false;
|
||||||
|
if (this.savedSearch != null && NO_SELECTION.equals(this.savedSearch) == false)
|
||||||
|
{
|
||||||
|
NodeRef searchRef = new NodeRef(Repository.getStoreRef(), this.savedSearch);
|
||||||
|
edit = (this.nodeService.exists(searchRef));
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentService contentService = Repository.getServiceRegistry(context).getContentService();
|
||||||
|
ContentWriter writer;
|
||||||
|
if (edit)
|
||||||
|
{
|
||||||
|
// edit existing saved search
|
||||||
|
NodeRef searchRef = new NodeRef(Repository.getStoreRef(), this.savedSearch);
|
||||||
|
props = this.nodeService.getProperties(searchRef);
|
||||||
|
props.put(ContentModel.PROP_NAME, this.searchName);
|
||||||
|
props.put(ContentModel.PROP_DESCRIPTION, this.searchDescription);
|
||||||
|
this.nodeService.setProperties(searchRef, props);
|
||||||
|
|
||||||
|
writer = contentService.getWriter(searchRef, ContentModel.PROP_CONTENT, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// create new content node as the saved search object
|
||||||
|
props = new HashMap<QName, Serializable>(2, 1.0f);
|
||||||
|
props.put(ContentModel.PROP_NAME, this.searchName);
|
||||||
|
props.put(ContentModel.PROP_DESCRIPTION, this.searchDescription);
|
||||||
|
ChildAssociationRef childRef = this.nodeService.createNode(
|
||||||
|
searchesRef,
|
||||||
|
ContentModel.ASSOC_CONTAINS,
|
||||||
|
QName.createQName(NamespaceService.ALFRESCO_URI, QName.createValidLocalName(this.searchName)),
|
||||||
|
ContentModel.TYPE_CONTENT,
|
||||||
|
props);
|
||||||
|
|
||||||
|
writer = contentService.getWriter(childRef.getChildRef(), ContentModel.PROP_CONTENT, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// get a writer to our new node ready for XML content
|
||||||
|
writer.setMimetype(MimetypeMap.MIMETYPE_XML);
|
||||||
|
writer.setEncoding("UTF-8");
|
||||||
|
|
||||||
|
// output an XML serialized version of the SearchContext object
|
||||||
|
writer.putContent(search.toXML());
|
||||||
|
|
||||||
|
tx.commit();
|
||||||
|
|
||||||
|
this.savedSearch = null;
|
||||||
|
}
|
||||||
|
catch (Throwable e)
|
||||||
|
{
|
||||||
|
try { if (tx != null) {tx.rollback();} } catch (Exception ex) {}
|
||||||
|
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
|
||||||
|
FacesContext.getCurrentInstance(), MSG_ERROR_SAVE_SEARCH), e.getMessage()), e);
|
||||||
|
outcome = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return outcome;
|
return outcome;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return list of saved searches as SelectItem objects
|
||||||
|
*/
|
||||||
|
public List<SelectItem> getSavedSearches()
|
||||||
|
{
|
||||||
|
// TODO: cache for 1 minute? - dirty cache when new search is saved!
|
||||||
|
FacesContext fc = FacesContext.getCurrentInstance();
|
||||||
|
String xpath = ".//*";
|
||||||
|
|
||||||
|
ServiceRegistry services = Repository.getServiceRegistry(fc);
|
||||||
|
|
||||||
|
List<SelectItem> savedSearches = null;
|
||||||
|
NodeRef searchesRef = getSavedSearchesRef();
|
||||||
|
if (searchesRef != null)
|
||||||
|
{
|
||||||
|
List<NodeRef> results = searchService.selectNodes(
|
||||||
|
searchesRef,
|
||||||
|
xpath,
|
||||||
|
null,
|
||||||
|
namespaceService,
|
||||||
|
false);
|
||||||
|
savedSearches = new ArrayList<SelectItem>(results.size() + 1);
|
||||||
|
if (results.size() != 0)
|
||||||
|
{
|
||||||
|
DictionaryService dd = services.getDictionaryService();
|
||||||
|
for (NodeRef ref : results)
|
||||||
|
{
|
||||||
|
Node childNode = new Node(ref);
|
||||||
|
if (dd.isSubClass(childNode.getType(), ContentModel.TYPE_CONTENT))
|
||||||
|
{
|
||||||
|
savedSearches.add(new SelectItem(childNode.getId(), childNode.getName()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// make sure the list is sorted by the label
|
||||||
|
QuickSort sorter = new QuickSort(savedSearches, "label", true, IDataContainer.SORT_CASEINSENSITIVE);
|
||||||
|
sorter.sort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// handle missing folder case
|
||||||
|
savedSearches = new ArrayList<SelectItem>(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// add an entry (at the start) to instruct the user to select a saved search
|
||||||
|
savedSearches.add(0, new SelectItem(NO_SELECTION,
|
||||||
|
Application.getMessage(FacesContext.getCurrentInstance(), MSG_SELECT_SAVED_SEARCH)));
|
||||||
|
|
||||||
|
return savedSearches;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Action handler called when a saved search is selected by the user
|
||||||
|
*/
|
||||||
|
public void selectSearch(ActionEvent event)
|
||||||
|
{
|
||||||
|
if (NO_SELECTION.equals(savedSearch) == false)
|
||||||
|
{
|
||||||
|
// read an XML serialized version of the SearchContext object
|
||||||
|
NodeRef searchSearchRef = new NodeRef(Repository.getStoreRef(), savedSearch);
|
||||||
|
ServiceRegistry services = Repository.getServiceRegistry(FacesContext.getCurrentInstance());
|
||||||
|
ContentService cs = services.getContentService();
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (services.getNodeService().exists(searchSearchRef))
|
||||||
|
{
|
||||||
|
ContentReader reader = cs.getReader(searchSearchRef, ContentModel.PROP_CONTENT);
|
||||||
|
SearchContext search = new SearchContext().fromXML(reader.getContentString());
|
||||||
|
|
||||||
|
// if we get here we read the serialized object successfully
|
||||||
|
// now setup the UI to match the new SearchContext object
|
||||||
|
initialiseFromContext(search);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Throwable err)
|
||||||
|
{
|
||||||
|
Utils.addErrorMessage(MessageFormat.format(Application.getMessage(
|
||||||
|
FacesContext.getCurrentInstance(), MSG_ERROR_RESTORE_SEARCH), err.getMessage()), err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialise the Advanced Search UI screen from a SearchContext
|
||||||
|
*
|
||||||
|
* @param search the SearchContext to retrieve state from
|
||||||
|
*/
|
||||||
|
private void initialiseFromContext(SearchContext search)
|
||||||
|
{
|
||||||
|
resetFields();
|
||||||
|
|
||||||
|
this.text = search.getText();
|
||||||
|
|
||||||
|
switch (search.getMode())
|
||||||
|
{
|
||||||
|
case SearchContext.SEARCH_ALL:
|
||||||
|
this.mode = MODE_ALL;
|
||||||
|
break;
|
||||||
|
case SearchContext.SEARCH_FILE_NAMES_CONTENTS:
|
||||||
|
this.mode = MODE_FILES_TEXT;
|
||||||
|
break;
|
||||||
|
case SearchContext.SEARCH_FILE_NAMES:
|
||||||
|
this.mode = MODE_FILES;
|
||||||
|
break;
|
||||||
|
case SearchContext.SEARCH_SPACE_NAMES:
|
||||||
|
this.mode = MODE_FOLDERS;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this.panels.put(PANEL_RESTRICT, true);
|
||||||
|
|
||||||
|
if (search.getLocation() != null)
|
||||||
|
{
|
||||||
|
this.locationChildren = search.getLocation().endsWith("//*");
|
||||||
|
this.location = findNodeRefFromPath(search.getLocation());
|
||||||
|
this.lookin = LOOKIN_OTHER;
|
||||||
|
this.panels.put(PANEL_LOCATION, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
String[] categories = search.getCategories();
|
||||||
|
if (categories != null && categories.length != 0)
|
||||||
|
{
|
||||||
|
for (String category : categories)
|
||||||
|
{
|
||||||
|
NodeRef categoryRef = findNodeRefFromPath(category);
|
||||||
|
if (categoryRef != null)
|
||||||
|
{
|
||||||
|
Node categoryNode = new MapNode(categoryRef);
|
||||||
|
// add a value bound propery used to indicate if searching across children is selected
|
||||||
|
categoryNode.getProperties().put(INCLUDE_CHILDREN, category.endsWith("//*"));
|
||||||
|
this.categories.add(categoryNode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
this.panels.put(PANEL_CATEGORIES, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.contentType = search.getContentType();
|
||||||
|
this.contentFormat = search.getMimeType();
|
||||||
|
|
||||||
|
this.description = search.getAttributeQuery(ContentModel.PROP_DESCRIPTION);
|
||||||
|
this.title = search.getAttributeQuery(ContentModel.PROP_TITLE);
|
||||||
|
this.author = search.getAttributeQuery(ContentModel.PROP_AUTHOR);
|
||||||
|
if (this.contentType != null || this.contentFormat != null ||
|
||||||
|
this.description != null || this.title != null || this.author != null)
|
||||||
|
{
|
||||||
|
this.panels.put(PANEL_ATTRS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
RangeProperties createdDate = search.getRangeProperty(ContentModel.PROP_CREATED);
|
||||||
|
if (createdDate != null)
|
||||||
|
{
|
||||||
|
this.createdDateFrom = Utils.parseXMLDateFormat(createdDate.lower);
|
||||||
|
this.createdDateTo = Utils.parseXMLDateFormat(createdDate.upper);
|
||||||
|
this.createdDateChecked = true;
|
||||||
|
this.panels.put(PANEL_ATTRS, true);
|
||||||
|
}
|
||||||
|
RangeProperties modifiedDate = search.getRangeProperty(ContentModel.PROP_MODIFIED);
|
||||||
|
if (modifiedDate != null)
|
||||||
|
{
|
||||||
|
this.modifiedDateFrom = Utils.parseXMLDateFormat(modifiedDate.lower);
|
||||||
|
this.modifiedDateTo = Utils.parseXMLDateFormat(modifiedDate.upper);
|
||||||
|
this.modifiedDateChecked = true;
|
||||||
|
this.panels.put(PANEL_ATTRS, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// custom fields - calculate which are required to set through the custom properties lookup table
|
||||||
|
for (String qname : getCustomPropertyLookup().keySet())
|
||||||
|
{
|
||||||
|
DataTypeDefinition typeDef = getCustomPropertyLookup().get(qname);
|
||||||
|
if (typeDef != null)
|
||||||
|
{
|
||||||
|
QName typeName = typeDef.getName();
|
||||||
|
if (DataTypeDefinition.DATE.equals(typeName) || DataTypeDefinition.DATETIME.equals(typeName))
|
||||||
|
{
|
||||||
|
RangeProperties dateProps = search.getRangeProperty(QName.createQName(qname));
|
||||||
|
if (dateProps != null)
|
||||||
|
{
|
||||||
|
this.customProperties.put(UISearchCustomProperties.PREFIX_DATE_FROM + qname,
|
||||||
|
Utils.parseXMLDateFormat(dateProps.lower));
|
||||||
|
this.customProperties.put(UISearchCustomProperties.PREFIX_DATE_TO + qname,
|
||||||
|
Utils.parseXMLDateFormat(dateProps.upper));
|
||||||
|
this.customProperties.put(qname, true);
|
||||||
|
this.panels.put(PANEL_CUSTOM, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (DataTypeDefinition.BOOLEAN.equals(typeName))
|
||||||
|
{
|
||||||
|
String strBool = search.getFixedValueQuery(QName.createQName(qname));
|
||||||
|
if (strBool != null)
|
||||||
|
{
|
||||||
|
this.customProperties.put(qname, Boolean.parseBoolean(strBool));
|
||||||
|
this.panels.put(PANEL_CUSTOM, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (DataTypeDefinition.NODE_REF.equals(typeName) || DataTypeDefinition.CATEGORY.equals(typeName))
|
||||||
|
{
|
||||||
|
String strNodeRef = search.getFixedValueQuery(QName.createQName(qname));
|
||||||
|
if (strNodeRef != null)
|
||||||
|
{
|
||||||
|
this.customProperties.put(qname, new NodeRef(strNodeRef));
|
||||||
|
this.panels.put(PANEL_CUSTOM, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (DataTypeDefinition.INT.equals(typeName) || DataTypeDefinition.LONG.equals(typeName) ||
|
||||||
|
DataTypeDefinition.FLOAT.equals(typeName) || DataTypeDefinition.DOUBLE.equals(typeName))
|
||||||
|
{
|
||||||
|
// currently numbers are rendered as text in UISearchCustomProperties component
|
||||||
|
// this code will need updating if that changes!
|
||||||
|
this.customProperties.put(qname, search.getFixedValueQuery(QName.createQName(qname)));
|
||||||
|
this.panels.put(PANEL_CUSTOM, true);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.customProperties.put(qname, search.getAttributeQuery(QName.createQName(qname)));
|
||||||
|
this.panels.put(PANEL_CUSTOM, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return NodeRef to the last Node referenced on the end of the specified xpath value
|
||||||
|
*
|
||||||
|
* @param xpath XPath - note that any /* or //* will be removed to find trailing node
|
||||||
|
*
|
||||||
|
* @return NodeRef if found null otherwise
|
||||||
|
*/
|
||||||
|
private NodeRef findNodeRefFromPath(String xpath)
|
||||||
|
{
|
||||||
|
if (xpath.endsWith("//*"))
|
||||||
|
{
|
||||||
|
xpath = xpath.substring(0, xpath.lastIndexOf("//*"));
|
||||||
|
}
|
||||||
|
else if (xpath.endsWith("/*"))
|
||||||
|
{
|
||||||
|
xpath = xpath.substring(0, xpath.lastIndexOf("/*"));
|
||||||
|
}
|
||||||
|
NodeRef rootRef = new NodeRef(Repository.getStoreRef(), Application.getCompanyRootId());
|
||||||
|
List<NodeRef> results = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
results = searchService.selectNodes(
|
||||||
|
rootRef,
|
||||||
|
xpath,
|
||||||
|
null,
|
||||||
|
namespaceService,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
catch (AccessDeniedException err)
|
||||||
|
{
|
||||||
|
// ignore and return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return (results != null && results.size() == 1) ? results.get(0) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the cached reference to the shared Saved Searches folder
|
||||||
|
*/
|
||||||
|
private NodeRef getSavedSearchesRef()
|
||||||
|
{
|
||||||
|
if (savedSearchesRef == null)
|
||||||
|
{
|
||||||
|
FacesContext fc = FacesContext.getCurrentInstance();
|
||||||
|
String xpath = Application.getRootPath(fc) + "/" +
|
||||||
|
Application.getGlossaryFolderName(fc) + "/" +
|
||||||
|
Application.getSavedSearchesFolderName(fc);
|
||||||
|
|
||||||
|
NodeRef rootNodeRef = this.nodeService.getRootNode(Repository.getStoreRef());
|
||||||
|
List<NodeRef> results = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
results = searchService.selectNodes(
|
||||||
|
rootNodeRef,
|
||||||
|
xpath,
|
||||||
|
null,
|
||||||
|
namespaceService,
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
catch (AccessDeniedException err)
|
||||||
|
{
|
||||||
|
// ignore and return null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results != null && results.size() == 1)
|
||||||
|
{
|
||||||
|
savedSearchesRef = results.get(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return savedSearchesRef;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Action handler called when the Add button is pressed to add the current Category selection
|
* Action handler called when the Add button is pressed to add the current Category selection
|
||||||
*/
|
*/
|
||||||
@@ -683,7 +1187,7 @@ public class AdvancedSearchBean
|
|||||||
{
|
{
|
||||||
Node categoryNode = new MapNode(categoryRef);
|
Node categoryNode = new MapNode(categoryRef);
|
||||||
// add a value bound propery used to indicate if searching across children is selected
|
// add a value bound propery used to indicate if searching across children is selected
|
||||||
categoryNode.getProperties().put("includeChildren", chkChildren.isSelected());
|
categoryNode.getProperties().put(INCLUDE_CHILDREN, chkChildren.isSelected());
|
||||||
this.categories.add(categoryNode);
|
this.categories.add(categoryNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -768,6 +1272,17 @@ public class AdvancedSearchBean
|
|||||||
|
|
||||||
private static final String MSG_CONTENT = "content";
|
private static final String MSG_CONTENT = "content";
|
||||||
private static final String MSG_ALL_FORMATS = "all_formats";
|
private static final String MSG_ALL_FORMATS = "all_formats";
|
||||||
|
private static final String MSG_ERROR_SAVE_SEARCH = "error_save_search";
|
||||||
|
private static final String MSG_ERROR_RESTORE_SEARCH = "error_restore_search";
|
||||||
|
private static final String MSG_SELECT_SAVED_SEARCH = "select_saved_search";
|
||||||
|
|
||||||
|
private static final String PANEL_CUSTOM = "custom-panel";
|
||||||
|
private static final String PANEL_ATTRS = "attrs-panel";
|
||||||
|
private static final String PANEL_CATEGORIES = "categories-panel";
|
||||||
|
private static final String PANEL_RESTRICT = "restrict-panel";
|
||||||
|
private static final String PANEL_LOCATION = "location-panel";
|
||||||
|
|
||||||
|
private static final String INCLUDE_CHILDREN = "includeChildren";
|
||||||
|
|
||||||
private static final String MODE_ALL = "all";
|
private static final String MODE_ALL = "all";
|
||||||
private static final String MODE_FILES_TEXT = "files_text";
|
private static final String MODE_FILES_TEXT = "files_text";
|
||||||
@@ -777,6 +1292,8 @@ public class AdvancedSearchBean
|
|||||||
private static final String LOOKIN_ALL = "all";
|
private static final String LOOKIN_ALL = "all";
|
||||||
private static final String LOOKIN_OTHER = "other";
|
private static final String LOOKIN_OTHER = "other";
|
||||||
|
|
||||||
|
private static final String NO_SELECTION = "none";
|
||||||
|
|
||||||
/** The NodeService to be used by the bean */
|
/** The NodeService to be used by the bean */
|
||||||
private NodeService nodeService;
|
private NodeService nodeService;
|
||||||
|
|
||||||
@@ -786,12 +1303,19 @@ public class AdvancedSearchBean
|
|||||||
/** The NavigationBean reference */
|
/** The NavigationBean reference */
|
||||||
private NavigationBean navigator;
|
private NavigationBean navigator;
|
||||||
|
|
||||||
|
/** SearchService bean reference */
|
||||||
|
private SearchService searchService;
|
||||||
|
|
||||||
/** Client Config reference */
|
/** Client Config reference */
|
||||||
private ClientConfigElement clientConfigElement = null;
|
private ClientConfigElement clientConfigElement = null;
|
||||||
|
|
||||||
/** Progressive panel UI state */
|
/** Progressive panel UI state */
|
||||||
private Map<String, Boolean> panels = new HashMap(5, 1.0f);
|
private Map<String, Boolean> panels = new HashMap(5, 1.0f);
|
||||||
|
|
||||||
|
/** Saved search properties */
|
||||||
|
private String searchName;
|
||||||
|
private String searchDescription;
|
||||||
|
|
||||||
/** custom property names to values */
|
/** custom property names to values */
|
||||||
private Map<String, Object> customProperties = new HashMap(5, 1.0f);
|
private Map<String, Object> customProperties = new HashMap(5, 1.0f);
|
||||||
|
|
||||||
@@ -854,4 +1378,10 @@ public class AdvancedSearchBean
|
|||||||
|
|
||||||
private boolean modifiedDateChecked = false;
|
private boolean modifiedDateChecked = false;
|
||||||
private boolean createdDateChecked = false;
|
private boolean createdDateChecked = false;
|
||||||
|
|
||||||
|
private NodeRef savedSearchesRef = null;
|
||||||
|
|
||||||
|
private String savedSearch = null;
|
||||||
|
|
||||||
|
private String editSearchName = null;
|
||||||
}
|
}
|
||||||
|
@@ -83,9 +83,6 @@ public class BrowseBean implements IContextListener
|
|||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
// Construction
|
// Construction
|
||||||
|
|
||||||
private static final String VIEWMODE_DASHBOARD = "dashboard";
|
|
||||||
private static final String PAGE_NAME_BROWSE = "browse";
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default Constructor
|
* Default Constructor
|
||||||
*/
|
*/
|
||||||
@@ -1443,6 +1440,9 @@ public class BrowseBean implements IContextListener
|
|||||||
|
|
||||||
public static final String BROWSE_VIEW_ID = "/jsp/browse/browse.jsp";
|
public static final String BROWSE_VIEW_ID = "/jsp/browse/browse.jsp";
|
||||||
|
|
||||||
|
private static final String VIEWMODE_DASHBOARD = "dashboard";
|
||||||
|
private static final String PAGE_NAME_BROWSE = "browse";
|
||||||
|
|
||||||
/** I18N messages */
|
/** I18N messages */
|
||||||
private static final String MSG_ERROR_DELETE_FILE = "error_delete_file";
|
private static final String MSG_ERROR_DELETE_FILE = "error_delete_file";
|
||||||
private static final String MSG_ERROR_DELETE_SPACE = "error_delete_space";
|
private static final String MSG_ERROR_DELETE_SPACE = "error_delete_space";
|
||||||
|
@@ -198,6 +198,16 @@ public class DocumentDetailsBean
|
|||||||
return Utils.generateURL(FacesContext.getCurrentInstance(), getDocument(), URLMode.CIFS);
|
return Utils.generateURL(FacesContext.getCurrentInstance(), getDocument(), URLMode.CIFS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the Alfresco NodeRef URL for the current document
|
||||||
|
*
|
||||||
|
* @return the Alfresco NodeRef URL
|
||||||
|
*/
|
||||||
|
public String getNodeRefUrl()
|
||||||
|
{
|
||||||
|
return getDocument().getNodeRef().toString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether the current document is versionable
|
* Determines whether the current document is versionable
|
||||||
*
|
*
|
||||||
|
@@ -17,13 +17,19 @@
|
|||||||
package org.alfresco.web.bean;
|
package org.alfresco.web.bean;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
import java.io.StringReader;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.StringTokenizer;
|
import java.util.StringTokenizer;
|
||||||
|
|
||||||
import javax.faces.context.FacesContext;
|
import javax.faces.context.FacesContext;
|
||||||
|
|
||||||
|
import org.alfresco.error.AlfrescoRuntimeException;
|
||||||
import org.alfresco.model.ContentModel;
|
import org.alfresco.model.ContentModel;
|
||||||
import org.alfresco.repo.search.impl.lucene.QueryParser;
|
import org.alfresco.repo.search.impl.lucene.QueryParser;
|
||||||
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
import org.alfresco.service.cmr.repository.ChildAssociationRef;
|
||||||
@@ -35,6 +41,12 @@ import org.alfresco.util.ISO9075;
|
|||||||
import org.alfresco.web.bean.repository.Repository;
|
import org.alfresco.web.bean.repository.Repository;
|
||||||
import org.apache.commons.logging.Log;
|
import org.apache.commons.logging.Log;
|
||||||
import org.apache.commons.logging.LogFactory;
|
import org.apache.commons.logging.LogFactory;
|
||||||
|
import org.dom4j.Document;
|
||||||
|
import org.dom4j.DocumentHelper;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
import org.dom4j.io.OutputFormat;
|
||||||
|
import org.dom4j.io.SAXReader;
|
||||||
|
import org.dom4j.io.XMLWriter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds the context required to build a search query and can return the populated query.
|
* Holds the context required to build a search query and can return the populated query.
|
||||||
@@ -43,6 +55,28 @@ import org.apache.commons.logging.LogFactory;
|
|||||||
*/
|
*/
|
||||||
public final class SearchContext implements Serializable
|
public final class SearchContext implements Serializable
|
||||||
{
|
{
|
||||||
|
private static final long serialVersionUID = 6730844584074229969L;
|
||||||
|
|
||||||
|
/** XML serialization elements */
|
||||||
|
private static final String ELEMENT_VALUE = "value";
|
||||||
|
private static final String ELEMENT_FIXED_VALUES = "fixed-values";
|
||||||
|
private static final String ELEMENT_INCLUSIVE = "inclusive";
|
||||||
|
private static final String ELEMENT_UPPER = "upper";
|
||||||
|
private static final String ELEMENT_LOWER = "lower";
|
||||||
|
private static final String ELEMENT_RANGE = "range";
|
||||||
|
private static final String ELEMENT_RANGES = "ranges";
|
||||||
|
private static final String ELEMENT_NAME = "name";
|
||||||
|
private static final String ELEMENT_ATTRIBUTE = "attribute";
|
||||||
|
private static final String ELEMENT_ATTRIBUTES = "attributes";
|
||||||
|
private static final String ELEMENT_MIMETYPE = "mimetype";
|
||||||
|
private static final String ELEMENT_CONTENT_TYPE = "content-type";
|
||||||
|
private static final String ELEMENT_CATEGORY = "category";
|
||||||
|
private static final String ELEMENT_CATEGORIES = "categories";
|
||||||
|
private static final String ELEMENT_LOCATION = "location";
|
||||||
|
private static final String ELEMENT_MODE = "mode";
|
||||||
|
private static final String ELEMENT_TEXT = "text";
|
||||||
|
private static final String ELEMENT_SEARCH = "search";
|
||||||
|
|
||||||
/** Search mode constants */
|
/** Search mode constants */
|
||||||
public final static int SEARCH_ALL = 0;
|
public final static int SEARCH_ALL = 0;
|
||||||
public final static int SEARCH_FILE_NAMES_CONTENTS = 1;
|
public final static int SEARCH_FILE_NAMES_CONTENTS = 1;
|
||||||
@@ -55,18 +89,12 @@ public final class SearchContext implements Serializable
|
|||||||
/** mode for the search */
|
/** mode for the search */
|
||||||
private int mode = SearchContext.SEARCH_ALL;
|
private int mode = SearchContext.SEARCH_ALL;
|
||||||
|
|
||||||
/** folder node location for the search */
|
/** folder XPath location for the search */
|
||||||
private String location = null;
|
private String location = null;
|
||||||
|
|
||||||
/** categories to add to the search */
|
/** categories to add to the search */
|
||||||
private String[] categories = new String[0];
|
private String[] categories = new String[0];
|
||||||
|
|
||||||
/** true to search location children as well as location */
|
|
||||||
private boolean locationChildren = true;
|
|
||||||
|
|
||||||
/** true to search category children as well as category */
|
|
||||||
private boolean categoryChildren = true;
|
|
||||||
|
|
||||||
/** content type to restrict search against */
|
/** content type to restrict search against */
|
||||||
private String contentType = null;
|
private String contentType = null;
|
||||||
|
|
||||||
@@ -96,7 +124,7 @@ public final class SearchContext implements Serializable
|
|||||||
String query;
|
String query;
|
||||||
|
|
||||||
// the QName for the well known "name" attribute
|
// the QName for the well known "name" attribute
|
||||||
String nameAttr = Repository.escapeQName(QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "name"));
|
String nameAttr = Repository.escapeQName(QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, ELEMENT_NAME));
|
||||||
|
|
||||||
// match against content text
|
// match against content text
|
||||||
String text = this.text.trim();
|
String text = this.text.trim();
|
||||||
@@ -375,7 +403,7 @@ public final class SearchContext implements Serializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns the node to search from or null for all.
|
* @return Returns the node XPath to search in or null for all.
|
||||||
*/
|
*/
|
||||||
public String getLocation()
|
public String getLocation()
|
||||||
{
|
{
|
||||||
@@ -383,7 +411,7 @@ public final class SearchContext implements Serializable
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param location The node to search from or null for all..
|
* @param location The node XPATH to search from or null for all..
|
||||||
*/
|
*/
|
||||||
public void setLocation(String location)
|
public void setLocation(String location)
|
||||||
{
|
{
|
||||||
@@ -453,38 +481,6 @@ public final class SearchContext implements Serializable
|
|||||||
this.mimeType = mimeType;
|
this.mimeType = mimeType;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Returns true to search location children, false for just the specified location.
|
|
||||||
*/
|
|
||||||
public boolean getLocationChildren()
|
|
||||||
{
|
|
||||||
return this.locationChildren;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param locationChildren True to search location children, false for just the specified location.
|
|
||||||
*/
|
|
||||||
public void setLocationChildren(boolean locationChildren)
|
|
||||||
{
|
|
||||||
this.locationChildren = locationChildren;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return Returns true to search category children, false for just the specified category.
|
|
||||||
*/
|
|
||||||
public boolean getCategoryChildren()
|
|
||||||
{
|
|
||||||
return this.categoryChildren;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param categoryChildren True to search category children, false for just the specified category.
|
|
||||||
*/
|
|
||||||
public void setCategoryChildren(boolean categoryChildren)
|
|
||||||
{
|
|
||||||
this.categoryChildren = categoryChildren;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an additional attribute to search against
|
* Add an additional attribute to search against
|
||||||
*
|
*
|
||||||
@@ -496,6 +492,11 @@ public final class SearchContext implements Serializable
|
|||||||
this.queryAttributes.put(qname, value);
|
this.queryAttributes.put(qname, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getAttributeQuery(QName qname)
|
||||||
|
{
|
||||||
|
return this.queryAttributes.get(qname);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an additional range attribute to search against
|
* Add an additional range attribute to search against
|
||||||
*
|
*
|
||||||
@@ -509,6 +510,11 @@ public final class SearchContext implements Serializable
|
|||||||
this.rangeAttributes.put(qname, new RangeProperties(qname, lower, upper, inclusive));
|
this.rangeAttributes.put(qname, new RangeProperties(qname, lower, upper, inclusive));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public RangeProperties getRangeProperty(QName qname)
|
||||||
|
{
|
||||||
|
return this.rangeAttributes.get(qname);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add an additional fixed value attribute to search against
|
* Add an additional fixed value attribute to search against
|
||||||
*
|
*
|
||||||
@@ -520,11 +526,216 @@ public final class SearchContext implements Serializable
|
|||||||
this.queryFixedValues.put(qname, value);
|
this.queryFixedValues.put(qname, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getFixedValueQuery(QName qname)
|
||||||
|
{
|
||||||
|
return this.queryFixedValues.get(qname);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return this SearchContext as XML
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* <code>
|
||||||
|
* <?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
* <search>
|
||||||
|
* <text>CDATA</text>
|
||||||
|
* <mode>int</mode>
|
||||||
|
* <location>XPath</location>
|
||||||
|
* <categories>
|
||||||
|
* <category>XPath</category>
|
||||||
|
* </categories>
|
||||||
|
* <content-type>String</content-type>
|
||||||
|
* <mimetype>String</mimetype>
|
||||||
|
* <attributes>
|
||||||
|
* <attribute name="String">String</attribute>
|
||||||
|
* </attributes>
|
||||||
|
* <ranges>
|
||||||
|
* <range name="String">
|
||||||
|
* <lower>String</lower>
|
||||||
|
* <upper>String</upper>
|
||||||
|
* <inclusive>boolean</inclusive>
|
||||||
|
* </range>
|
||||||
|
* </ranges>
|
||||||
|
* <fixed-values>
|
||||||
|
* <value name="String">String</value>
|
||||||
|
* </fixed-values>
|
||||||
|
* </search>
|
||||||
|
* </code>
|
||||||
|
*/
|
||||||
|
public String toXML()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
NamespaceService ns = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNamespaceService();
|
||||||
|
|
||||||
|
Document doc = DocumentHelper.createDocument();
|
||||||
|
|
||||||
|
Element root = doc.addElement(ELEMENT_SEARCH);
|
||||||
|
|
||||||
|
root.addElement(ELEMENT_TEXT).addCDATA(this.text);
|
||||||
|
root.addElement(ELEMENT_MODE).addText(Integer.toString(this.mode));
|
||||||
|
if (this.location != null)
|
||||||
|
{
|
||||||
|
root.addElement(ELEMENT_LOCATION).addText(this.location);
|
||||||
|
}
|
||||||
|
|
||||||
|
Element categories = root.addElement(ELEMENT_CATEGORIES);
|
||||||
|
for (String path : this.categories)
|
||||||
|
{
|
||||||
|
categories.addElement(ELEMENT_CATEGORY).addText(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.contentType != null)
|
||||||
|
{
|
||||||
|
root.addElement(ELEMENT_CONTENT_TYPE).addText(this.contentType);
|
||||||
|
}
|
||||||
|
if (this.mimeType != null)
|
||||||
|
{
|
||||||
|
root.addElement(ELEMENT_MIMETYPE).addText(this.mimeType);
|
||||||
|
}
|
||||||
|
|
||||||
|
Element attributes = root.addElement(ELEMENT_ATTRIBUTES);
|
||||||
|
for (QName attrName : this.queryAttributes.keySet())
|
||||||
|
{
|
||||||
|
attributes.addElement(ELEMENT_ATTRIBUTE)
|
||||||
|
.addAttribute(ELEMENT_NAME, attrName.toPrefixString(ns))
|
||||||
|
.addCDATA(this.queryAttributes.get(attrName));
|
||||||
|
}
|
||||||
|
|
||||||
|
Element ranges = root.addElement(ELEMENT_RANGES);
|
||||||
|
for (QName rangeName : this.rangeAttributes.keySet())
|
||||||
|
{
|
||||||
|
RangeProperties rangeProps = this.rangeAttributes.get(rangeName);
|
||||||
|
Element range = ranges.addElement(ELEMENT_RANGE);
|
||||||
|
range.addAttribute(ELEMENT_NAME, rangeName.toPrefixString(ns));
|
||||||
|
range.addElement(ELEMENT_LOWER).addText(rangeProps.lower);
|
||||||
|
range.addElement(ELEMENT_UPPER).addText(rangeProps.upper);
|
||||||
|
range.addElement(ELEMENT_INCLUSIVE).addText(Boolean.toString(rangeProps.inclusive));
|
||||||
|
}
|
||||||
|
|
||||||
|
Element values = root.addElement(ELEMENT_FIXED_VALUES);
|
||||||
|
for (QName valueName : this.queryFixedValues.keySet())
|
||||||
|
{
|
||||||
|
values.addElement(ELEMENT_VALUE)
|
||||||
|
.addAttribute(ELEMENT_NAME, valueName.toPrefixString(ns))
|
||||||
|
.addCDATA(this.queryFixedValues.get(valueName));
|
||||||
|
}
|
||||||
|
|
||||||
|
StringWriter out = new StringWriter(1024);
|
||||||
|
XMLWriter writer = new XMLWriter(OutputFormat.createPrettyPrint());
|
||||||
|
writer.setWriter(out);
|
||||||
|
writer.write(doc);
|
||||||
|
|
||||||
|
return out.toString();
|
||||||
|
}
|
||||||
|
catch (Throwable err)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Failed to export SearchContext to XML.", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restore a SearchContext from an XML definition
|
||||||
|
*
|
||||||
|
* @param xml XML format SearchContext @see #toXML()
|
||||||
|
*/
|
||||||
|
public SearchContext fromXML(String xml)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
NamespaceService ns = Repository.getServiceRegistry(FacesContext.getCurrentInstance()).getNamespaceService();
|
||||||
|
|
||||||
|
// get the root element
|
||||||
|
SAXReader reader = new SAXReader();
|
||||||
|
Document document = reader.read(new StringReader(xml));
|
||||||
|
Element rootElement = document.getRootElement();
|
||||||
|
Element textElement = rootElement.element(ELEMENT_TEXT);
|
||||||
|
if (textElement != null)
|
||||||
|
{
|
||||||
|
this.text = textElement.getText();
|
||||||
|
}
|
||||||
|
Element modeElement = rootElement.element(ELEMENT_MODE);
|
||||||
|
if (modeElement != null)
|
||||||
|
{
|
||||||
|
this.mode = Integer.parseInt(modeElement.getText());
|
||||||
|
}
|
||||||
|
Element locationElement = rootElement.element(ELEMENT_LOCATION);
|
||||||
|
if (locationElement != null)
|
||||||
|
{
|
||||||
|
this.location = locationElement.getText();
|
||||||
|
}
|
||||||
|
Element categoriesElement = rootElement.element(ELEMENT_CATEGORIES);
|
||||||
|
if (categoriesElement != null)
|
||||||
|
{
|
||||||
|
List<String> categories = new ArrayList<String>(4);
|
||||||
|
for (Iterator i=categoriesElement.elementIterator(ELEMENT_CATEGORY); i.hasNext(); /**/)
|
||||||
|
{
|
||||||
|
Element categoryElement = (Element)i.next();
|
||||||
|
categories.add(categoryElement.getText());
|
||||||
|
}
|
||||||
|
this.categories = categories.toArray(this.categories);
|
||||||
|
}
|
||||||
|
Element contentTypeElement = rootElement.element(ELEMENT_CONTENT_TYPE);
|
||||||
|
if (contentTypeElement != null)
|
||||||
|
{
|
||||||
|
this.contentType = contentTypeElement.getText();
|
||||||
|
}
|
||||||
|
Element mimetypeElement = rootElement.element(ELEMENT_MIMETYPE);
|
||||||
|
if (mimetypeElement != null)
|
||||||
|
{
|
||||||
|
this.mimeType = mimetypeElement.getText();
|
||||||
|
}
|
||||||
|
Element attributesElement = rootElement.element(ELEMENT_ATTRIBUTES);
|
||||||
|
if (attributesElement != null)
|
||||||
|
{
|
||||||
|
for (Iterator i=attributesElement.elementIterator(ELEMENT_ATTRIBUTE); i.hasNext(); /**/)
|
||||||
|
{
|
||||||
|
Element attrElement = (Element)i.next();
|
||||||
|
QName qname = QName.createQName(attrElement.attributeValue(ELEMENT_NAME), ns);
|
||||||
|
addAttributeQuery(qname, attrElement.getText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Element rangesElement = rootElement.element(ELEMENT_RANGES);
|
||||||
|
if (rangesElement != null)
|
||||||
|
{
|
||||||
|
for (Iterator i=rangesElement.elementIterator(ELEMENT_RANGE); i.hasNext(); /**/)
|
||||||
|
{
|
||||||
|
Element rangeElement = (Element)i.next();
|
||||||
|
Element lowerElement = rangeElement.element(ELEMENT_LOWER);
|
||||||
|
Element upperElement = rangeElement.element(ELEMENT_UPPER);
|
||||||
|
Element incElement = rangeElement.element(ELEMENT_INCLUSIVE);
|
||||||
|
if (lowerElement != null && upperElement != null && incElement != null)
|
||||||
|
{
|
||||||
|
QName qname = QName.createQName(rangeElement.attributeValue(ELEMENT_NAME), ns);
|
||||||
|
addRangeQuery(qname,
|
||||||
|
lowerElement.getText(), upperElement.getText(),
|
||||||
|
Boolean.parseBoolean(incElement.getText()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Element valuesElement = rootElement.element(ELEMENT_FIXED_VALUES);
|
||||||
|
if (valuesElement != null)
|
||||||
|
{
|
||||||
|
for (Iterator i=valuesElement.elementIterator(ELEMENT_VALUE); i.hasNext(); /**/)
|
||||||
|
{
|
||||||
|
Element valueElement = (Element)i.next();
|
||||||
|
QName qname = QName.createQName(valueElement.attributeValue(ELEMENT_NAME), ns);
|
||||||
|
addFixedValueQuery(qname, valueElement.getText());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Throwable err)
|
||||||
|
{
|
||||||
|
throw new AlfrescoRuntimeException("Failed to import SearchContext from XML.", err);
|
||||||
|
}
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple wrapper class for range query attribute properties
|
* Simple wrapper class for range query attribute properties
|
||||||
*/
|
*/
|
||||||
private static class RangeProperties
|
static class RangeProperties
|
||||||
{
|
{
|
||||||
QName qname;
|
QName qname;
|
||||||
String lower;
|
String lower;
|
||||||
|
@@ -117,7 +117,7 @@ public class SpaceDetailsBean
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the id of the current document
|
* Returns the id of the current space
|
||||||
*
|
*
|
||||||
* @return The id
|
* @return The id
|
||||||
*/
|
*/
|
||||||
@@ -127,9 +127,9 @@ public class SpaceDetailsBean
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the name of the current document
|
* Returns the name of the current space
|
||||||
*
|
*
|
||||||
* @return Name of the current document
|
* @return Name of the current space
|
||||||
*/
|
*/
|
||||||
public String getName()
|
public String getName()
|
||||||
{
|
{
|
||||||
@@ -137,7 +137,7 @@ public class SpaceDetailsBean
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the WebDAV URL for the current document
|
* Returns the WebDAV URL for the current space
|
||||||
*
|
*
|
||||||
* @return The WebDAV url
|
* @return The WebDAV url
|
||||||
*/
|
*/
|
||||||
@@ -147,7 +147,7 @@ public class SpaceDetailsBean
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the URL to access the details page for the current document
|
* Returns the URL to access the details page for the current space
|
||||||
*
|
*
|
||||||
* @return The bookmark URL
|
* @return The bookmark URL
|
||||||
*/
|
*/
|
||||||
@@ -157,7 +157,7 @@ public class SpaceDetailsBean
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the CIFS path for the current document
|
* Returns the CIFS path for the current space
|
||||||
*
|
*
|
||||||
* @return The CIFS path
|
* @return The CIFS path
|
||||||
*/
|
*/
|
||||||
@@ -166,6 +166,16 @@ public class SpaceDetailsBean
|
|||||||
return Utils.generateURL(FacesContext.getCurrentInstance(), getSpace(), URLMode.CIFS);
|
return Utils.generateURL(FacesContext.getCurrentInstance(), getSpace(), URLMode.CIFS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the Alfresco NodeRef URL for the current space
|
||||||
|
*
|
||||||
|
* @return the Alfresco NodeRef URL
|
||||||
|
*/
|
||||||
|
public String getNodeRefUrl()
|
||||||
|
{
|
||||||
|
return getSpace().getNodeRef().toString();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Returns the template Id.
|
* @return Returns the template Id.
|
||||||
*/
|
*/
|
||||||
|
@@ -133,7 +133,6 @@ public abstract class BasePreviewBean
|
|||||||
public SelectItem[] getTemplates()
|
public SelectItem[] getTemplates()
|
||||||
{
|
{
|
||||||
// TODO: could cache this last for say 1 minute before requerying
|
// TODO: could cache this last for say 1 minute before requerying
|
||||||
|
|
||||||
// get the template from the special Content Templates folder
|
// get the template from the special Content Templates folder
|
||||||
FacesContext context = FacesContext.getCurrentInstance();
|
FacesContext context = FacesContext.getCurrentInstance();
|
||||||
String xpath = Application.getRootPath(context) + "/" +
|
String xpath = Application.getRootPath(context) + "/" +
|
||||||
@@ -143,7 +142,7 @@ public abstract class BasePreviewBean
|
|||||||
NamespaceService resolver = Repository.getServiceRegistry(context).getNamespaceService();
|
NamespaceService resolver = Repository.getServiceRegistry(context).getNamespaceService();
|
||||||
List<NodeRef> results = this.searchService.selectNodes(rootNodeRef, xpath, null, resolver, false);
|
List<NodeRef> results = this.searchService.selectNodes(rootNodeRef, xpath, null, resolver, false);
|
||||||
|
|
||||||
List<SelectItem> templates = new ArrayList<SelectItem>(results.size());
|
List<SelectItem> templates = new ArrayList<SelectItem>(results.size() + 1);
|
||||||
if (results.size() != 0)
|
if (results.size() != 0)
|
||||||
{
|
{
|
||||||
DictionaryService dd = Repository.getServiceRegistry(context).getDictionaryService();
|
DictionaryService dd = Repository.getServiceRegistry(context).getDictionaryService();
|
||||||
|
@@ -22,6 +22,7 @@ import java.io.StringReader;
|
|||||||
import java.net.URLEncoder;
|
import java.net.URLEncoder;
|
||||||
import java.text.DateFormat;
|
import java.text.DateFormat;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
|
import java.util.Calendar;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@@ -988,6 +989,79 @@ public final class Utils
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parse XML format date YYYY-MM-DDTHH:MM:SS
|
||||||
|
* @param isoDate
|
||||||
|
* @return Date or null if failed to parse
|
||||||
|
*/
|
||||||
|
public static Date parseXMLDateFormat(String isoDate)
|
||||||
|
{
|
||||||
|
Date parsed = null;
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
int offset = 0;
|
||||||
|
|
||||||
|
// extract year
|
||||||
|
int year = Integer.parseInt(isoDate.substring(offset, offset += 4));
|
||||||
|
if (isoDate.charAt(offset) != '-')
|
||||||
|
{
|
||||||
|
throw new IndexOutOfBoundsException("Expected - character but found " + isoDate.charAt(offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract month
|
||||||
|
int month = Integer.parseInt(isoDate.substring(offset += 1, offset += 2));
|
||||||
|
if (isoDate.charAt(offset) != '-')
|
||||||
|
{
|
||||||
|
throw new IndexOutOfBoundsException("Expected - character but found " + isoDate.charAt(offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract day
|
||||||
|
int day = Integer.parseInt(isoDate.substring(offset += 1, offset += 2));
|
||||||
|
if (isoDate.charAt(offset) != 'T')
|
||||||
|
{
|
||||||
|
throw new IndexOutOfBoundsException("Expected T character but found " + isoDate.charAt(offset));
|
||||||
|
}
|
||||||
|
|
||||||
|
// extract hours, minutes, seconds and milliseconds
|
||||||
|
int hour = Integer.parseInt(isoDate.substring(offset += 1, offset += 2));
|
||||||
|
if (isoDate.charAt(offset) != ':')
|
||||||
|
{
|
||||||
|
throw new IndexOutOfBoundsException("Expected : character but found " + isoDate.charAt(offset));
|
||||||
|
}
|
||||||
|
int minutes = Integer.parseInt(isoDate.substring(offset += 1, offset += 2));
|
||||||
|
if (isoDate.charAt(offset) != ':')
|
||||||
|
{
|
||||||
|
throw new IndexOutOfBoundsException("Expected : character but found " + isoDate.charAt(offset));
|
||||||
|
}
|
||||||
|
int seconds = Integer.parseInt(isoDate.substring(offset += 1 , offset += 2));
|
||||||
|
|
||||||
|
// initialize Calendar object
|
||||||
|
Calendar calendar = Calendar.getInstance();
|
||||||
|
calendar.setLenient(false);
|
||||||
|
calendar.set(Calendar.YEAR, year);
|
||||||
|
calendar.set(Calendar.MONTH, month - 1);
|
||||||
|
calendar.set(Calendar.DAY_OF_MONTH, day);
|
||||||
|
calendar.set(Calendar.HOUR_OF_DAY, hour);
|
||||||
|
calendar.set(Calendar.MINUTE, minutes);
|
||||||
|
calendar.set(Calendar.SECOND, seconds);
|
||||||
|
|
||||||
|
// extract the date
|
||||||
|
parsed = calendar.getTime();
|
||||||
|
}
|
||||||
|
catch(IndexOutOfBoundsException e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch(NumberFormatException e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
catch(IllegalArgumentException e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
return parsed;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the image path to the filetype icon for the specified file name string
|
* Return the image path to the filetype icon for the specified file name string
|
||||||
*
|
*
|
||||||
|
@@ -303,6 +303,7 @@ public class UIActionLink extends UICommand
|
|||||||
this.onclick = onclick;
|
this.onclick = onclick;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------
|
||||||
// Private data
|
// Private data
|
||||||
|
|
||||||
|
@@ -158,10 +158,10 @@ public class ActionLinkRenderer extends BaseRenderer
|
|||||||
linkBuf.append(" class=")
|
linkBuf.append(" class=")
|
||||||
.append(attrs.get("styleClass"));
|
.append(attrs.get("styleClass"));
|
||||||
}
|
}
|
||||||
if (attrs.get("tooltip") != null)
|
if (link.getTooltip() != null)
|
||||||
{
|
{
|
||||||
linkBuf.append(" title=\"")
|
linkBuf.append(" title=\"")
|
||||||
.append(Utils.encode((String)attrs.get("tooltip")))
|
.append(Utils.encode(link.getTooltip()))
|
||||||
.append('"');
|
.append('"');
|
||||||
}
|
}
|
||||||
linkBuf.append('>');
|
linkBuf.append('>');
|
||||||
@@ -266,10 +266,8 @@ public class ActionLinkRenderer extends BaseRenderer
|
|||||||
}
|
}
|
||||||
buf.append(">");
|
buf.append(">");
|
||||||
|
|
||||||
Map attrs = link.getAttributes();
|
|
||||||
|
|
||||||
// render text link cell for the menu
|
// render text link cell for the menu
|
||||||
if (attrs.get("href") == null)
|
if (link.getHref() == null)
|
||||||
{
|
{
|
||||||
buf.append("<a href='#' onclick=\"");
|
buf.append("<a href='#' onclick=\"");
|
||||||
buf.append(Utils.generateFormSubmit(context, link, Utils.getActionHiddenFieldName(context, link), link.getClientId(context), getParameterMap(link)));
|
buf.append(Utils.generateFormSubmit(context, link, Utils.getActionHiddenFieldName(context, link), link.getClientId(context), getParameterMap(link)));
|
||||||
@@ -277,7 +275,7 @@ public class ActionLinkRenderer extends BaseRenderer
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
String href = (String)attrs.get("href");
|
String href = link.getHref();
|
||||||
if (href.startsWith("http") == false)
|
if (href.startsWith("http") == false)
|
||||||
{
|
{
|
||||||
href = context.getExternalContext().getRequestContextPath() + href;
|
href = context.getExternalContext().getRequestContextPath() + href;
|
||||||
@@ -295,6 +293,7 @@ public class ActionLinkRenderer extends BaseRenderer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map attrs = link.getAttributes();
|
||||||
if (attrs.get("style") != null)
|
if (attrs.get("style") != null)
|
||||||
{
|
{
|
||||||
buf.append(" style=\"")
|
buf.append(" style=\"")
|
||||||
|
@@ -108,7 +108,7 @@ public class BreadcrumbRenderer extends BaseRenderer
|
|||||||
if (first == false)
|
if (first == false)
|
||||||
{
|
{
|
||||||
buf.append(' ')
|
buf.append(' ')
|
||||||
.append(bc.getSeparator())
|
.append(Utils.encode(bc.getSeparator()))
|
||||||
.append(' ');
|
.append(' ');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -170,6 +170,10 @@
|
|||||||
<from-outcome>showTopic</from-outcome>
|
<from-outcome>showTopic</from-outcome>
|
||||||
<to-view-id>/jsp/forums/topic.jsp</to-view-id>
|
<to-view-id>/jsp/forums/topic.jsp</to-view-id>
|
||||||
</navigation-case>
|
</navigation-case>
|
||||||
|
<navigation-case>
|
||||||
|
<from-outcome>saveSearch</from-outcome>
|
||||||
|
<to-view-id>/jsp/dialog/save-search.jsp</to-view-id>
|
||||||
|
</navigation-case>
|
||||||
</navigation-rule>
|
</navigation-rule>
|
||||||
|
|
||||||
<!-- Admin Console rules -->
|
<!-- Admin Console rules -->
|
||||||
|
@@ -191,6 +191,10 @@
|
|||||||
<property-name>namespaceService</property-name>
|
<property-name>namespaceService</property-name>
|
||||||
<value>#{NamespaceService}</value>
|
<value>#{NamespaceService}</value>
|
||||||
</managed-property>
|
</managed-property>
|
||||||
|
<managed-property>
|
||||||
|
<property-name>searchService</property-name>
|
||||||
|
<value>#{SearchService}</value>
|
||||||
|
</managed-property>
|
||||||
</managed-bean>
|
</managed-bean>
|
||||||
|
|
||||||
<managed-bean>
|
<managed-bean>
|
||||||
|
BIN
source/web/images/icons/save_search.gif
Normal file
BIN
source/web/images/icons/save_search.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 KiB |
BIN
source/web/images/icons/save_search_large.gif
Normal file
BIN
source/web/images/icons/save_search_large.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 KiB |
@@ -163,6 +163,7 @@
|
|||||||
<%-- Current object actions --%>
|
<%-- Current object actions --%>
|
||||||
<h:outputText style="padding-left:20px" styleClass="mainSubTitle" value="#{msg.actions}" id="msg14" /><br>
|
<h:outputText style="padding-left:20px" styleClass="mainSubTitle" value="#{msg.actions}" id="msg14" /><br>
|
||||||
<a:actionLink value="#{msg.new_search}" image="/images/icons/search_icon.gif" padding="4" action="advSearch" id="link20" />
|
<a:actionLink value="#{msg.new_search}" image="/images/icons/search_icon.gif" padding="4" action="advSearch" id="link20" />
|
||||||
|
<a:actionLink value="#{msg.save_search}" image="/images/icons/save_search.gif" padding="4" action="#{AdvancedSearchBean.saveSearch}" id="link20_1" />
|
||||||
<a:actionLink value="#{msg.close_search}" image="/images/icons/action.gif" padding="4" actionListener="#{BrowseBean.closeSearch}" id="link21" />
|
<a:actionLink value="#{msg.close_search}" image="/images/icons/action.gif" padding="4" actionListener="#{BrowseBean.closeSearch}" id="link21" />
|
||||||
</td>
|
</td>
|
||||||
</a:panel>
|
</a:panel>
|
||||||
@@ -209,7 +210,7 @@
|
|||||||
<%-- component to display if the list is empty --%>
|
<%-- component to display if the list is empty --%>
|
||||||
<f:facet name="empty">
|
<f:facet name="empty">
|
||||||
<%-- TODO: either build complete message in BrowseBean or have no icon... --%>
|
<%-- TODO: either build complete message in BrowseBean or have no icon... --%>
|
||||||
<h:outputFormat value="#{msg.no_space_items}" escape="false">
|
<h:outputFormat value="#{msg.no_space_items}" escape="false" rendered="#{NavigationBean.searchContext == null}">
|
||||||
<f:param value="#{msg.new_space}" />
|
<f:param value="#{msg.new_space}" />
|
||||||
</h:outputFormat>
|
</h:outputFormat>
|
||||||
</f:facet>
|
</f:facet>
|
||||||
@@ -362,7 +363,7 @@
|
|||||||
<%-- component to display if the list is empty --%>
|
<%-- component to display if the list is empty --%>
|
||||||
<f:facet name="empty">
|
<f:facet name="empty">
|
||||||
<%-- TODO: either build complete message in BrowseBean or have no icon... --%>
|
<%-- TODO: either build complete message in BrowseBean or have no icon... --%>
|
||||||
<h:outputFormat value="#{msg.no_content_items}" escape="false">
|
<h:outputFormat value="#{msg.no_content_items}" escape="false" rendered="#{NavigationBean.searchContext == null}">
|
||||||
<f:param value="#{msg.add_content}" />
|
<f:param value="#{msg.add_content}" />
|
||||||
<f:param value="#{msg.create_content}" />
|
<f:param value="#{msg.create_content}" />
|
||||||
</h:outputFormat>
|
</h:outputFormat>
|
||||||
|
@@ -104,6 +104,21 @@
|
|||||||
<h:outputText style="padding-left:20px" styleClass="mainSubTitle" value="#{msg.actions}" /><br>
|
<h:outputText style="padding-left:20px" styleClass="mainSubTitle" value="#{msg.actions}" /><br>
|
||||||
<a:actionLink value="#{msg.resetall}" image="/images/icons/delete.gif" padding="4" actionListener="#{AdvancedSearchBean.reset}" />
|
<a:actionLink value="#{msg.resetall}" image="/images/icons/delete.gif" padding="4" actionListener="#{AdvancedSearchBean.reset}" />
|
||||||
</td>
|
</td>
|
||||||
|
<td bgcolor="#465F7D" width=1></td>
|
||||||
|
<td width=100 style="padding-left:2px">
|
||||||
|
<%-- Available Saved Searches --%>
|
||||||
|
<h:outputText style="padding-left:20px" styleClass="mainSubTitle" value="#{msg.saved_searches}" />
|
||||||
|
<div style="padding-top:4px;white-space:nowrap">
|
||||||
|
<%-- Saved Searches drop-down selector --%>
|
||||||
|
<%-- uses a nasty hack to execute an ActionListener for the drop-down
|
||||||
|
tried using a valueChangedListener+formsubmit but the valueChangedListener
|
||||||
|
is called too late in the lifecycle for the form controls to be managed --%>
|
||||||
|
<h:selectOneMenu id="searches" value="#{AdvancedSearchBean.savedSearch}" onchange="document.forms['advsearch']['advsearch:act'].value='advsearch:show-search'; document.forms['advsearch'].submit(); return true;">
|
||||||
|
<f:selectItems value="#{AdvancedSearchBean.savedSearches}" />
|
||||||
|
</h:selectOneMenu>
|
||||||
|
<div style="display:none"><a:actionLink id="show-search" value="Select" actionListener="#{AdvancedSearchBean.selectSearch}" /></div>
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
|
@@ -225,7 +225,10 @@
|
|||||||
<a:actionLink value="#{msg.download_content}" href="#{DocumentDetailsBean.downloadUrl}" target="new" id="link4" />
|
<a:actionLink value="#{msg.download_content}" href="#{DocumentDetailsBean.downloadUrl}" target="new" id="link4" />
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a:actionLink value="#{msg.details_page_bookmark}" href="#{DocumentDetailsBean.bookmarkUrl}" target="new" id="link5" />
|
<a href='<h:outputText value="#{DocumentDetailsBean.bookmarkUrl}" escape="false" />' onclick="return false;"><h:outputText value="#{msg.details_page_bookmark}" /></a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href='<h:outputText value="#{DocumentDetailsBean.nodeRefUrl}" escape="false" />' onclick="return false;"><h:outputText value="#{msg.noderef_link}" /></a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
203
source/web/jsp/dialog/save-search.jsp
Normal file
203
source/web/jsp/dialog/save-search.jsp
Normal file
@@ -0,0 +1,203 @@
|
|||||||
|
<%--
|
||||||
|
Copyright (C) 2005 Alfresco, Inc.
|
||||||
|
|
||||||
|
Licensed under the Mozilla Public License version 1.1
|
||||||
|
with a permitted attribution clause. You may obtain a
|
||||||
|
copy of the License at
|
||||||
|
|
||||||
|
http://www.alfresco.org/legal/license.txt
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
|
||||||
|
either express or implied. See the License for the specific
|
||||||
|
language governing permissions and limitations under the
|
||||||
|
License.
|
||||||
|
--%>
|
||||||
|
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
|
||||||
|
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
|
||||||
|
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
|
||||||
|
<%@ taglib uri="/WEB-INF/alfresco.tld" prefix="a" %>
|
||||||
|
<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>
|
||||||
|
|
||||||
|
<%@ page buffer="32kb" contentType="text/html;charset=UTF-8" %>
|
||||||
|
<%@ page isELIgnored="false" %>
|
||||||
|
<%@ page import="org.alfresco.web.ui.common.PanelGenerator" %>
|
||||||
|
|
||||||
|
<r:page titleId="title_save_search">
|
||||||
|
|
||||||
|
<script language="JavaScript1.2">
|
||||||
|
|
||||||
|
window.onload = pageLoaded;
|
||||||
|
|
||||||
|
function pageLoaded()
|
||||||
|
{
|
||||||
|
document.getElementById("save-search:name").focus();
|
||||||
|
checkButtonState();
|
||||||
|
}
|
||||||
|
|
||||||
|
function checkButtonState()
|
||||||
|
{
|
||||||
|
if (document.getElementById("save-search:name").value.length == 0 )
|
||||||
|
{
|
||||||
|
document.getElementById("save-search:ok-button").disabled = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
document.getElementById("save-search:ok-button").disabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<f:view>
|
||||||
|
|
||||||
|
<%-- load a bundle of properties with I18N strings --%>
|
||||||
|
<f:loadBundle basename="alfresco.messages.webclient" var="msg"/>
|
||||||
|
|
||||||
|
<h:form acceptCharset="UTF-8" id="save-search">
|
||||||
|
|
||||||
|
<%-- Main outer table --%>
|
||||||
|
<table cellspacing="0" cellpadding="2">
|
||||||
|
|
||||||
|
<%-- Title bar --%>
|
||||||
|
<tr>
|
||||||
|
<td colspan="2">
|
||||||
|
<%@ include file="../parts/titlebar.jsp" %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<%-- Main area --%>
|
||||||
|
<tr valign="top">
|
||||||
|
<%-- Shelf --%>
|
||||||
|
<td>
|
||||||
|
<%@ include file="../parts/shelf.jsp" %>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<%-- Work Area --%>
|
||||||
|
<td width="100%">
|
||||||
|
<table cellspacing="0" cellpadding="0" width="100%">
|
||||||
|
<%-- Breadcrumb --%>
|
||||||
|
<%@ include file="../parts/breadcrumb.jsp" %>
|
||||||
|
|
||||||
|
<%-- Status and Actions --%>
|
||||||
|
<tr>
|
||||||
|
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/statuspanel_4.gif)" width="4"></td>
|
||||||
|
<td bgcolor="#EEEEEE">
|
||||||
|
|
||||||
|
<%-- Status and Actions inner contents table --%>
|
||||||
|
<%-- Generally this consists of an icon, textual summary and actions for the current object --%>
|
||||||
|
<table cellspacing="4" cellpadding="0" width="100%">
|
||||||
|
<tr valign="top">
|
||||||
|
<td width="32">
|
||||||
|
<h:graphicImage id="wizard-logo" url="/images/icons/save_search_large.gif" />
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<div class="mainTitle"><h:outputText value="#{msg.save_search}" /></div>
|
||||||
|
<div class="mainSubText"><h:outputText value="#{msg.save_search_description}" /></div>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/statuspanel_6.gif)" width="4"></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<%-- separator row with gradient shadow --%>
|
||||||
|
<tr>
|
||||||
|
<td><img src="<%=request.getContextPath()%>/images/parts/statuspanel_7.gif" width="4" height="9"></td>
|
||||||
|
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/statuspanel_8.gif)"></td>
|
||||||
|
<td><img src="<%=request.getContextPath()%>/images/parts/statuspanel_9.gif" width="4" height="9"></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<%-- Details --%>
|
||||||
|
<tr valign=top>
|
||||||
|
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_4.gif)" width="4"></td>
|
||||||
|
<td>
|
||||||
|
<table cellspacing="0" cellpadding="3" border="0" width="100%">
|
||||||
|
<tr>
|
||||||
|
<td width="100%" valign="top">
|
||||||
|
|
||||||
|
<a:errors message="#{msg.error_wizard}" styleClass="errorMessage" />
|
||||||
|
|
||||||
|
<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "white", "white"); %>
|
||||||
|
<table cellpadding="2" cellspacing="2" border="0" width="100%">
|
||||||
|
<a:panel id="edit-panel" rendered="#{AdvancedSearchBean.editSearchName != null}">
|
||||||
|
<tr>
|
||||||
|
<td width="100%" valign="top" colspan="2" style="padding-bottom:6px">
|
||||||
|
<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "yellowInner", "#ffffcc"); %>
|
||||||
|
<table cellpadding="0" cellspacing="0" border="0" width="100%">
|
||||||
|
<tr>
|
||||||
|
<td valign=top style="padding-top:2px" width=20><h:graphicImage url="/images/icons/info_icon.gif" width="16" height="16"/></td>
|
||||||
|
<td class="mainSubText">
|
||||||
|
<h:outputFormat value="#{msg.saved_search_warning}">
|
||||||
|
<f:param value="#{AdvancedSearchBean.editSearchName}" />
|
||||||
|
</h:outputFormat>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "yellowInner"); %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</a:panel>
|
||||||
|
|
||||||
|
<tr>
|
||||||
|
<td colspan="2" class="wizardSectionHeading"><h:outputText value="#{msg.search_props}" /></td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><h:outputText value="#{msg.name}" />:</td>
|
||||||
|
<td>
|
||||||
|
<h:inputText id="name" value="#{AdvancedSearchBean.searchName}" size="35" maxlength="1024"
|
||||||
|
onkeyup="javascript:checkButtonState();" onchange="javascript:checkButtonState();"/> *
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td><h:outputText value="#{msg.description}" />:</td>
|
||||||
|
<td>
|
||||||
|
<h:inputText value="#{AdvancedSearchBean.searchDescription}" size="35" maxlength="1024" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "white"); %>
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td valign="top">
|
||||||
|
<% PanelGenerator.generatePanelStart(out, request.getContextPath(), "blue", "#D3E6FE"); %>
|
||||||
|
<table cellpadding="1" cellspacing="1" border="0">
|
||||||
|
<tr>
|
||||||
|
<td align="center">
|
||||||
|
<h:commandButton id="ok-button" value="#{msg.save}" action="#{AdvancedSearchBean.saveSearchOK}"
|
||||||
|
styleClass="wizardButton" disabled="true" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td align="center">
|
||||||
|
<h:commandButton value="#{msg.cancel}" action="browse" styleClass="wizardButton" />
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
<% PanelGenerator.generatePanelEnd(out, request.getContextPath(), "blue"); %>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
<td style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_6.gif)" width="4"></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<%-- separator row with bottom panel graphics --%>
|
||||||
|
<tr>
|
||||||
|
<td><img src="<%=request.getContextPath()%>/images/parts/whitepanel_7.gif" width="4" height="4"></td>
|
||||||
|
<td width="100%" align="center" style="background-image: url(<%=request.getContextPath()%>/images/parts/whitepanel_8.gif)"></td>
|
||||||
|
<td><img src="<%=request.getContextPath()%>/images/parts/whitepanel_9.gif" width="4" height="4"></td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</h:form>
|
||||||
|
|
||||||
|
</f:view>
|
||||||
|
|
||||||
|
</r:page>
|
@@ -225,7 +225,10 @@
|
|||||||
<a:actionLink value="#{msg.view_in_cifs}" href="#{SpaceDetailsBean.cifsPath}" target="new" id="link2" />
|
<a:actionLink value="#{msg.view_in_cifs}" href="#{SpaceDetailsBean.cifsPath}" target="new" id="link2" />
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
<a:actionLink value="#{msg.details_page_bookmark}" href="#{SpaceDetailsBean.bookmarkUrl}" target="new" id="link3" />
|
<a href='<h:outputText value="#{SpaceDetailsBean.bookmarkUrl}" escape="false" />' onclick="return false;"><h:outputText value="#{msg.details_page_bookmark}" /></a>
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<a href='<h:outputText value="#{SpaceDetailsBean.nodeRefUrl}" escape="false" />' onclick="return false;"><h:outputText value="#{msg.noderef_link}" /></a>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
Reference in New Issue
Block a user