diff --git a/config/alfresco/extension/web-client-config-custom.xml.sample b/config/alfresco/extension/web-client-config-custom.xml.sample
index 78dae712a2..c212eddfdb 100644
--- a/config/alfresco/extension/web-client-config-custom.xml.sample
+++ b/config/alfresco/extension/web-client-config-custom.xml.sample
@@ -5,6 +5,7 @@
someone@your-domain.com
+ 100
-->
diff --git a/config/alfresco/messages/webclient.properties b/config/alfresco/messages/webclient.properties
index 26160b9809..a542ea4083 100644
--- a/config/alfresco/messages/webclient.properties
+++ b/config/alfresco/messages/webclient.properties
@@ -764,8 +764,8 @@ home_space_name=Home Space Name
title_admin_console=Administration Console
admin_console=Administration Console
admin_description=Use this view to perform system administration functions.
-admin_limited_license=Licensed: {0} license issued on {1,date,short} limited to {2} days expiring {3,date,short} ({4} days remaining).
-admin_unlimited_license=Licensed: {0} license issued on {1,date,short} (does not expire).
+admin_limited_license=Licensed: {0} license granted to {1} and limited to {3} days expiring {4,date,short} ({5} days remaining - issued on {2,date,short}).
+admin_unlimited_license=Licensed: {0} license granted to {1} and does not expire (issued on {2,date,short}).
admin_invalid_license=Licensed: LICENSE INVALID - Alfresco Repository restricted to read-only capability.
# UI Page Titles
diff --git a/config/alfresco/web-client-config.xml b/config/alfresco/web-client-config.xml
index 9ecdb0b79a..f9fef1e0c0 100644
--- a/config/alfresco/web-client-config.xml
+++ b/config/alfresco/web-client-config.xml
@@ -39,6 +39,13 @@
3
+
+ false
+
+
+ -1
+
+
@@ -138,6 +145,7 @@
+
diff --git a/source/java/org/alfresco/web/bean/AdvancedSearchBean.java b/source/java/org/alfresco/web/bean/AdvancedSearchBean.java
index 4d7d5aabbd..106b9a7b20 100644
--- a/source/java/org/alfresco/web/bean/AdvancedSearchBean.java
+++ b/source/java/org/alfresco/web/bean/AdvancedSearchBean.java
@@ -686,8 +686,12 @@ public class AdvancedSearchBean
// then simply navigating to the browse screen will cause it pickup the Search Context
SearchContext search = new SearchContext();
+ // set the full-text/name field value
search.setText(this.text);
+ // set whether to force AND operation on text terms
+ search.setForceAndTerms(Application.getClientConfig(FacesContext.getCurrentInstance()).getForceAndTerms());
+
if (this.mode.equals(MODE_ALL))
{
search.setMode(SearchContext.SEARCH_ALL);
diff --git a/source/java/org/alfresco/web/bean/BrowseBean.java b/source/java/org/alfresco/web/bean/BrowseBean.java
index b116b09018..3547317fcc 100644
--- a/source/java/org/alfresco/web/bean/BrowseBean.java
+++ b/source/java/org/alfresco/web/bean/BrowseBean.java
@@ -43,8 +43,10 @@ import org.alfresco.service.cmr.repository.InvalidNodeRefException;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.Path;
+import org.alfresco.service.cmr.search.LimitBy;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow;
+import org.alfresco.service.cmr.search.SearchParameters;
import org.alfresco.service.cmr.search.SearchService;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.namespace.QName;
@@ -679,9 +681,20 @@ public class BrowseBean implements IContextListener
tx = Repository.getUserTransaction(FacesContext.getCurrentInstance(), true);
tx.begin();
- results = this.searchService.query(
- Repository.getStoreRef(),
- SearchService.LANGUAGE_LUCENE, query, null, null);
+ // Limit search to the first 100 matches
+ SearchParameters sp = new SearchParameters();
+ sp.setLanguage(SearchService.LANGUAGE_LUCENE);
+ sp.setQuery(query);
+ sp.addStore(Repository.getStoreRef());
+
+ int searchLimit = Application.getClientConfig(FacesContext.getCurrentInstance()).getSearchMaxResults();
+ if(searchLimit > 0)
+ {
+ sp.setLimitBy(LimitBy.FINAL_SIZE);
+ sp.setLimit(searchLimit);
+ }
+
+ results = this.searchService.query(sp);
if (logger.isDebugEnabled())
logger.debug("Search results returned: " + results.length());
diff --git a/source/java/org/alfresco/web/bean/SearchContext.java b/source/java/org/alfresco/web/bean/SearchContext.java
index 90802c92aa..5aea16661e 100644
--- a/source/java/org/alfresco/web/bean/SearchContext.java
+++ b/source/java/org/alfresco/web/bean/SearchContext.java
@@ -119,6 +119,9 @@ public final class SearchContext implements Serializable
/** any additional fixed value attributes to add to the search, such as boolean or noderef */
private Map queryFixedValues = new HashMap(5, 1.0f);
+ /** set true to force the use of AND between text terms */
+ private boolean forceAndTerms = false;
+
/** logger */
private static Log logger = LogFactory.getLog(SearchContext.class);
@@ -217,6 +220,9 @@ public final class SearchContext implements Serializable
term = term.substring(1);
}
+ // special case for AND all terms if set (apply after operator character removed)
+ operatorAND = operatorAND | this.forceAndTerms;
+
if (term.length() != 0)
{
// operators such as AND and OR are only make sense for full text searching
@@ -654,6 +660,22 @@ public final class SearchContext implements Serializable
return this.queryFixedValues.get(qname);
}
+ /**
+ * @return Returns if AND is forced between text terms. False (OR terms) is the default.
+ */
+ public boolean getForceAndTerms()
+ {
+ return this.forceAndTerms;
+ }
+
+ /**
+ * @param forceAndTerms Set true to force AND between text terms. Otherwise OR is the default.
+ */
+ public void setForceAndTerms(boolean forceAndTerms)
+ {
+ this.forceAndTerms = forceAndTerms;
+ }
+
/**
* @return this SearchContext as XML
*
diff --git a/source/java/org/alfresco/web/config/ClientConfigElement.java b/source/java/org/alfresco/web/config/ClientConfigElement.java
index ef2ecfd302..602159cb92 100644
--- a/source/java/org/alfresco/web/config/ClientConfigElement.java
+++ b/source/java/org/alfresco/web/config/ClientConfigElement.java
@@ -34,6 +34,8 @@ public class ClientConfigElement extends ConfigElementAdapter
private int recentSpacesItems = 6;
private boolean shelfVisible = true;
private int searchMinimum = 3;
+ private boolean forceAndTerms = false;
+ private int searchMaxResults = -1;
private String helpUrl = null;
private String editLinkType = "http";
private String homeSpacePermission = null;
@@ -121,6 +123,16 @@ public class ClientConfigElement extends ConfigElementAdapter
newElement.setSearchMinimum(existingElement.getSearchMinimum());
}
+ if (existingElement.getForceAndTerms() != newElement.getForceAndTerms())
+ {
+ newElement.setForceAndTerms(existingElement.getForceAndTerms());
+ }
+
+ if (existingElement.getSearchMaxResults() != newElement.getSearchMaxResults())
+ {
+ newElement.setSearchMaxResults(existingElement.getSearchMaxResults());
+ }
+
if (existingElement.isShelfVisible() != newElement.isShelfVisible())
{
newElement.setShelfVisible(existingElement.isShelfVisible());
@@ -263,6 +275,44 @@ public class ClientConfigElement extends ConfigElementAdapter
{
this.searchMinimum = searchMinimum;
}
+
+ /**
+ * @return If true enables AND text terms for simple/advanced search by default.
+ */
+ public boolean getForceAndTerms()
+ {
+ return this.forceAndTerms;
+ }
+
+ /**
+ * @param forceAndTerms True to enable AND text terms for simple/advanced search by default.
+ */
+ /*package*/ void setForceAndTerms(boolean forceAndTerms)
+ {
+ this.forceAndTerms = forceAndTerms;
+ }
+
+ /**
+ * If positive, this will limit the size of the result set from the search.
+ *
+ * @return
+ */
+
+ public int getSearchMaxResults()
+ {
+ return searchMaxResults;
+ }
+
+ /**
+ * Set if the the result set from a search will be of limited size.
+ * If negative it is unlimited, by convention, this is set to -1.
+ *
+ * @param searchMaxResults
+ */
+ /*package*/ void setSearchMaxResults(int searchMaxResults)
+ {
+ this.searchMaxResults = searchMaxResults;
+ }
/**
* @return Returns the default Home Space permissions.
diff --git a/source/java/org/alfresco/web/config/ClientElementReader.java b/source/java/org/alfresco/web/config/ClientElementReader.java
index 228af242e4..73cf1ecc5c 100644
--- a/source/java/org/alfresco/web/config/ClientElementReader.java
+++ b/source/java/org/alfresco/web/config/ClientElementReader.java
@@ -34,6 +34,8 @@ public class ClientElementReader implements ConfigElementReader
public static final String ELEMENT_HELPURL = "help-url";
public static final String ELEMENT_EDITLINKTYPE = "edit-link-type";
public static final String ELEMENT_SEARCHMINIMUM = "search-minimum";
+ public static final String ELEMENT_SEARCHANDTERMS = "search-and-terms";
+ public static final String ELEMENT_SEARCHMAXRESULTS = "search-max-results";
public static final String ELEMENT_HOMESPACEPERMISSION = "home-space-permission";
public static final String ELEMENT_FROMEMAILADDRESS = "from-email-address";
public static final String ELEMENT_SHELFVISIBLE = "shelf-visible";
@@ -93,6 +95,20 @@ public class ClientElementReader implements ConfigElementReader
configElement.setSearchMinimum(Integer.parseInt(searchMin.getTextTrim()));
}
+ // get the search force AND terms setting
+ Element searchForceAnd = element.element(ELEMENT_SEARCHANDTERMS);
+ if (searchForceAnd != null)
+ {
+ configElement.setForceAndTerms(Boolean.parseBoolean(searchForceAnd.getTextTrim()));
+ }
+
+ // get the search max results size
+ Element searchMaxResults = element.element(ELEMENT_SEARCHMAXRESULTS);
+ if (searchMaxResults != null)
+ {
+ configElement.setSearchMaxResults(Integer.parseInt(searchMaxResults.getTextTrim()));
+ }
+
// get the default permission for newly created users Home Spaces
Element permission = element.element(ELEMENT_HOMESPACEPERMISSION);
if (permission != null)
diff --git a/source/java/org/alfresco/web/ui/repo/component/UISimpleSearch.java b/source/java/org/alfresco/web/ui/repo/component/UISimpleSearch.java
index 16e954c113..ecc375ff66 100644
--- a/source/java/org/alfresco/web/ui/repo/component/UISimpleSearch.java
+++ b/source/java/org/alfresco/web/ui/repo/component/UISimpleSearch.java
@@ -132,6 +132,7 @@ public class UISimpleSearch extends UICommand
*/
public void broadcast(FacesEvent event) throws AbortProcessingException
{
+ FacesContext fc = getFacesContext();
if (event instanceof SearchEvent)
{
// update the component parameters from the search event details
@@ -141,6 +142,7 @@ public class UISimpleSearch extends UICommand
SearchContext context = new SearchContext();
context.setText(searchEvent.SearchText);
context.setMode(searchEvent.SearchMode);
+ context.setForceAndTerms(Application.getClientConfig(fc).getForceAndTerms());
this.search = context;
super.broadcast(event);
@@ -149,7 +151,6 @@ public class UISimpleSearch extends UICommand
{
// special case to navigate to the advanced search screen
AdvancedSearchEvent searchEvent = (AdvancedSearchEvent)event;
- FacesContext fc = getFacesContext();
fc.getApplication().getNavigationHandler().handleNavigation(fc, null, searchEvent.Outcome);
// NOTE: we don't call super() here so that our nav outcome is the one that occurs!