. Saved Search execution and direct Lucene query execution support added to Template API.

. Fixed bug in TemplateNode for encoding of UTF-8 characters in generated URL filenames.

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2334 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
Kevin Roast 2006-02-09 14:22:54 +00:00
parent 923f393732
commit 26e45a09a1
8 changed files with 328 additions and 17 deletions

View File

@ -17,7 +17,7 @@
package org.alfresco.repo.template;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Collections;
import java.util.List;
import org.alfresco.service.ServiceRegistry;
@ -32,11 +32,9 @@ import org.apache.commons.logging.LogFactory;
*
* @author Kevin Roast
*/
public abstract class BasePathResultsMap extends HashMap implements Cloneable
public abstract class BasePathResultsMap extends BaseTemplateMap
{
protected static Log logger = LogFactory.getLog(BasePathResultsMap.class);
protected TemplateNode parent;
protected ServiceRegistry services = null;
/**
* Constructor
@ -46,16 +44,17 @@ public abstract class BasePathResultsMap extends HashMap implements Cloneable
*/
public BasePathResultsMap(TemplateNode parent, ServiceRegistry services)
{
super(1, 1.0f);
this.services = services;
this.parent = parent;
super(parent, services);
}
/**
* @see java.util.Map#get(java.lang.Object)
* Return a list or a single Node from executing an xpath against the parent Node.
*
* @param xpath XPath to execute
* @param firstOnly True to return the first result only
*
* @return List<TemplateNode>
*/
public abstract Object get(Object key);
protected List<TemplateNode> getChildrenByXPath(String xpath, boolean firstOnly)
{
List<TemplateNode> result = null;
@ -92,6 +91,6 @@ public abstract class BasePathResultsMap extends HashMap implements Cloneable
}
}
return result != null ? result : new ArrayList<TemplateNode>(0);
return result != null ? result : (List)Collections.emptyList();
}
}

View File

@ -0,0 +1,94 @@
/*
* 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.
*/
package org.alfresco.repo.template;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.TemplateNode;
import org.alfresco.service.cmr.search.ResultSet;
import org.alfresco.service.cmr.search.ResultSetRow;
import org.alfresco.service.cmr.search.SearchService;
/**
* Class providing the base Search Query services to execute a search returning a list of
* TemplateNode objects from a Lucene search string.
*
* @author Kevin Roast
*/
public abstract class BaseSearchResultsMap extends BaseTemplateMap
{
/**
* Constructor
*
* @param parent The parent TemplateNode to execute searches from
* @param services The ServiceRegistry to use
*/
public BaseSearchResultsMap(TemplateNode parent, ServiceRegistry services)
{
super(parent, services);
}
/**
* Perform a SearchService query with the given Lucene search string
*/
protected List<TemplateNode> query(String search)
{
List<TemplateNode> nodes = null;
// check if a full Lucene search string has been supplied or extracted from XML
if (search != null && search.length() != 0)
{
// perform the search against the repo
ResultSet results = null;
try
{
results = this.services.getSearchService().query(
this.parent.getNodeRef().getStoreRef(),
SearchService.LANGUAGE_LUCENE,
search);
if (results.length() != 0)
{
nodes = new ArrayList<TemplateNode>(results.length());
for (ResultSetRow row: results)
{
NodeRef nodeRef = row.getNodeRef();
nodes.add(new TemplateNode(nodeRef, services, this.parent.getImageResolver()));
}
}
}
catch (Throwable err)
{
throw new AlfrescoRuntimeException("Failed to execute search: " + search, err);
}
finally
{
if (results != null)
{
results.close();
}
}
}
return nodes != null ? nodes : (List)Collections.emptyList();
}
}

View File

@ -0,0 +1,52 @@
/*
* 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.
*/
package org.alfresco.repo.template;
import java.util.HashMap;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.TemplateNode;
/**
* An abstract Map class that can be used process the parent Node as part of the get()
* Map interface implementation.
*
* @author Kevin Roast
*/
public abstract class BaseTemplateMap extends HashMap implements Cloneable
{
protected TemplateNode parent;
protected ServiceRegistry services = null;
/**
* Constructor
*
* @param parent The parent TemplateNode to execute searches from
* @param services The ServiceRegistry to use
*/
public BaseTemplateMap(TemplateNode parent, ServiceRegistry services)
{
super(1, 1.0f);
this.services = services;
this.parent = parent;
}
/**
* @see java.util.Map#get(java.lang.Object)
*/
public abstract Object get(Object key);
}

View File

@ -0,0 +1,57 @@
/*
* 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.
*/
package org.alfresco.repo.template;
import java.io.StringReader;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.TemplateNode;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* Provides functionality to execute a Lucene search string and return TemplateNode objects.
*
* @author Kevin Roast
*/
public class LuceneSearchResultsMap extends BaseSearchResultsMap
{
/**
* Constructor
*
* @param parent The parent TemplateNode to execute searches from
* @param services The ServiceRegistry to use
*/
public LuceneSearchResultsMap(TemplateNode parent, ServiceRegistry services)
{
super(parent, services);
}
/**
* @see org.alfresco.repo.template.BaseTemplateMap#get(java.lang.Object)
*/
public Object get(Object key)
{
// execute the search
return query(key.toString());
}
}

View File

@ -28,7 +28,7 @@ import org.alfresco.service.cmr.repository.TemplateNode;
*
* @author Kevin Roast
*/
public final class NamePathResultsMap extends BasePathResultsMap implements Cloneable
public final class NamePathResultsMap extends BasePathResultsMap
{
/**
* Constructor

View File

@ -0,0 +1,89 @@
/*
* 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.
*/
package org.alfresco.repo.template;
import java.io.StringReader;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.TemplateNode;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
/**
* Provides functionality to load a saved search and execute it to return TemplateNode objects.
*
* @author Kevin Roast
*/
public class SavedSearchResultsMap extends BaseSearchResultsMap
{
private static final String ELEMENT_QUERY = "query";
/**
* Constructor
*
* @param parent The parent TemplateNode to execute searches from
* @param services The ServiceRegistry to use
*/
public SavedSearchResultsMap(TemplateNode parent, ServiceRegistry services)
{
super(parent, services);
}
/**
* @see org.alfresco.repo.template.BaseTemplateMap#get(java.lang.Object)
*/
public Object get(Object key)
{
String search = null;
if (key != null && key.toString().length() != 0)
{
// read the Saved Search XML on the specified node - and get the Lucene search from it
try
{
NodeRef ref = new NodeRef(key.toString());
ContentReader content = services.getContentService().getReader(ref, ContentModel.PROP_CONTENT);
if (content != null && content.exists())
{
// get the root element
SAXReader reader = new SAXReader();
Document document = reader.read(new StringReader(content.getContentString()));
Element rootElement = document.getRootElement();
Element queryElement = rootElement.element(ELEMENT_QUERY);
if (queryElement != null)
{
search = queryElement.getText();
}
}
}
catch (Throwable err)
{
throw new AlfrescoRuntimeException("Failed to find or load saved Search: " + key, err);
}
}
// execute the search
return query(search);
}
}

View File

@ -25,7 +25,7 @@ import org.alfresco.service.cmr.repository.TemplateNode;
*
* @author Kevin Roast
*/
public final class XPathResultsMap extends BasePathResultsMap implements Cloneable
public final class XPathResultsMap extends BasePathResultsMap
{
/**
* Constructor

View File

@ -26,10 +26,11 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.security.permissions.AccessDeniedException;
import org.alfresco.repo.template.LuceneSearchResultsMap;
import org.alfresco.repo.template.NamePathResultsMap;
import org.alfresco.repo.template.SavedSearchResultsMap;
import org.alfresco.repo.template.XPathResultsMap;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.dictionary.DictionaryService;
@ -39,6 +40,7 @@ import org.alfresco.service.namespace.QNameMap;
import org.alfresco.service.namespace.RegexQNamePattern;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.util.StringUtils;
import org.xml.sax.InputSource;
import freemarker.ext.dom.NodeModel;
@ -211,6 +213,24 @@ public final class TemplateNode implements Serializable
return new XPathResultsMap(this, this.services);
}
/**
* @return A map capable of returning a List of TemplateNode objects from an NodeRef to a Saved Search
* object. The Saved Search is executed and the resulting nodes supplied as a sequence.
*/
public Map getChildrenBySavedSearch()
{
return new SavedSearchResultsMap(this, this.services);
}
/**
* @return A map capable of returning a List of TemplateNode objects from an NodeRef to a Lucene search
* string. The Saved Search is executed and the resulting nodes supplied as a sequence.
*/
public Map getChildrenByLuceneSearch()
{
return new LuceneSearchResultsMap(this, this.services);
}
/**
* @return The associations for this Node. As a Map of assoc name to a List of TemplateNodes.
*/
@ -493,7 +513,7 @@ public final class TemplateNode implements Serializable
nodeRef.getStoreRef().getProtocol(),
nodeRef.getStoreRef().getIdentifier(),
nodeRef.getId(),
URLEncoder.encode(getName(), "US-ASCII") } );
StringUtils.replace(URLEncoder.encode(getName(), "UTF-8"), "+", "%20") } );
}
catch (UnsupportedEncodingException err)
{
@ -602,8 +622,8 @@ public final class TemplateNode implements Serializable
nodeRef.getStoreRef().getProtocol(),
nodeRef.getStoreRef().getIdentifier(),
nodeRef.getId(),
URLEncoder.encode(getName(), "US-ASCII"),
URLEncoder.encode(property.toString(), "US-ASCII") } );
StringUtils.replace(URLEncoder.encode(getName(), "UTF-8"), "+", "%20"),
StringUtils.replace(URLEncoder.encode(property.toString(), "UTF-8"), "+", "%20") } );
}
catch (UnsupportedEncodingException err)
{