/** * The contents of this file are subject to the license and copyright * detailed in the LICENSE and NOTICE files at the root of the source * tree and available online at * * http://www.dspace.org/license/ */ package org.dspace.app.xmlui.opensearch; import java.io.IOException; import java.io.Serializable; import java.sql.SQLException; import java.util.Map; import org.apache.avalon.excalibur.pool.Recyclable; import org.apache.avalon.framework.parameters.Parameters; import org.apache.cocoon.ProcessingException; import org.apache.cocoon.caching.CacheableProcessingComponent; import org.apache.cocoon.environment.ObjectModelHelper; import org.apache.cocoon.environment.Request; import org.apache.cocoon.environment.SourceResolver; import org.apache.cocoon.generation.AbstractGenerator; import org.apache.cocoon.util.HashUtil; import org.apache.cocoon.xml.dom.DOMStreamer; import org.apache.excalibur.source.SourceValidity; import org.apache.excalibur.source.impl.validity.NOPValidity; import org.dspace.app.util.OpenSearch; import org.dspace.app.xmlui.utils.ContextUtil; import org.dspace.content.DSpaceObject; import org.dspace.core.Context; import org.w3c.dom.Document; import org.xml.sax.SAXException; /** * * Generate an OpenSearch-compliant description document for DSpace, * based on dspace.cfg configuration properties * * @author Richard Rodgers * @author Nestor Oviedo */ public class DescriptionOpenSearchGenerator extends AbstractGenerator implements CacheableProcessingComponent, Recyclable { /** optional search scope (community or collection instance) or null */ protected DSpaceObject scope = null; /** * Generate the unique caching key. * It includes the class name to ensure uniqueness */ public Serializable getKey() { StringBuffer key = new StringBuffer("key:"); key.append(DescriptionOpenSearchGenerator.class.getName()); if (scope != null) { key.append(":"+scope.getHandle()); } return HashUtil.hash(key.toString()); } /** * It's not expected that the OpenSearch's configuration to be changed very frecuently, * so we assume this component is always valid (the cache should be cleared to update this component) */ public SourceValidity getValidity() { return NOPValidity.SHARED_INSTANCE; } /** * Setup configuration for this request. * Parsing of the scope parameter * * @throws ProcessingException if the scope param cannot be resolved to a valid Community or Collection */ public void setup(SourceResolver resolver, Map objectModel, String src, Parameters par) throws ProcessingException, SAXException, IOException { super.setup(resolver, objectModel, src, par); // Checks if scope is a valid community/collection handle Context context = null; try { context = ContextUtil.obtainContext(objectModel); } catch (SQLException e) { throw new ProcessingException("Couldn't get DSpace Context object", e); } Request request = ObjectModelHelper.getRequest(objectModel); String scopeParam = request.getParameter("scope"); try { scope = OpenSearch.resolveScope(context, scopeParam); } catch (SQLException e) { throw new ProcessingException("Error resolving scope handle param "+scopeParam, e); } } /** * Generate the OpenSearch description document */ public void generate() throws IOException, SAXException, ProcessingException { // Create the description document Document retDoc = OpenSearch.getDescriptionDoc( scope == null ? null : scope.getHandle() ); // Send the SAX events DOMStreamer streamer = new DOMStreamer(contentHandler, lexicalHandler); streamer.stream(retDoc); } /** * Recycle */ public void recycle() { this.scope = null; super.recycle(); } }