/*
* eXist Open Source Native XML Database
* Copyright (C) 2001-09 Wolfgang M. Meier
* wolfgang@exist-db.org
* http://exist.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* $Id$
*/
package org.exist.xquery.modules.metadata;
import java.util.Iterator;
import org.apache.log4j.Logger;
import org.exist.collections.Collection;
import org.exist.dom.DocumentImpl;
import org.exist.dom.DocumentSet;
import org.exist.dom.ExtArrayNodeSet;
import org.exist.dom.NodeProxy;
import org.exist.dom.NodeSet;
import org.exist.dom.QName;
import org.exist.xmldb.XmldbURI;
import org.exist.xquery.BasicFunction;
import org.exist.xquery.Cardinality;
import org.exist.xquery.FunctionSignature;
import org.exist.xquery.XPathException;
import org.exist.xquery.XQueryContext;
import org.exist.xquery.value.FunctionReturnSequenceType;
import org.exist.xquery.value.Sequence;
import org.exist.xquery.value.Type;
/**
* @author Adam Retter <adam.retter@devon.gov.uk>
*/
public class MetadataFunction extends BasicFunction {
protected static final Logger logger = Logger.getLogger(MetadataFunction.class);
public final static FunctionSignature signature =
new FunctionSignature(
new QName("metadata", MetadataModule.NAMESPACE_URI, MetadataModule.PREFIX),
"Retrieves metadata for the dynamic context. " +
"If the context item is undefined an error is raised.",
null,
new FunctionReturnSequenceType(Type.NODE, Cardinality.ZERO_OR_ONE, "the metadata documents"),
"An orphaned experiment.");
public MetadataFunction(XQueryContext context) {
super(context, signature);
}
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException
{
//must be a context to act on
if(contextSequence == null)
{
throw new XPathException(this, "FONC0001: undefined context item");
}
//iterate through the source documents
DocumentSet sourceDocuments = contextSequence.getDocumentSet();
Iterator itSourceDocuments = sourceDocuments.getDocumentIterator();
NodeSet metadataDocuments = new ExtArrayNodeSet(sourceDocuments.getDocumentCount(), 1);
Collection metadataCollection = null;
XmldbURI lastMetadataCollectionURI = null;
while(itSourceDocuments.hasNext())
{
//get the source document
DocumentImpl sourceDoc = (DocumentImpl)itSourceDocuments.next();
//get the uri for the corresponding metadata document
XmldbURI metadataDocURI = XmldbURI.METADATA_COLLECTION_URI.append(sourceDoc.getURI());
//get the uri for the corresponding metadata collection
String tmpMetadataCollectionURI = metadataDocURI.getCollectionPath();
tmpMetadataCollectionURI = tmpMetadataCollectionURI.substring(0, tmpMetadataCollectionURI.lastIndexOf('/'));
XmldbURI metadataCollectionURI = XmldbURI.create(tmpMetadataCollectionURI);
//get the metadata document corresponding to the source document
DocumentImpl metadataDoc = null;
//TODO: not sure that this collection fetch avoidance code is working correctly?
//only refetch the collection if different uri
if(!metadataCollectionURI.equals(lastMetadataCollectionURI))
{
metadataCollection = context.getBroker().getCollection(metadataCollectionURI);
//remeber the metadata collection uri
lastMetadataCollectionURI = metadataCollectionURI;
}
//is there a corresponding metadata collection?
if(metadataCollection != null)
{
//is there a corresponding metadata document?
if(metadataCollection.hasDocument(metadataDocURI.lastSegment()))
{
//get the metadata document
metadataDoc = metadataCollection.getDocument(context.getBroker(), metadataDocURI.lastSegment());
}
}
//if we find a metadata document, add it to the result set
if(metadataDoc != null)
{
metadataDocuments.add(new NodeProxy(metadataDoc));
}
}
return metadataDocuments;
}
}