/*
* eXist Open Source Native XML Database
* Copyright (C) 2001-07 The eXist Project
* http://exist-db.org
*
* 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 library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
* $Id$
*/
package org.exist.xmlrpc;
import org.apache.log4j.Logger;
import org.exist.EXistException;
import org.exist.Namespaces;
import org.exist.backup.Backup;
import org.exist.collections.Collection;
import org.exist.collections.CollectionConfigurationException;
import org.exist.collections.CollectionConfigurationManager;
import org.exist.collections.IndexInfo;
import org.exist.dom.*;
import org.exist.memtree.NodeImpl;
import org.exist.numbering.NodeId;
import org.exist.protocolhandler.embedded.EmbeddedInputStream;
import org.exist.protocolhandler.xmldb.XmldbURL;
import org.exist.security.*;
import org.exist.security.SecurityManager;
import org.exist.security.xacml.AccessContext;
import org.exist.source.Source;
import org.exist.source.StringSource;
import org.exist.storage.DBBroker;
import org.exist.storage.DataBackup;
import org.exist.storage.XQueryPool;
import org.exist.storage.BrokerPool;
import org.exist.storage.lock.Lock;
import org.exist.storage.lock.LockedDocumentMap;
import org.exist.storage.serializers.Serializer;
import org.exist.storage.serializers.EXistOutputKeys;
import org.exist.storage.sync.Sync;
import org.exist.storage.txn.TransactionManager;
import org.exist.storage.txn.Txn;
import org.exist.util.*;
import org.exist.util.serializer.SAXSerializer;
import org.exist.util.serializer.SerializerPool;
import org.exist.validation.ValidationReport;
import org.exist.validation.Validator;
import org.exist.xmldb.XmldbURI;
import org.exist.xquery.*;
import org.exist.xquery.util.HTTPUtils;
import org.exist.xquery.value.*;
import org.exist.xupdate.Modification;
import org.exist.xupdate.XUpdateProcessor;
import org.w3c.dom.DocumentType;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import java.io.*;
import java.net.URISyntaxException;
import java.util.*;
import java.util.zip.DeflaterOutputStream;
import org.exist.storage.TextSearchEngine;
/**
* This class implements the actual methods defined by
* {@link org.exist.xmlrpc.RpcAPI}.
*
* @author Wolfgang Meier (wolfgang@exist-db.org)
* Modified by {Marco.Tampucci, Massimo.Martinelli} @isti.cnr.it
*/
public class RpcConnection implements RpcAPI {
private final static Logger LOG = Logger.getLogger(RpcConnection.class);
private final static int MAX_DOWNLOAD_CHUNK_SIZE = 0x40000;
private final static String DEFAULT_ENCODING = "UTF-8";
protected XmldbRequestProcessorFactory factory;
protected User user;
/**
* Creates a new <code>RpcConnection</code> instance.
*
* @exception EXistException if an error occurs
*/
public RpcConnection(XmldbRequestProcessorFactory factory, User user)
{
super();
this.factory = factory;
this.user = user;
}
private void handleException(Throwable e) throws EXistException, PermissionDeniedException {
LOG.debug(e.getMessage(), e);
if (e instanceof EXistException)
throw (EXistException) e;
else if (e instanceof PermissionDeniedException)
throw (PermissionDeniedException) e;
else {
//System.out.println(e.getClass().getName());
throw new EXistException(e);
}
}
public boolean createCollection(String name) throws EXistException, PermissionDeniedException {
return createCollection(name, null);
}
/**
* The method <code>createCollection</code>
*
* @param name a <code>String</code> value
* @param created a <code>Date</code> value
* @exception Exception if an error occurs
* @exception PermissionDeniedException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public boolean createCollection(String name, Date created) throws EXistException, PermissionDeniedException {
try {
return createCollection(XmldbURI.xmldbUriFor(name),created);
} catch (URISyntaxException e) {
handleException(e);
}
return false;
}
/**
* The method <code>createCollection</code>
*
* @param collUri a <code>XmldbURI</code> value
* @param created a <code>Date</code> value
* @exception Exception if an error occurs
* @exception PermissionDeniedException if an error occurs
*/
private boolean createCollection(XmldbURI collUri, Date created) throws PermissionDeniedException, EXistException {
DBBroker broker = null;
TransactionManager transact = factory.getBrokerPool().getTransactionManager();
Txn transaction = transact.beginTransaction();
try {
broker = factory.getBrokerPool().get(user);
Collection current = broker.getOrCreateCollection(transaction, collUri);
//TODO : register a lock (wich one ?) within the transaction ?
if (created != null)
current.setCreationTime( created.getTime());
LOG.debug("creating collection " + collUri);
broker.saveCollection(transaction, current);
transact.commit(transaction);
broker.flush();
//broker.sync();
LOG.info("collection " + collUri + " has been created");
return true;
} catch (Throwable e) {
transact.abort(transaction);
handleException(e);
} finally {
factory.getBrokerPool().release(broker);
}
return false;
}
/**
* The method <code>configureCollection</code>
*
* @param collName a <code>String</code> value
* @param configuration a <code>String</code> value
* @exception EXistException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public boolean configureCollection(String collName, String configuration)
throws EXistException, PermissionDeniedException {
try {
return configureCollection(XmldbURI.xmldbUriFor(collName),configuration);
} catch (URISyntaxException e) {
handleException(e);
}
return false;
}
/**
* The method <code>configureCollection</code>
*
* @param collUri a <code>XmldbURI</code> value
* @param configuration a <code>String</code> value
* @exception EXistException if an error occurs
*/
private boolean configureCollection(XmldbURI collUri, String configuration)
throws EXistException {
DBBroker broker = null;
Collection collection = null;
TransactionManager transact = factory.getBrokerPool().getTransactionManager();
Txn transaction = transact.beginTransaction();
try {
broker = factory.getBrokerPool().get(user);
try {
collection = broker.openCollection(collUri, Lock.READ_LOCK);
if (collection == null) {
transact.abort(transaction);
throw new EXistException("collection " + collUri + " not found!");
}
} finally {
if (collection != null)
collection.release(Lock.READ_LOCK);
}
CollectionConfigurationManager mgr = factory.getBrokerPool().getConfigurationManager();
mgr.addConfiguration(transaction, broker, collection, configuration);
transact.commit(transaction);
LOG.info("Configured '" + collection.getURI() + "'");
} catch (CollectionConfigurationException e) {
transact.abort(transaction);
throw new EXistException(e.getMessage());
} finally {
factory.getBrokerPool().release(broker);
}
return false;
}
/**
* The method <code>createId</code>
*
* @param collName a <code>String</code> value
* @return a <code>String</code> value
* @exception EXistException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public String createId(String collName) throws EXistException, URISyntaxException {
return createId(XmldbURI.xmldbUriFor(collName));
}
private String createId(XmldbURI collUri) throws EXistException {
DBBroker broker = factory.getBrokerPool().get(user);
Collection collection = null;
try {
collection = broker.openCollection(collUri, Lock.READ_LOCK);
if (collection == null)
throw new EXistException("collection " + collUri + " not found!");
XmldbURI id;
Random rand = new Random();
boolean ok;
do {
ok = true;
id = XmldbURI.create(Integer.toHexString(rand.nextInt()) + ".xml");
// check if this id does already exist
if (collection.hasDocument(id))
ok = false;
if (collection.hasSubcollection(id))
ok = false;
} while (!ok);
return id.toString();
} finally {
if(collection != null)
collection.release(Lock.READ_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>doQuery</code>
*
* @param broker a <code>DBBroker</code> value
* @param xpath a <code>String</code> value
* @param contextSet a <code>NodeSet</code> value
* @param parameters a <code>HashMap</code> value
* @return a <code>QueryResult</code> value
* @exception Exception if an error occurs
*/
protected QueryResult doQuery(DBBroker broker, String xpath,
NodeSet contextSet, HashMap parameters)
throws Exception {
XQuery xquery = broker.getXQueryService();
XQueryPool pool = xquery.getXQueryPool();
Source source = new StringSource(xpath);
CompiledXQuery compiled = compile(broker, source, parameters);
checkPragmas(compiled.getContext(), parameters);
LockedDocumentMap lockedDocuments = null;
try {
long start = System.currentTimeMillis();
lockedDocuments = beginProtected(broker, parameters);
if (lockedDocuments != null)
compiled.getContext().setProtectedDocs(lockedDocuments);
Properties outputProperties = new Properties();
Sequence result = xquery.execute(compiled, contextSet, outputProperties);
// pass last modified date to the HTTP response
HTTPUtils.addLastModifiedHeader( result, compiled.getContext() );
LOG.info("query took " + (System.currentTimeMillis() - start) + "ms.");
return new QueryResult(result, outputProperties);
} catch (XPathException e) {
return new QueryResult(e);
} finally {
if(lockedDocuments != null) {
lockedDocuments.unlock();
}
if(compiled != null)
pool.returnCompiledXQuery(source, compiled);
}
}
protected LockedDocumentMap beginProtected(DBBroker broker, HashMap parameters) throws EXistException {
String protectColl = (String) parameters.get(RpcAPI.PROTECTED_MODE);
if (protectColl == null)
return null;
do {
MutableDocumentSet docs = null;
LockedDocumentMap lockedDocuments = new LockedDocumentMap();
try {
Collection coll = broker.getCollection(XmldbURI.createInternal(protectColl));
docs = new DefaultDocumentSet();
coll.allDocs(broker, docs, true, lockedDocuments, Lock.WRITE_LOCK);
return lockedDocuments;
} catch (LockException e) {
LOG.debug("Deadlock detected. Starting over again. Docs: " + docs.getDocumentCount() + "; locked: " +
lockedDocuments.size());
lockedDocuments.unlock();
}
} while (true);
}
/**
* The method <code>compile</code>
*
* @param broker a <code>DBBroker</code> value
* @param source a <code>Source</code> value
* @param parameters a <code>HashMap</code> value
* @return a <code>CompiledXQuery</code> value
* @exception XPathException if an error occurs
* @exception IOException if an error occurs
*/
private CompiledXQuery compile(DBBroker broker, Source source, HashMap parameters) throws XPathException, IOException {
XQuery xquery = broker.getXQueryService();
XQueryPool pool = xquery.getXQueryPool();
CompiledXQuery compiled = pool.borrowCompiledXQuery(broker, source);
XQueryContext context;
if(compiled == null)
context = xquery.newContext(AccessContext.XMLRPC);
else
context = compiled.getContext();
String base = (String) parameters.get(RpcAPI.BASE_URI);
if(base!=null)
context.setBaseURI(new AnyURIValue(base));
HashMap namespaces = (HashMap)parameters.get(RpcAPI.NAMESPACES);
if(namespaces != null && namespaces.size() > 0) {
context.declareNamespaces(namespaces);
}
// declare static variables
HashMap variableDecls = (HashMap)parameters.get(RpcAPI.VARIABLES);
if(variableDecls != null) {
for (Iterator i = variableDecls.entrySet().iterator(); i.hasNext();) {
Map.Entry entry = (Map.Entry) i.next();
LOG.debug("declaring " + entry.getKey().toString() + " = " + entry.getValue());
context.declareVariable((String) entry.getKey(), entry.getValue());
}
}
Object[] staticDocuments = (Object[])parameters.get(RpcAPI.STATIC_DOCUMENTS);
if(staticDocuments != null) {
try {
XmldbURI[] d = new XmldbURI[staticDocuments.length];
for (int i = 0; i < staticDocuments.length; i++) {
XmldbURI next = XmldbURI.xmldbUriFor((String) staticDocuments[i]);
d[i] = next;
}
context.setStaticallyKnownDocuments(d);
} catch(URISyntaxException e) {
throw new XPathException(e);
}
} else if(context.isBaseURIDeclared()) {
context.setStaticallyKnownDocuments(new XmldbURI[] { context.getBaseURI().toXmldbURI() });
}
if(compiled == null)
compiled = xquery.compile(context, source);
return compiled;
}
/**
* The method <code>printDiagnostics</code>
*
* @param query a <code>String</code> value
* @param parameters a <code>HashMap</code> value
* @return a <code>String</code> value
* @exception Exception if an error occurs
*/
public String printDiagnostics(String query, HashMap parameters) throws EXistException, PermissionDeniedException {
DBBroker broker = null;
try {
broker = factory.getBrokerPool().get(user);
Source source = new StringSource(query);
XQuery xquery = broker.getXQueryService();
XQueryPool pool = xquery.getXQueryPool();
CompiledXQuery compiled = pool.borrowCompiledXQuery(broker, source);
if(compiled == null)
compiled = compile(broker, source, parameters);
StringWriter writer = new StringWriter();
compiled.dump(writer);
return writer.toString();
} catch (Throwable e) {
handleException(e);
} finally {
factory.getBrokerPool().release(broker);
}
return null;
}
/**
* Check if the XQuery contains pragmas that define serialization settings.
* If yes, copy the corresponding settings to the current set of output properties.
*
* @param context
*/
protected void checkPragmas(XQueryContext context, HashMap parameters) throws XPathException {
Option pragma = context.getOption(Option.SERIALIZE_QNAME);
checkPragmas(pragma, parameters);
}
protected void checkPragmas(Option pragma, HashMap parameters) throws XPathException {
if(pragma == null)
return;
String[] contents = pragma.tokenizeContents();
for(int i = 0; i < contents.length; i++) {
String[] pair = Option.parseKeyValuePair(contents[i]);
if(pair == null)
throw new XPathException("Unknown parameter found in " + pragma.getQName().getStringValue() +
": '" + contents[i] + "'");
LOG.debug("Setting serialization property from pragma: " + pair[0] + " = " + pair[1]);
parameters.put(pair[0], pair[1]);
}
}
public int executeQuery(byte[] xpath, String encoding, HashMap parameters) throws EXistException, PermissionDeniedException {
String xpathString = null;
if (encoding != null)
try {
xpathString = new String(xpath, encoding);
} catch (UnsupportedEncodingException e) {
LOG.warn(e);
}
if (xpathString == null)
xpathString = new String(xpath);
LOG.debug("query: " + xpathString);
return executeQuery(xpathString, parameters);
}
/**
* The method <code>executeQuery</code>
*
* @param xpath a <code>String</code> value
* @param parameters a <code>HashMap</code> value
* @return an <code>int</code> value
* @exception Exception if an error occurs
*/
public int executeQuery(String xpath, HashMap parameters) throws EXistException, PermissionDeniedException {
long startTime = System.currentTimeMillis();
DBBroker broker = null;
try {
broker = factory.getBrokerPool().get(user);
QueryResult result = doQuery(broker, xpath, null,
parameters);
if(result.hasErrors())
throw result.getException();
result.queryTime = System.currentTimeMillis() - startTime;
return factory.resultSets.add(result);
} catch (Throwable e) {
handleException(e);
} finally {
factory.getBrokerPool().release(broker);
}
return -1;
}
/**
* The method <code>formatErrorMsg</code>
*
* @param message a <code>String</code> value
* @return a <code>String</code> value
*/
protected String formatErrorMsg(String message) {
return formatErrorMsg("error", message);
}
/**
* The method <code>formatErrorMsg</code>
*
* @param type a <code>String</code> value
* @param message a <code>String</code> value
* @return a <code>String</code> value
*/
protected String formatErrorMsg(String type, String message) {
StringBuilder buf = new StringBuilder();
buf.append("<exist:result xmlns:exist=\""+ Namespaces.EXIST_NS + "\" ");
buf.append("hitCount=\"0\">");
buf.append('<');
buf.append(type);
buf.append('>');
buf.append(message);
buf.append("</");
buf.append(type);
buf.append("></exist:result>");
return buf.toString();
}
/**
* The method <code>getCollectionDesc</code>
*
* @param rootCollection a <code>String</code> value
* @return a <code>HashMap</code> value
* @exception Exception if an error occurs
* @exception URISyntaxException if an error occurs
*/
public HashMap getCollectionDesc(String rootCollection) throws EXistException, PermissionDeniedException {
try {
return getCollectionDesc((rootCollection==null)?XmldbURI.ROOT_COLLECTION_URI:XmldbURI.xmldbUriFor(rootCollection));
} catch (Throwable e) {
handleException(e);
}
return null;
}
/**
* The method <code>getCollectionDesc</code>
*
* @param rootUri a <code>XmldbURI</code> value
* @return a <code>HashMap</code> value
* @exception Exception if an error occurs
*/
private HashMap getCollectionDesc(XmldbURI rootUri)
throws Exception {
DBBroker broker = factory.getBrokerPool().get(user);
Collection collection = null;
try {
collection = broker.openCollection(rootUri, Lock.READ_LOCK);
if (collection == null)
throw new EXistException("collection " + rootUri + " not found!");
HashMap desc = new HashMap();
Vector docs = new Vector();
Vector collections = new Vector();
if (collection.getPermissions().validate(user, Permission.READ)) {
for (Iterator i = collection.iterator(broker); i.hasNext(); ) {
DocumentImpl doc = (DocumentImpl) i.next();
Permission perms = doc.getPermissions();
HashMap hash = new HashMap(4);
hash.put("name", doc.getFileURI().toString());
hash.put("owner", perms.getOwner());
hash.put("group", perms.getOwnerGroup());
hash.put("permissions", new Integer(perms.getPermissions()));
hash.put("type",
doc.getResourceType() == DocumentImpl.BINARY_FILE
? "BinaryResource"
: "XMLResource");
docs.addElement(hash);
}
for (Iterator i = collection.collectionIterator(); i.hasNext(); )
collections.addElement(((XmldbURI) i.next()).toString());
}
Permission perms = collection.getPermissions();
desc.put("collections", collections);
desc.put("documents", docs);
desc.put("name", collection.getURI().toString());
desc.put("created", Long.toString(collection.getCreationTime()));
desc.put("owner", perms.getOwner());
desc.put("group", perms.getOwnerGroup());
desc.put("permissions", new Integer(perms.getPermissions()));
return desc;
} finally {
if(collection != null)
collection.release(Lock.READ_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>describeResource</code>
*
* @param resourceName a <code>String</code> value
* @return a <code>HashMap</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public HashMap describeResource(String resourceName)
throws EXistException, PermissionDeniedException {
try {
return describeResource(XmldbURI.xmldbUriFor(resourceName));
} catch (Throwable e) {
handleException(e);
}
return null;
}
/**
* The method <code>describeResource</code>
*
* @param resourceUri a <code>XmldbURI</code> value
* @return a <code>HashMap</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
*/
private HashMap describeResource(XmldbURI resourceUri)
throws EXistException, PermissionDeniedException {
DBBroker broker = factory.getBrokerPool().get(user);
DocumentImpl doc = null;
HashMap hash = new HashMap(5);
try {
doc = broker.getXMLResource(resourceUri, Lock.READ_LOCK);
if (doc == null) {
LOG.debug("document " + resourceUri + " not found!");
return hash;
}
if (!doc.getCollection().getPermissions().validate(user, Permission.READ)) {
throw new PermissionDeniedException("Not allowed to read collection");
}
Permission perms = doc.getPermissions();
hash.put("name", resourceUri.toString());
hash.put("owner", perms.getOwner());
hash.put("group", perms.getOwnerGroup());
hash.put("permissions", new Integer(perms.getPermissions()));
hash.put("type",
doc.getResourceType() == DocumentImpl.BINARY_FILE
? "BinaryResource"
: "XMLResource");
hash.put("content-length", new Integer(doc.getContentLength()));
hash.put("mime-type", doc.getMetadata().getMimeType());
hash.put("created", new Date(doc.getMetadata().getCreated()));
hash.put("modified", new Date(doc.getMetadata().getLastModified()));
return hash;
} finally {
if(doc != null)
doc.getUpdateLock().release(Lock.READ_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>describeCollection</code>
*
* @param rootCollection a <code>String</code> value
* @return a <code>HashMap</code> value
* @exception Exception if an error occurs
* @exception URISyntaxException if an error occurs
*/
public HashMap describeCollection(String rootCollection) throws EXistException, PermissionDeniedException {
try {
return describeCollection((rootCollection==null)?XmldbURI.ROOT_COLLECTION_URI:XmldbURI.xmldbUriFor(rootCollection));
} catch (Throwable e) {
handleException(e);
return null;
}
}
/**
* The method <code>describeCollection</code>
*
* @param collUri a <code>XmldbURI</code> value
* @return a <code>HashMap</code> value
* @exception Exception if an error occurs
*/
private HashMap describeCollection(XmldbURI collUri)
throws Exception {
DBBroker broker = factory.getBrokerPool().get(user);
Collection collection = null;
try {
collection = broker.openCollection(collUri, Lock.READ_LOCK);
if (collection == null)
throw new EXistException("collection " + collUri + " not found!");
HashMap desc = new HashMap();
List collections = new ArrayList();
if (collection.getPermissions().validate(user, Permission.READ)) {
for (Iterator i = collection.collectionIterator(); i.hasNext(); )
collections.add(i.next().toString());
}
Permission perms = collection.getPermissions();
desc.put("collections", collections);
desc.put("name", collection.getURI().toString());
desc.put("created", Long.toString(collection.getCreationTime()));
desc.put("owner", perms.getOwner());
desc.put("group", perms.getOwnerGroup());
desc.put("permissions", new Integer(perms.getPermissions()));
return desc;
} finally {
if(collection != null)
collection.release(Lock.READ_LOCK);
factory.getBrokerPool().release(broker);
}
}
public byte[] getDocument(String name, HashMap parametri) throws EXistException,
PermissionDeniedException {
String encoding = DEFAULT_ENCODING;
String compression = "no";
if (((String) parametri.get("encoding")) == null) {
encoding = DEFAULT_ENCODING;
} else {
encoding = (String) parametri.get("encoding");
}
if (((String) parametri.get(EXistOutputKeys.COMPRESS_OUTPUT)) != null) {
compression = (String) parametri.get(EXistOutputKeys.COMPRESS_OUTPUT);
}
try {
String xml = getDocumentAsString(name, parametri);
if (xml == null)
throw new EXistException("document " + name + " not found!");
try {
if (compression.equals("no")) {
return xml.getBytes(encoding);
} else {
LOG.debug("getdocument with compression");
return Compressor.compress(xml.getBytes(encoding));
}
} catch (UnsupportedEncodingException uee) {
LOG.warn(uee);
if (compression.equals("no")) {
return xml.getBytes();
} else {
LOG.debug("getdocument with compression");
return Compressor.compress(xml.getBytes());
}
}
} catch (Throwable e) {
handleException(e);
return null;
}
}
/**
* The method <code>getDocument</code>
*
* @param docName a <code>String</code> value
* @param parametri a <code>HashMap</code> value
* @return a <code>String</code> value
* @exception Exception if an error occurs
* @exception URISyntaxException if an error occurs
*/
public String getDocumentAsString(String docName, HashMap parametri) throws EXistException, PermissionDeniedException {
try {
return getDocumentAsString(XmldbURI.xmldbUriFor(docName), parametri);
} catch (Throwable e) {
handleException(e);
return null;
}
}
/**
* The method <code>getDocument</code>
*
* @param docUri a <code>XmldbURI</code> value
* @param parametri a <code>HashMap</code> value
* @return a <code>String</code> value
* @exception Exception if an error occurs
*/
private String getDocumentAsString(XmldbURI docUri, HashMap parametri)
throws Exception {
DBBroker broker = null;
Collection collection = null;
DocumentImpl doc = null;
try {
broker = factory.getBrokerPool().get(user);
collection = broker.openCollection(docUri.removeLastSegment(), Lock.READ_LOCK);
if (collection == null) {
LOG.debug("collection " + docUri.removeLastSegment() + " not found!");
return null;
}
if(!collection.getPermissions().validate(user, Permission.READ)) {
throw new PermissionDeniedException("Insufficient privileges to read resource");
}
doc = collection.getDocumentWithLock(broker, docUri.lastSegment(), Lock.READ_LOCK);
if (doc == null) {
LOG.debug("document " + docUri + " not found!");
throw new EXistException("document not found");
}
if(!doc.getPermissions().validate(user, Permission.READ))
throw new PermissionDeniedException("Insufficient privileges to read resource " + docUri);
Serializer serializer = broker.getSerializer();
serializer.setProperties(parametri);
String xml = serializer.serialize(doc);
return xml;
} catch (NoSuchMethodError nsme) {
nsme.printStackTrace();
return null;
} finally {
if(collection != null)
collection.releaseDocument(doc, Lock.READ_LOCK);
if(collection != null)
collection.release(Lock.READ_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>getDocumentData</code>
*
* @param docName a <code>String</code> value
* @param parameters a <code>HashMap</code> value
* @return a <code>HashMap</code> value
* @exception Exception if an error occurs
*/
public HashMap getDocumentData(String docName, HashMap parameters) throws EXistException, PermissionDeniedException {
Collection collection = null;
DocumentImpl doc = null;
DBBroker broker = null;
try {
broker = factory.getBrokerPool().get(user);
XmldbURI docURI = XmldbURI.xmldbUriFor(docName);
collection = broker.openCollection(docURI.removeLastSegment(), Lock.READ_LOCK);
if (collection == null) {
LOG.debug("collection " + docURI.removeLastSegment() + " not found!");
throw new EXistException("Collection " + docURI.removeLastSegment() + " not found!");
}
if(!collection.getPermissions().validate(user, Permission.READ)) {
throw new PermissionDeniedException("Insufficient privileges to read resource");
}
doc = collection.getDocumentWithLock(broker, docURI.lastSegment(), Lock.READ_LOCK);
if (doc == null) {
LOG.debug("document " + docURI + " not found!");
throw new EXistException("document not found");
}
if(!doc.getPermissions().validate(user, Permission.READ))
throw new PermissionDeniedException("Insufficient privileges to read resource " + docName);
String encoding = (String)parameters.get(OutputKeys.ENCODING);
if(encoding == null)
encoding = DEFAULT_ENCODING;
// A tweak for very large resources, VirtualTempFile
HashMap result = new HashMap();
VirtualTempFile vtempFile = new VirtualTempFile(MAX_DOWNLOAD_CHUNK_SIZE,MAX_DOWNLOAD_CHUNK_SIZE);
vtempFile.setTempPrefix("eXistRPCC");
// binary check TODO dwes
if(doc.getResourceType() == DocumentImpl.XML_FILE) {
vtempFile.setTempPostfix(".xml");
Serializer serializer = broker.getSerializer();
serializer.setProperties(parameters);
Writer writer = new OutputStreamWriter(vtempFile, encoding);
serializer.serialize(doc, writer);
writer.close();
} else {
vtempFile.setTempPostfix(".bin");
broker.readBinaryResource((BinaryDocument)doc, vtempFile);
}
vtempFile.close();
byte[] firstChunk = vtempFile.getChunk(0);
result.put("data", firstChunk);
int offset = 0;
if(vtempFile.length()>MAX_DOWNLOAD_CHUNK_SIZE) {
offset = firstChunk.length;
int handle = factory.resultSets.add(new SerializedResult(vtempFile));
result.put("handle", Integer.toString(handle));
result.put("supports-long-offset", new Boolean(true));
} else {
vtempFile.delete();
}
result.put("offset", new Integer(offset));
return result;
} catch (Throwable e) {
handleException(e);
return null;
} finally {
if(collection != null) {
collection.releaseDocument(doc, Lock.READ_LOCK);
collection.getLock().release(Lock.READ_LOCK);
}
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>getNextChunk</code>
*
* @param handle a <code>String</code> value
* @param offset an <code>int</code> value
* @return a <code>HashMap</code> value
* @exception Exception if an error occurs
*/
public HashMap getNextChunk(String handle, int offset) throws EXistException, PermissionDeniedException {
try {
int resultId = Integer.parseInt(handle);
SerializedResult sr = factory.resultSets.getSerializedResult(resultId);
if(sr==null)
throw new EXistException("Invalid handle specified");
// This will keep the serialized result in the cache
sr.touch();
VirtualTempFile vfile = sr.result;
if(offset <= 0 || offset > vfile.length()) {
factory.resultSets.remove(resultId);
throw new EXistException("No more data available");
}
byte[] chunk = vfile.getChunk(offset);
long nextChunk = offset + chunk.length;
HashMap result = new HashMap();
result.put("data", chunk);
result.put("handle", handle);
if(nextChunk > (long)Integer.MAX_VALUE || nextChunk == vfile.length()) {
factory.resultSets.remove(resultId);
result.put("offset", new Integer(0));
} else
result.put("offset", new Integer((int)nextChunk));
return result;
} catch (Throwable e) {
handleException(e);
return null;
}
}
/**
* The method <code>getNextExtendedChunk</code>
*
* @param handle a <code>String</code> value
* @param offset a <code>String</code> value
* @return a <code>HashMap</code> value
* @exception Exception if an error occurs
*/
public HashMap getNextExtendedChunk(String handle, String offset) throws EXistException, PermissionDeniedException {
try {
int resultId = Integer.parseInt(handle);
SerializedResult sr = factory.resultSets.getSerializedResult(resultId);
if(sr==null)
throw new EXistException("Invalid handle specified");
// This will keep the serialized result in the cache
sr.touch();
VirtualTempFile vfile = sr.result;
long longOffset=new Long(offset).longValue();
if(longOffset< 0 || longOffset > vfile.length()) {
factory.resultSets.remove(resultId);
throw new EXistException("No more data available");
}
byte[] chunk = vfile.getChunk(longOffset);
long nextChunk = longOffset + chunk.length;
HashMap result = new HashMap();
result.put("data", chunk);
result.put("handle", handle);
if(nextChunk == vfile.length()) {
factory.resultSets.remove(resultId);
result.put("offset", Long.toString(0));
} else
result.put("offset", Long.toString(nextChunk));
return result;
} catch (Throwable e) {
handleException(e);
return null;
}
}
/**
* The method <code>getBinaryResource</code>
*
* @param name a <code>String</code> value
* @return a <code>byte[]</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public byte[] getBinaryResource(String name)
throws EXistException, PermissionDeniedException, URISyntaxException {
return getBinaryResource(XmldbURI.xmldbUriFor(name));
}
/**
* The method <code>getBinaryResource</code>
*
* @param name a <code>XmldbURI</code> value
* @return a <code>byte[]</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
*/
private byte[] getBinaryResource(XmldbURI name)
throws EXistException, PermissionDeniedException {
DBBroker broker = null;
DocumentImpl doc = null;
try {
broker = factory.getBrokerPool().get(user);
doc = broker.getXMLResource(name, Lock.READ_LOCK);
if (doc == null)
throw new EXistException("Resource " + name + " not found");
if (doc.getResourceType() != DocumentImpl.BINARY_FILE)
throw new EXistException("Document " + name
+ " is not a binary resource");
if(!doc.getPermissions().validate(user, Permission.READ))
throw new PermissionDeniedException("Insufficient privileges to read resource");
try {
InputStream is = broker.getBinaryResource((BinaryDocument)doc);
byte[] data = new byte[(int)broker.getBinaryResourceSize((BinaryDocument)doc)];
is.read(data);
is.close();
return data;
} catch (IOException ex) {
throw new EXistException("I/O error while reading resource.",ex);
}
} finally {
if(doc != null)
doc.getUpdateLock().release(Lock.READ_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>xupdate</code>
*
* @param collectionName a <code>String</code> value
* @param xupdate a <code>String</code> value
* @return an <code>int</code> value
* @exception SAXException if an error occurs
* @exception LockException if an error occurs
* @exception PermissionDeniedException if an error occurs
* @exception EXistException if an error occurs
* @exception XPathException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public int xupdate(String collectionName, byte[] xupdate) throws PermissionDeniedException, EXistException {
try {
return xupdate(XmldbURI.xmldbUriFor(collectionName), new String(xupdate, DEFAULT_ENCODING));
} catch (Throwable e) {
handleException(e);
return -1;
}
}
/**
* The method <code>xupdate</code>
*
* @param collUri a <code>XmldbURI</code> value
* @param xupdate a <code>String</code> value
* @return an <code>int</code> value
* @exception SAXException if an error occurs
* @exception LockException if an error occurs
* @exception PermissionDeniedException if an error occurs
* @exception EXistException if an error occurs
* @exception XPathException if an error occurs
*/
private int xupdate(XmldbURI collUri, String xupdate)
throws SAXException, LockException, PermissionDeniedException, EXistException,
XPathException {
TransactionManager transact = factory.getBrokerPool().getTransactionManager();
Txn transaction = transact.beginTransaction();
DBBroker broker = null;
try {
broker = factory.getBrokerPool().get(user);
Collection collection = broker.getCollection(collUri);
if (collection == null) {
transact.abort(transaction);
throw new EXistException("collection " + collUri + " not found");
}
//TODO : register a lock (which one ?) in the transaction ?
DocumentSet docs = collection.allDocs(broker, new DefaultDocumentSet(), true, true);
XUpdateProcessor processor = new XUpdateProcessor(broker, docs, AccessContext.XMLRPC);
Modification modifications[] = processor.parse(new InputSource(new StringReader(xupdate)));
long mods = 0;
for (int i = 0; i < modifications.length; i++) {
mods += modifications[i].process(transaction);
broker.flush();
}
transact.commit(transaction);
return (int) mods;
} catch (ParserConfigurationException e) {
transact.abort(transaction);
throw new EXistException(e.getMessage());
} catch (IOException e) {
transact.abort(transaction);
throw new EXistException(e.getMessage());
} finally {
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>xupdateResource</code>
*
* @param resource a <code>String</code> value
* @param xupdate a <code>String</code> value
* @return an <code>int</code> value
* @exception SAXException if an error occurs
* @exception LockException if an error occurs
* @exception PermissionDeniedException if an error occurs
* @exception EXistException if an error occurs
* @exception XPathException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public int xupdateResource(String resource, byte[] xupdate, String encoding) throws PermissionDeniedException, EXistException {
try {
return xupdateResource(XmldbURI.xmldbUriFor(resource), new String(xupdate, encoding));
} catch (Throwable e) {
handleException(e);
return -1;
}
}
/**
* The method <code>xupdateResource</code>
*
* @param docUri a <code>XmldbURI</code> value
* @param xupdate a <code>String</code> value
* @return an <code>int</code> value
* @exception SAXException if an error occurs
* @exception LockException if an error occurs
* @exception PermissionDeniedException if an error occurs
* @exception EXistException if an error occurs
* @exception XPathException if an error occurs
*/
private int xupdateResource(XmldbURI docUri, String xupdate)
throws SAXException, LockException, PermissionDeniedException, EXistException,
XPathException {
TransactionManager transact = factory.getBrokerPool().getTransactionManager();
Txn transaction = transact.beginTransaction();
DBBroker broker = null;
try {
broker = factory.getBrokerPool().get(user);
DocumentImpl doc = (DocumentImpl)broker.getXMLResource(docUri);
if (doc == null) {
transact.abort(transaction);
throw new EXistException("document " + docUri + " not found");
}
//TODO : register a lock (which one ?) within the transaction ?
if(!doc.getPermissions().validate(user, Permission.READ)) {
transact.abort(transaction);
throw new PermissionDeniedException("Insufficient privileges to read resource");
}
MutableDocumentSet docs = new DefaultDocumentSet();
docs.add(doc);
XUpdateProcessor processor = new XUpdateProcessor(broker, docs, AccessContext.XMLRPC);
Modification modifications[] = processor.parse(new InputSource(
new StringReader(xupdate)));
long mods = 0;
for (int i = 0; i < modifications.length; i++) {
mods += modifications[i].process(transaction);
broker.flush();
}
transact.commit(transaction);
return (int) mods;
} catch (ParserConfigurationException e) {
transact.abort(transaction);
throw new EXistException(e.getMessage());
} catch (IOException e) {
transact.abort(transaction);
throw new EXistException(e.getMessage());
} finally {
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>sync</code>
*
* @return a <code>boolean</code> value
*/
public boolean sync() {
DBBroker broker = null;
try {
broker = factory.getBrokerPool().get(XMLSecurityManager.SYSTEM_USER);
broker.sync(Sync.MAJOR_SYNC);
} catch (EXistException e) {
LOG.warn(e.getMessage(), e);
} finally {
factory.getBrokerPool().release(broker);
}
return true;
}
/**
* The method <code>isXACMLEnabled</code>
*
* @return a <code>boolean</code> value
*/
public boolean isXACMLEnabled() {
return factory.getBrokerPool().getSecurityManager().isXACMLEnabled();
}
/**
* The method <code>dataBackup</code>
*
* @param dest a <code>String</code> value
* @return a <code>boolean</code> value
*/
public boolean dataBackup(String dest ) {
factory.getBrokerPool().triggerSystemTask( new DataBackup(dest));
return true;
}
/**
* The method <code>getDocumentListing</code>
*
* @return a <code>Vector</code> value
* @exception EXistException if an error occurs
*/
public Vector getDocumentListing() throws EXistException {
DBBroker broker = null;
try {
broker = factory.getBrokerPool().get(user);
DocumentSet docs = broker.getAllXMLResources(new DefaultDocumentSet());
XmldbURI names[] = docs.getNames();
Vector vec = new Vector();
for (int i = 0; i < names.length; i++)
vec.addElement(names[i].toString());
return vec;
} finally {
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>getDocumentListing</code>
*
* @param collName a <code>String</code> value
* @return a <code>Vector</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public Vector getDocumentListing(String collName)
throws EXistException, PermissionDeniedException, URISyntaxException {
return getDocumentListing(XmldbURI.xmldbUriFor(collName));
}
/**
* The method <code>getDocumentListing</code>
*
* @param collUri a <code>XmldbURI</code> value
* @return a <code>Vector</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
*/
private Vector getDocumentListing(XmldbURI collUri)
throws EXistException, PermissionDeniedException {
DBBroker broker = null;
Collection collection = null;
try {
broker = factory.getBrokerPool().get(user);
collection = broker.openCollection(collUri, Lock.READ_LOCK);
Vector vec = new Vector();
if (collection == null) {
LOG.debug("collection " + collUri + " not found.");
return vec;
}
for (Iterator i = collection.iterator(broker); i.hasNext(); ) {
vec.addElement(((DocumentImpl) i.next()).getFileURI().toString());
}
return vec;
} finally {
if(collection != null)
collection.release(Lock.READ_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>getResourceCount</code>
*
* @param collectionName a <code>String</code> value
* @return an <code>int</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public int getResourceCount(String collectionName)
throws EXistException, PermissionDeniedException, URISyntaxException {
return getResourceCount(XmldbURI.xmldbUriFor(collectionName));
}
/**
* The method <code>getResourceCount</code>
*
* @param collUri a <code>XmldbURI</code> value
* @return an <code>int</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
*/
private int getResourceCount(XmldbURI collUri)
throws EXistException, PermissionDeniedException {
DBBroker broker = null;
Collection collection = null;
try {
broker = factory.getBrokerPool().get(user);
collection = broker.openCollection(collUri, Lock.READ_LOCK);
return collection.getDocumentCount();
} finally {
if(collection != null)
collection.release(Lock.READ_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>createResourceId</code>
*
* @param collectionName a <code>String</code> value
* @return a <code>String</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public String createResourceId(String collectionName)
throws EXistException, PermissionDeniedException, URISyntaxException {
return createResourceId(XmldbURI.xmldbUriFor(collectionName));
}
/**
* Creates a unique name for a database resource
* Uniqueness is only guaranteed within the eXist instance
*
* The name is based on a hex encoded string of a random integer
* and will have the format xxxxxxxx.xml where x is in the range
* 0 to 9 and a to f
*
* @return the unique resource name
*/
private String createResourceId(XmldbURI collUri) throws EXistException, PermissionDeniedException {
DBBroker broker = null;
Collection collection = null;
try {
broker = factory.getBrokerPool().get(user);
collection = broker.openCollection(collUri, Lock.READ_LOCK);
XmldbURI id;
Random rand = new Random();
boolean ok;
do {
ok = true;
id = XmldbURI.create(Integer.toHexString(rand.nextInt()) + ".xml");
// check if this id does already exist
if (collection.hasDocument(id))
ok = false;
if (collection.hasSubcollection(id))
ok = false;
} while (!ok);
return id.toString();
} finally {
if(collection != null)
collection.release(Lock.READ_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>listDocumentPermissions</code>
*
* @return a <code>HashMap</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public HashMap listDocumentPermissions(String name)
throws EXistException, PermissionDeniedException, URISyntaxException {
return listDocumentPermissions(XmldbURI.xmldbUriFor(name));
}
/**
* The method <code>listDocumentPermissions</code>
*
* @param collUri a <code>XmldbURI</code> value
* @return a <code>HashMap</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
*/
private HashMap listDocumentPermissions(XmldbURI collUri)
throws EXistException, PermissionDeniedException {
DBBroker broker = null;
Collection collection = null;
try {
broker = factory.getBrokerPool().get(user);
collection = broker.openCollection(collUri, Lock.READ_LOCK);
if (collection == null)
throw new EXistException("Collection " + collUri + " not found");
if (!collection.getPermissions().validate(user, Permission.READ))
throw new PermissionDeniedException(
"not allowed to read collection " + collUri);
HashMap result = new HashMap(collection.getDocumentCount());
for (Iterator i = collection.iterator(broker); i.hasNext(); ) {
DocumentImpl doc = (DocumentImpl) i.next();
Permission perm = doc.getPermissions();
List tmp = new ArrayList(3);
tmp.add(perm.getOwner());
tmp.add(perm.getOwnerGroup());
tmp.add(new Integer(perm.getPermissions()));
result.put(doc.getFileURI().toString(), tmp);
}
return result;
} finally {
if(collection != null)
collection.release(Lock.READ_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>listCollectionPermissions</code>
*
* @param name a <code>String</code> value
* @return a <code>HashMap</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public HashMap listCollectionPermissions(String name)
throws EXistException, PermissionDeniedException, URISyntaxException {
return listCollectionPermissions(XmldbURI.xmldbUriFor(name));
}
/**
* The method <code>listCollectionPermissions</code>
*
* @param collUri a <code>XmldbURI</code> value
* @return a <code>HashMap</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
*/
private HashMap listCollectionPermissions(XmldbURI collUri)
throws EXistException, PermissionDeniedException {
DBBroker broker = null;
Collection collection = null;
try {
broker = factory.getBrokerPool().get(user);
collection = broker.openCollection(collUri, Lock.READ_LOCK);
if (collection == null)
throw new EXistException("Collection " + collUri + " not found");
if (!collection.getPermissions().validate(user, Permission.READ))
throw new PermissionDeniedException("not allowed to read collection " + collUri);
HashMap result = new HashMap(collection.getChildCollectionCount());
for (Iterator i = collection.collectionIterator(); i.hasNext(); ) {
XmldbURI child = (XmldbURI) i.next();
XmldbURI path = collUri.append(child);
Collection childColl = broker.getCollection(path);
Permission perm = childColl.getPermissions();
List tmp = new ArrayList(3);
tmp.add(perm.getOwner());
tmp.add(perm.getOwnerGroup());
tmp.add(new Integer(perm.getPermissions()));
result.put(child, tmp);
}
return result;
} finally {
if(collection != null)
collection.release(Lock.READ_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>getHits</code>
*
* @param resultId an <code>int</code> value
* @return an <code>int</code> value
* @exception EXistException if an error occurs
*/
public int getHits(int resultId) throws EXistException {
QueryResult qr = factory.resultSets.getResult(resultId);
if (qr == null)
throw new EXistException("result set unknown or timed out");
qr.touch();
if (qr.result == null)
return 0;
return qr.result.getItemCount();
}
/**
* The method <code>getPermissions</code>
*
* @param name a <code>String</code> value
* @return a <code>HashMap</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public HashMap getPermissions(String name)
throws EXistException, PermissionDeniedException, URISyntaxException {
return getPermissions(XmldbURI.xmldbUriFor(name));
}
/**
* The method <code>getPermissions</code>
*
* @param uri a <code>XmldbURI</code> value
* @return a <code>HashMap</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
*/
private HashMap getPermissions(XmldbURI uri)
throws EXistException, PermissionDeniedException {
DBBroker broker = null;
Collection collection = null;
try {
broker = factory.getBrokerPool().get(user);
collection = broker.openCollection(uri, Lock.READ_LOCK);
Permission perm = null;
if (collection == null) {
DocumentImpl doc = null;
try {
doc = broker.getXMLResource(uri, Lock.READ_LOCK);
if (doc == null)
throw new EXistException("document or collection " + uri + " not found");
perm = doc.getPermissions();
} finally {
if (doc != null)
doc.getUpdateLock().release(Lock.READ_LOCK);
}
} else {
perm = collection.getPermissions();
}
HashMap result = new HashMap();
result.put("owner", perm.getOwner());
result.put("group", perm.getOwnerGroup());
result.put("permissions", new Integer(perm.getPermissions()));
return result;
} finally {
if (collection != null)
collection.release(Lock.READ_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>getCreationDate</code>
*
* @param collectionPath a <code>String</code> value
* @return a <code>Date</code> value
* @exception PermissionDeniedException if an error occurs
* @exception EXistException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public Date getCreationDate(String collectionPath)
throws PermissionDeniedException, EXistException, URISyntaxException {
return getCreationDate(XmldbURI.xmldbUriFor(collectionPath));
}
/**
* The method <code>getCreationDate</code>
*
* @param collUri a <code>XmldbURI</code> value
* @return a <code>Date</code> value
* @exception PermissionDeniedException if an error occurs
* @exception EXistException if an error occurs
*/
private Date getCreationDate(XmldbURI collUri)
throws PermissionDeniedException, EXistException {
DBBroker broker = null;
Collection collection = null;
try {
broker = factory.getBrokerPool().get(user);
collection = broker.openCollection(collUri, Lock.READ_LOCK);
if (collection == null)
throw new EXistException("collection " + collUri + " not found");
return new Date(collection.getCreationTime());
} finally {
if(collection != null)
collection.release(Lock.READ_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>getTimestamps</code>
*
* @param documentPath a <code>String</code> value
* @return a <code>Vector</code> value
* @exception PermissionDeniedException if an error occurs
* @exception EXistException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public Vector getTimestamps(String documentPath)
throws PermissionDeniedException, EXistException, URISyntaxException {
return getTimestamps(XmldbURI.xmldbUriFor(documentPath));
}
/**
* The method <code>getTimestamps</code>
*
* @param docUri a <code>XmldbURI</code> value
* @return a <code>Vector</code> value
* @exception PermissionDeniedException if an error occurs
* @exception EXistException if an error occurs
*/
private Vector getTimestamps(XmldbURI docUri)
throws PermissionDeniedException, EXistException {
DBBroker broker = null;
DocumentImpl doc = null;
try {
broker = factory.getBrokerPool().get(user);
doc = broker.getXMLResource(docUri, Lock.READ_LOCK);
if (doc == null) {
LOG.debug("document " + docUri + " not found!");
throw new EXistException("document not found");
}
DocumentMetadata metadata = doc.getMetadata();
Vector vector = new Vector(2);
vector.addElement(new Date(metadata.getCreated()));
vector.addElement(new Date(metadata.getLastModified()));
return vector;
} finally {
if(doc != null)
doc.getUpdateLock().release(Lock.READ_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>getUser</code>
*
* @param name a <code>String</code> value
* @return a <code>HashMap</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
*/
public HashMap getUser(String name) throws EXistException,
PermissionDeniedException {
User u = factory.getBrokerPool().getSecurityManager().getUser(name);
if (u == null)
throw new EXistException("user " + name + " does not exist");
HashMap tab = new HashMap();
tab.put("name", u.getName());
Vector groups = new Vector();
String[] gl = u.getGroups();
for (int i = 0; i < gl.length; i++)
groups.addElement(gl[i]);
tab.put("groups", groups);
if (u.getHome() != null)
tab.put("home", u.getHome().toString());
return tab;
}
/**
* The method <code>getUsers</code>
*
* @return a <code>Vector</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
*/
public Vector getUsers() throws EXistException,
PermissionDeniedException {
User users[] = factory.getBrokerPool().getSecurityManager().getUsers();
Vector r = new Vector();
for (int i = 0; i < users.length; i++) {
final HashMap tab = new HashMap();
tab.put("name", users[i].getName());
Vector groups = new Vector();
String[] gl = users[i].getGroups();
for (int j = 0; j < gl.length; j++)
groups.addElement(gl[j]);
tab.put("groups", groups);
if (users[i].getHome() != null)
tab.put("home", users[i].getHome().toString());
r.addElement(tab);
}
return r;
}
/**
* The method <code>getGroups</code>
*
* @return a <code>Vector</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
*/
public Vector getGroups() throws EXistException,
PermissionDeniedException {
String[] groups = factory.getBrokerPool().getSecurityManager().getGroups();
Vector v = new Vector(groups.length);
for (int i = 0; i < groups.length; i++) {
v.addElement(groups[i]);
}
return v;
}
/**
* The method <code>hasDocument</code>
*
* @param documentPath a <code>String</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
* @exception URISyntaxException if an error occurs
*/
public boolean hasDocument(String documentPath) throws URISyntaxException, EXistException, PermissionDeniedException {
return hasDocument(XmldbURI.xmldbUriFor(documentPath));
}
/**
* The method <code>hasDocument</code>
*
* @param docUri a <code>XmldbURI</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
*/
private boolean hasDocument(XmldbURI docUri) throws EXistException, PermissionDeniedException {
DBBroker broker = null;
try {
broker = factory.getBrokerPool().get(user);
return (broker.getXMLResource(docUri) != null);
} finally {
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>hasCollection</code>
*
* @param collectionName a <code>String</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
* @exception URISyntaxException if an error occurs
*/
public boolean hasCollection(String collectionName) throws EXistException, URISyntaxException {
return hasCollection(XmldbURI.xmldbUriFor(collectionName));
}
/**
* The method <code>hasCollection</code>
*
* @param collUri a <code>XmldbURI</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
*/
private boolean hasCollection(XmldbURI collUri) throws EXistException {
DBBroker broker = null;
try {
broker = factory.getBrokerPool().get(user);
return (broker.getCollection(collUri) != null);
} finally {
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>parse</code>
*
* @param xml a <code>byte</code> value
* @param documentPath a <code>String</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
* @exception URISyntaxException if an error occurs
*/
public boolean parse(byte[] xml, String documentPath, int overwrite) throws URISyntaxException, EXistException, PermissionDeniedException {
return parse(xml,documentPath, overwrite, null, null);
}
/**
* The method <code>parse</code>
*
* @param xml a <code>byte</code> value
* @param documentPath a <code>String</code> value
* @param created a <code>Date</code> value
* @param modified a <code>Date</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
* @exception URISyntaxException if an error occurs
*/
public boolean parse(byte[] xml, String documentPath,
int overwrite, Date created, Date modified) throws URISyntaxException, EXistException, PermissionDeniedException {
return parse(xml,XmldbURI.xmldbUriFor(documentPath),overwrite,created,modified);
}
/**
* The method <code>parse</code>
*
* @param xml a <code>byte</code> value
* @param docUri a <code>XmldbURI</code> value
* @param created a <code>Date</code> value
* @param modified a <code>Date</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
*/
private boolean parse(byte[] xml, XmldbURI docUri,
int overwrite, Date created, Date modified) throws EXistException, PermissionDeniedException {
DBBroker broker = null;
TransactionManager transact = factory.getBrokerPool().getTransactionManager();
Txn transaction = transact.beginTransaction();
try {
long startTime = System.currentTimeMillis();
broker = factory.getBrokerPool().get(user);
IndexInfo info = null;
InputSource source = null;
Collection collection = null;
try {
collection = broker.openCollection(docUri.removeLastSegment(), Lock.WRITE_LOCK);
if (collection == null) {
transact.abort(transaction);
throw new EXistException("Collection " + docUri.removeLastSegment() + " not found");
}
if (overwrite == 0) {
DocumentImpl old = collection.getDocument(broker, docUri.lastSegment());
//TODO : register the lock within the transaction ?
if (old != null) {
transact.abort(transaction);
throw new PermissionDeniedException("Document exists and overwrite is not allowed");
}
}
InputStream is = new ByteArrayInputStream(xml);
source = new InputSource(is);
info = collection.validateXMLResource(transaction, broker, docUri.lastSegment(), source);
MimeType mime = MimeTable.getInstance().getContentTypeFor(docUri.lastSegment());
if (mime != null && mime.isXMLType()){
info.getDocument().getMetadata().setMimeType(mime.getName());
}
if (created != null)
info.getDocument().getMetadata().setCreated( created.getTime());
if (modified != null)
info.getDocument().getMetadata().setLastModified( modified.getTime());
} finally {
if (collection != null)
collection.release(Lock.WRITE_LOCK);
}
collection.store(transaction, broker, info, source, false);
transact.commit(transaction);
LOG.debug("parsing " + docUri + " took " + (System.currentTimeMillis() - startTime) + "ms.");
return true;
} catch (Throwable e) {
transact.abort(transaction);
handleException(e);
return false;
} finally {
factory.getBrokerPool().release(broker);
}
}
/**
* Parse a file previously uploaded with upload.
*
* The temporary file will be removed.
*
* @param localFile
* @throws EXistException
* @throws IOException
*/
public boolean parseLocal(String localFile, String documentPath,
int overwrite, String mimeType) throws Exception, URISyntaxException {
return parseLocal(localFile, documentPath, overwrite, mimeType, null, null);
}
/**
* Parse a file previously uploaded with upload, forcing it to XML or Binary.
*
* The temporary file will be removed.
*
* @param localFile
* @throws EXistException
* @throws IOException
*/
public boolean parseLocalExt(String localFile, String documentPath,
int overwrite, String mimeType, int isXML) throws Exception, URISyntaxException {
return parseLocalExt(localFile, documentPath, overwrite, mimeType, isXML, null, null);
}
/**
* The method <code>parseLocal</code>
*
* @param localFile a <code>String</code> value
* @param docUri a <code>XmldbURI</code> value
* @param mimeType a <code>String</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
*/
private boolean parseLocal(String localFile, XmldbURI docUri,
int overwrite, String mimeType) throws Exception {
return parseLocal(localFile, docUri, overwrite, mimeType, null, null, null);
}
/**
* The method <code>parseLocal</code>
*
* @param localFile a <code>String</code> value
* @param docUri a <code>XmldbURI</code> value
* @param mimeType a <code>String</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
*/
private boolean parseLocalExt(String localFile, XmldbURI docUri,
int overwrite, String mimeType, int isXML) throws Exception {
return parseLocal(localFile, docUri, overwrite, mimeType, new Boolean(isXML!=0), null, null);
}
/**
* The method <code>parseLocal</code>
*
* @param localFile a <code>String</code> value
* @param documentPath a <code>String</code> value
* @param mimeType a <code>String</code> value
* @param created a <code>Date</code> value
* @param modified a <code>Date</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
* @exception URISyntaxException if an error occurs
*/
public boolean parseLocal(String localFile, String documentPath, int overwrite,
String mimeType, Date created, Date modified) throws URISyntaxException, EXistException, PermissionDeniedException {
return parseLocal(localFile,XmldbURI.xmldbUriFor(documentPath), overwrite, mimeType, null, created, modified);
}
/**
* The method <code>parseLocal</code>
*
* @param localFile a <code>String</code> value
* @param documentPath a <code>String</code> value
* @param mimeType a <code>String</code> value
* @param created a <code>Date</code> value
* @param modified a <code>Date</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
* @exception URISyntaxException if an error occurs
*/
public boolean parseLocalExt(String localFile, String documentPath, int overwrite,
String mimeType, int isXML, Date created, Date modified) throws URISyntaxException, EXistException, PermissionDeniedException {
return parseLocal(localFile,XmldbURI.xmldbUriFor(documentPath), overwrite, mimeType, new Boolean(isXML!=0), created, modified);
}
/**
* The method <code>parseLocal</code>
*
* @param localFile a <code>String</code> value
* @param docUri a <code>XmldbURI</code> value
* @param mimeType a <code>String</code> value
* @param created a <code>Date</code> value
* @param modified a <code>Date</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
*/
private boolean parseLocal(String localFile, XmldbURI docUri, int overwrite, String mimeType, Boolean isXML, Date created, Date modified)
throws EXistException, PermissionDeniedException
{
VirtualTempFileInputSource source=null;
try {
int handle = Integer.parseInt(localFile);
SerializedResult sr = factory.resultSets.getSerializedResult(handle);
if(sr==null)
throw new EXistException("Invalid handle specified");
source = new VirtualTempFileInputSource(sr.result);
// Unlinking the VirtualTempFile from the SerializeResult
sr.result=null;
factory.resultSets.remove(handle);
} catch(NumberFormatException nfe) {
// As this file can be a non-temporal one, we should not
// blindly erase it!
File file = new File(localFile);
if (!file.canRead())
throw new EXistException("unable to read file " + file.getAbsolutePath());
source = new VirtualTempFileInputSource(file);
} catch(IOException ioe) {
throw new EXistException("Error preparing virtual temp file for parsing");
}
TransactionManager transact = factory.getBrokerPool().getTransactionManager();
Txn transaction = transact.beginTransaction();
DBBroker broker = null;
DocumentImpl doc = null;
// DWES
MimeType mime = MimeTable.getInstance().getContentType(mimeType);
if (mime == null)
mime = MimeType.BINARY_TYPE;
boolean treatAsXML=(isXML!=null && isXML.booleanValue()) || (isXML==null && mime.isXMLType());
try {
broker = factory.getBrokerPool().get(user);
Collection collection = null;
IndexInfo info = null;
try {
collection = broker.openCollection(docUri.removeLastSegment(), Lock.WRITE_LOCK);
if (collection == null) {
transact.abort(transaction);
throw new EXistException("Collection " + docUri.removeLastSegment() + " not found");
}
if (overwrite == 0) {
DocumentImpl old = collection.getDocument(broker, docUri.lastSegment());
if (old != null) {
transact.abort(transaction);
throw new PermissionDeniedException("Old document exists and overwrite is not allowed");
}
}
//XML
if(treatAsXML) {
info = collection.validateXMLResource(transaction, broker, docUri.lastSegment(), source);
if (created != null)
info.getDocument().getMetadata().setCreated(created.getTime());
if (modified != null)
info.getDocument().getMetadata().setLastModified(modified.getTime());
} else {
InputStream is = source.getByteStream();
doc = collection.addBinaryResource(transaction, broker, docUri.lastSegment(), is,
mime.getName(), (int) source.getByteStreamLength());
is.close();
if (created != null)
doc.getMetadata().setCreated(created.getTime());
if (modified != null)
doc.getMetadata().setLastModified(modified.getTime());
}
} finally {
if (collection != null)
collection.release(Lock.WRITE_LOCK);
}
// DWES why seperate store?
if(treatAsXML){
collection.store(transaction, broker, info, source, false);
}
// generic
transact.commit(transaction);
} catch (Throwable e) {
transact.abort(transaction);
handleException(e);
} finally {
factory.getBrokerPool().release(broker);
// DWES there are situations the file is not cleaned up
if(source!=null)
source.free();
}
return true; // when arrived here, insert/update was successful
}
/**
* The method <code>storeBinary</code>
*
* @param data a <code>byte</code> value
* @param documentPath a <code>String</code> value
* @param mimeType a <code>String</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
* @exception URISyntaxException if an error occurs
*/
public boolean storeBinary(byte[] data, String documentPath, String mimeType,
int overwrite) throws Exception, URISyntaxException {
return storeBinary(data, documentPath, mimeType, overwrite, null, null);
}
/**
* The method <code>storeBinary</code>
*
* @param data a <code>byte</code> value
* @param docUri a <code>XmldbURI</code> value
* @param mimeType a <code>String</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
*/
private boolean storeBinary(byte[] data, XmldbURI docUri, String mimeType,
int overwrite) throws Exception {
return storeBinary(data, docUri, mimeType, overwrite, null, null);
}
/**
* The method <code>storeBinary</code>
*
* @param data a <code>byte</code> value
* @param documentPath a <code>String</code> value
* @param mimeType a <code>String</code> value
* @param created a <code>Date</code> value
* @param modified a <code>Date</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
* @exception URISyntaxException if an error occurs
*/
public boolean storeBinary(byte[] data, String documentPath, String mimeType,
int overwrite, Date created, Date modified) throws URISyntaxException, EXistException, PermissionDeniedException {
return storeBinary(data,XmldbURI.xmldbUriFor(documentPath),mimeType,overwrite,created,modified);
}
/**
* The method <code>storeBinary</code>
*
* @param data a <code>byte</code> value
* @param docUri a <code>XmldbURI</code> value
* @param mimeType a <code>String</code> value
* @param created a <code>Date</code> value
* @param modified a <code>Date</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
*/
private boolean storeBinary(byte[] data, XmldbURI docUri, String mimeType,
int overwrite, Date created, Date modified) throws EXistException, PermissionDeniedException {
DBBroker broker = null;
DocumentImpl doc = null;
TransactionManager transact = factory.getBrokerPool().getTransactionManager();
Txn transaction = transact.beginTransaction();
try {
broker = factory.getBrokerPool().get(user);
Collection collection = broker.openCollection(docUri.removeLastSegment(), Lock.WRITE_LOCK);
if (collection == null) {
transact.abort(transaction);
throw new EXistException("Collection " + docUri.removeLastSegment() + " not found");
}
// keep the write lock in the transaction
transaction.registerLock(collection.getLock(), Lock.WRITE_LOCK);
if (overwrite == 0) {
DocumentImpl old = collection.getDocument(broker, docUri.lastSegment());
if (old != null) {
transact.abort(transaction);
throw new PermissionDeniedException("Old document exists and overwrite is not allowed");
}
}
LOG.debug("Storing binary resource to collection " + collection.getURI());
doc = collection.addBinaryResource(transaction, broker, docUri.lastSegment(), data, mimeType);
if (created != null)
doc.getMetadata().setCreated(created.getTime());
if (modified != null)
doc.getMetadata().setLastModified(modified.getTime());
transact.commit(transaction);
} catch (Throwable e) {
transact.abort(transaction);
handleException(e);
return false;
} finally {
factory.getBrokerPool().release(broker);
}
return doc != null;
}
/**
* The method <code>upload</code>
*
* @param chunk a <code>byte</code> value
* @param length an <code>int</code> value
* @param fileName a <code>String</code> value
* @param compressed a <code>boolean</code> value
* @return a <code>String</code> value
* @exception EXistException if an error occurs
* @exception IOException if an error occurs
*/
public String upload(byte[] chunk, int length, String fileName, boolean compressed)
throws EXistException, IOException
{
VirtualTempFile vtempFile;
if (fileName == null || fileName.length() == 0) {
// create temporary file
vtempFile = new VirtualTempFile(MAX_DOWNLOAD_CHUNK_SIZE,MAX_DOWNLOAD_CHUNK_SIZE);
vtempFile.setTempPrefix("rpc");
vtempFile.setTempPostfix(".xml");
int handle = factory.resultSets.add(new SerializedResult(vtempFile));
fileName = Integer.toString(handle);
} else {
// LOG.debug("appending to file " + fileName);
try {
int handle = Integer.parseInt(fileName);
SerializedResult sr = factory.resultSets.getSerializedResult(handle);
if(sr==null)
throw new EXistException("Invalid handle specified");
// This will keep the serialized result in the cache
sr.touch();
vtempFile = sr.result;
} catch(NumberFormatException nfe) {
throw new EXistException("Syntactically invalid handle specified");
}
}
if (compressed)
Compressor.uncompress(chunk, vtempFile);
else
vtempFile.write(chunk, 0, length);
return fileName;
}
/**
* The method <code>printAll</code>
*
* @param broker a <code>DBBroker</code> value
* @param resultSet a <code>Sequence</code> value
* @param howmany an <code>int</code> value
* @param start an <code>int</code> value
* @param properties a <code>HashMap</code> value
* @param queryTime a <code>long</code> value
* @return a <code>String</code> value
* @exception Exception if an error occurs
*/
protected String printAll(DBBroker broker, Sequence resultSet, int howmany,
int start, HashMap properties, long queryTime) throws Exception {
if (resultSet.isEmpty()) {
StringBuilder buf = new StringBuilder();
String opt = (String) properties.get(OutputKeys.OMIT_XML_DECLARATION);
if (opt == null || opt.equalsIgnoreCase("no"))
buf.append("<?xml version=\"1.0\"?>\n");
buf.append("<exist:result xmlns:exist=\"").append(Namespaces.EXIST_NS).append("\" ");
buf.append("hitCount=\"0\"/>");
return buf.toString();
}
if (howmany > resultSet.getItemCount() || howmany == 0)
howmany = resultSet.getItemCount();
if (start < 1 || start > resultSet.getItemCount())
throw new EXistException("start parameter out of range");
StringWriter writer = new StringWriter();
writer.write("<exist:result xmlns:exist=\"");
writer.write(Namespaces.EXIST_NS);
writer.write("\" hits=\"");
writer.write(Integer.toString(resultSet.getItemCount()));
writer.write("\" start=\"");
writer.write(Integer.toString(start));
writer.write("\" count=\"");
writer.write(Integer.toString(howmany));
writer.write("\">\n");
Serializer serializer = broker.getSerializer();
serializer.reset();
serializer.setProperties(properties);
Item item;
for (int i = --start; i < start + howmany; i++) {
item = resultSet.itemAt(i);
if (item == null)
continue;
if (item.getType() == Type.ELEMENT) {
NodeValue node = (NodeValue) item;
writer.write(serializer.serialize(node));
} else {
writer.write("<exist:value type=\"");
writer.write(Type.getTypeName(item.getType()));
writer.write("\">");
writer.write(item.getStringValue());
writer.write("</exist:value>");
}
}
writer.write("\n</exist:result>");
return writer.toString();
}
/**
* The method <code>compile</code>
*
* @param query a <code>String</code> value
* @param parameters a <code>HashMap</code> value
* @return a <code>HashMap</code> value
* @exception Exception if an error occurs
*/
public HashMap compile(String query, HashMap parameters) throws EXistException, PermissionDeniedException {
HashMap ret = new HashMap();
DBBroker broker = null;
XQueryPool pool = null;
CompiledXQuery compiled = null;
Source source = new StringSource(query);
try {
broker = factory.getBrokerPool().get(user);
XQuery xquery = broker.getXQueryService();
pool = xquery.getXQueryPool();
compiled = compile(broker, source, parameters);
} catch (XPathException e) {
ret.put(RpcAPI.ERROR, e.getMessage());
if(e.getLine() != 0) {
ret.put(RpcAPI.LINE, new Integer(e.getLine()));
ret.put(RpcAPI.COLUMN, new Integer(e.getColumn()));
}
} catch (Throwable e) {
handleException(e);
} finally {
factory.getBrokerPool().release(broker);
if(compiled != null && pool != null)
pool.returnCompiledXQuery(source, compiled);
}
return ret;
}
/**
* The method <code>query</code>
*
* @param xpath a <code>String</code> value
* @param howmany an <code>int</code> value
* @param start an <code>int</code> value
* @param parameters a <code>HashMap</code> value
* @return a <code>String</code> value
* @exception Exception if an error occurs
*/
public String query(String xpath, int howmany, int start,
HashMap parameters) throws EXistException, PermissionDeniedException {
long startTime = System.currentTimeMillis();
String result = null;
DBBroker broker = null;
try {
broker = factory.getBrokerPool().get(user);
QueryResult qr = doQuery(broker, xpath, null, parameters);
if (qr == null)
return "<?xml version=\"1.0\"?>\n"
+ "<exist:result xmlns:exist=\"" + Namespaces.EXIST_NS + "\" "
+ "hitCount=\"0\"/>";
if (qr.hasErrors())
throw qr.getException();
result = printAll(broker, qr.result, howmany, start, parameters,
(System.currentTimeMillis() - startTime));
} catch (Throwable e) {
handleException(e);
} finally {
factory.getBrokerPool().release(broker);
}
return result;
}
/**
* The method <code>queryP</code>
*
* @param xpath a <code>String</code> value
* @param documentPath a <code>String</code> value
* @param s_id a <code>String</code> value
* @param parameters a <code>HashMap</code> value
* @return a <code>HashMap</code> value
* @exception Exception if an error occurs
* @exception URISyntaxException if an error occurs
*/
public HashMap queryP(String xpath, String documentPath,
String s_id, HashMap parameters) throws URISyntaxException, EXistException, PermissionDeniedException {
return queryP(xpath,
(documentPath==null) ? null : XmldbURI.xmldbUriFor(documentPath),
s_id, parameters);
}
/**
* The method <code>queryP</code>
*
* @param xpath a <code>String</code> value
* @param docUri a <code>XmldbURI</code> value
* @param s_id a <code>String</code> value
* @param parameters a <code>HashMap</code> value
* @return a <code>HashMap</code> value
* @exception Exception if an error occurs
*/
private HashMap queryP(String xpath, XmldbURI docUri,
String s_id, HashMap parameters) throws EXistException, PermissionDeniedException {
long startTime = System.currentTimeMillis();
String sortBy = (String) parameters.get(RpcAPI.SORT_EXPR);
HashMap ret = new HashMap();
List result = new ArrayList();
NodeSet nodes = null;
QueryResult queryResult;
Sequence resultSeq = null;
DBBroker broker = null;
try {
broker = factory.getBrokerPool().get(user);
if (docUri != null && s_id != null) {
DocumentImpl doc = (DocumentImpl) broker.getXMLResource(docUri);
Object[] docs = new Object[1];
docs[0] = docUri.toString();
parameters.put(RpcAPI.STATIC_DOCUMENTS, docs);
if(s_id.length() > 0) {
NodeId nodeId = factory.getBrokerPool().getNodeFactory().createFromString(s_id);
NodeProxy node = new NodeProxy(doc, nodeId);
nodes = new ExtArrayNodeSet(1);
nodes.add(node);
}
}
queryResult = doQuery(broker, xpath, nodes, parameters);
if (queryResult == null)
return ret;
if (queryResult.hasErrors()) {
// return an error description
XPathException e = queryResult.getException();
ret.put(RpcAPI.ERROR, e.getMessage());
if(e.getLine() != 0) {
ret.put(RpcAPI.LINE, new Integer(e.getLine()));
ret.put(RpcAPI.COLUMN, new Integer(e.getColumn()));
}
return ret;
}
resultSeq = queryResult.result;
if (LOG.isDebugEnabled())
LOG.debug("found " + resultSeq.getItemCount());
if (sortBy != null) {
SortedNodeSet sorted = new SortedNodeSet(factory.getBrokerPool(), user,
sortBy, AccessContext.XMLRPC);
sorted.addAll(resultSeq);
resultSeq = sorted;
}
NodeProxy p;
Vector entry;
if (resultSeq != null) {
SequenceIterator i = resultSeq.iterate();
if (i != null) {
Item next;
while (i.hasNext()) {
next = i.nextItem();
if (Type.subTypeOf(next.getType(), Type.NODE)) {
entry = new Vector();
if (((NodeValue) next).getImplementationType() == NodeValue.PERSISTENT_NODE) {
p = (NodeProxy) next;
entry.addElement(p.getDocument().getURI().toString());
entry.addElement(p.getNodeId().toString());
} else {
entry.addElement("temp_xquery/" + next.hashCode());
entry.addElement(String.valueOf(((NodeImpl) next).getNodeNumber()));
}
result.add(entry);
} else
result.add(next.getStringValue());
}
} else {
LOG.debug("sequence iterator is null. Should not");
}
} else
LOG.debug("result sequence is null. Skipping it...");
} catch (Throwable e) {
handleException(e);
return null;
} finally {
factory.getBrokerPool().release(broker);
}
queryResult.result = resultSeq;
queryResult.queryTime = (System.currentTimeMillis() - startTime);
int id = factory.resultSets.add(queryResult);
ret.put("id", new Integer(id));
ret.put("hash", new Integer(queryResult.hashCode()));
ret.put("results", result);
return ret;
}
/**
* The method <code>execute</code>
*
* @param pathToQuery database path pointing to a stored XQuery
* @param parameters a <code>HashMap</code> value
* @return a <code>HashMap</code> value
* @exception Exception if an error occurs
*/
public HashMap execute(String pathToQuery, HashMap parameters) throws EXistException, PermissionDeniedException {
long startTime = System.currentTimeMillis();
byte[] doc = getBinaryResource(XmldbURI.createInternal(pathToQuery));
String xpath = null;
try {
xpath = new String(doc, DEFAULT_ENCODING);
} catch (UnsupportedEncodingException e) {
throw new EXistException("Character encoding issue while reading stored XQuery: " + e.getMessage());
}
String sortBy = (String) parameters.get(RpcAPI.SORT_EXPR);
HashMap ret = new HashMap();
Vector result = new Vector();
NodeSet nodes = null;
QueryResult queryResult;
Sequence resultSeq = null;
DBBroker broker = null;
try {
broker = factory.getBrokerPool().get(user);
queryResult = doQuery(broker, xpath, nodes, parameters);
if (queryResult == null)
return ret;
if (queryResult.hasErrors()) {
// return an error description
XPathException e = queryResult.getException();
ret.put(RpcAPI.ERROR, e.getMessage());
if(e.getLine() != 0) {
ret.put(RpcAPI.LINE, new Integer(e.getLine()));
ret.put(RpcAPI.COLUMN, new Integer(e.getColumn()));
}
return ret;
}
resultSeq = queryResult.result;
if (LOG.isDebugEnabled())
LOG.debug("found " + resultSeq.getItemCount());
if (sortBy != null) {
SortedNodeSet sorted = new SortedNodeSet(factory.getBrokerPool(), user,
sortBy, AccessContext.XMLRPC);
sorted.addAll(resultSeq);
resultSeq = sorted;
}
NodeProxy p;
Vector entry;
if (resultSeq != null) {
SequenceIterator i = resultSeq.iterate();
if (i != null) {
Item next;
while (i.hasNext()) {
next = i.nextItem();
if (Type.subTypeOf(next.getType(), Type.NODE)) {
entry = new Vector();
if (((NodeValue) next).getImplementationType() == NodeValue.PERSISTENT_NODE) {
p = (NodeProxy) next;
entry.addElement(p.getDocument().getURI().toString());
entry.addElement(p.getNodeId().toString());
} else {
entry.addElement("temp_xquery/"
+ next.hashCode());
entry.addElement(String
.valueOf(((NodeImpl) next)
.getNodeNumber()));
}
result.addElement(entry);
} else
result.addElement(next.getStringValue());
}
} else {
LOG.debug("sequence iterator is null. Should not");
}
} else
LOG.debug("result sequence is null. Skipping it...");
} catch (Throwable e) {
handleException(e);
return null;
} finally {
factory.getBrokerPool().release(broker);
}
queryResult.result = resultSeq;
queryResult.queryTime = (System.currentTimeMillis() - startTime);
int id = factory.resultSets.add(queryResult);
ret.put("id", new Integer(id));
ret.put("results", result);
return ret;
}
/**
* The method <code>releaseQueryResult</code>
*
* @param handle an <code>int</code> value
*/
public boolean releaseQueryResult(int handle) {
factory.resultSets.remove(handle);
LOG.debug("removed query result with handle " + handle);
return true;
}
public boolean releaseQueryResult(int handle, int hash) {
factory.resultSets.remove(handle, hash);
LOG.debug("removed query result with handle " + handle);
return true;
}
/**
* The method <code>remove</code>
*
* @param documentPath a <code>String</code> value
* @exception Exception if an error occurs
* @exception URISyntaxException if an error occurs
*/
public boolean remove(String documentPath) throws URISyntaxException, EXistException, PermissionDeniedException {
return remove(XmldbURI.xmldbUriFor(documentPath));
}
/**
* The method <code>remove</code>
*
* @param docUri a <code>XmldbURI</code> value
* @exception Exception if an error occurs
*/
private boolean remove(XmldbURI docUri) throws EXistException, PermissionDeniedException {
TransactionManager transact = factory.getBrokerPool().getTransactionManager();
Txn transaction = transact.beginTransaction();
DBBroker broker = null;
Collection collection = null;
try {
broker = factory.getBrokerPool().get(user);
collection = broker.openCollection(docUri.removeLastSegment(), Lock.WRITE_LOCK);
if (collection == null) {
transact.abort(transaction);
throw new EXistException("Collection " + docUri.removeLastSegment() + " not found");
}
// keep the write lock in the transaction
transaction.registerLock(collection.getLock(), Lock.WRITE_LOCK);
DocumentImpl doc = collection.getDocument(broker, docUri.lastSegment());
if (doc == null) {
transact.abort(transaction);
throw new EXistException("Document " + docUri + " not found");
}
if(doc.getResourceType() == DocumentImpl.BINARY_FILE)
collection.removeBinaryResource(transaction, broker, doc);
else
collection.removeXMLResource(transaction, broker, docUri.lastSegment());
transact.commit(transaction);
return true;
} catch (Throwable e) {
handleException(e);
return false;
} finally {
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>removeCollection</code>
*
* @param collectionName a <code>String</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
* @exception URISyntaxException if an error occurs
*/
public boolean removeCollection(String collectionName) throws URISyntaxException, EXistException, PermissionDeniedException {
return removeCollection(XmldbURI.xmldbUriFor(collectionName));
}
/**
* The method <code>removeCollection</code>
*
* @param collURI a <code>XmldbURI</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
*/
private boolean removeCollection(XmldbURI collURI) throws EXistException, PermissionDeniedException {
TransactionManager transact = factory.getBrokerPool().getTransactionManager();
Txn transaction = transact.beginTransaction();
DBBroker broker = null;
Collection collection = null;
try {
broker = factory.getBrokerPool().get(user);
collection = broker.openCollection(collURI, Lock.WRITE_LOCK);
if (collection == null) {
transact.abort(transaction);
return false;
}
// keep the write lock in the transaction
transaction.registerLock(collection.getLock(), Lock.WRITE_LOCK);
LOG.debug("removing collection " + collURI);
boolean removed = broker.removeCollection(transaction, collection);
transact.commit(transaction);
return removed;
} catch (Throwable e) {
transact.abort(transaction);
handleException(e);
return false;
} finally {
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>removeUser</code>
*
* @param name a <code>String</code> value
* @return a <code>boolean</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
*/
public boolean removeUser(String name) throws EXistException,
PermissionDeniedException {
SecurityManager manager = factory.getBrokerPool()
.getSecurityManager();
if (!manager.hasAdminPrivileges(user))
throw new PermissionDeniedException(
"you are not allowed to remove users");
manager.deleteUser(name);
return true;
}
public byte[] retrieve(String doc, String id, HashMap parameters)
throws EXistException, PermissionDeniedException {
String xml = null;
try {
xml = retrieveAsString(doc, id, parameters);
try {
String encoding = (String) parameters.get(OutputKeys.ENCODING);
if (encoding == null)
encoding = DEFAULT_ENCODING;
return xml.getBytes(encoding);
} catch (UnsupportedEncodingException uee) {
LOG.warn(uee);
return xml.getBytes();
}
} catch (Throwable e) {
handleException(e);
return null;
}
}
/**
* The method <code>retrieve</code>
*
* @param documentPath a <code>String</code> value
* @param s_id a <code>String</code> value
* @param parameters a <code>HashMap</code> value
* @return a <code>String</code> value
* @exception Exception if an error occurs
* @exception URISyntaxException if an error occurs
*/
public String retrieveAsString(String documentPath, String s_id,
HashMap parameters) throws URISyntaxException, EXistException, PermissionDeniedException {
return retrieve(XmldbURI.xmldbUriFor(documentPath),s_id,parameters);
}
/**
* The method <code>retrieve</code>
*
* @param docUri a <code>XmldbURI</code> value
* @param s_id a <code>String</code> value
* @param parameters a <code>HashMap</code> value
* @return a <code>String</code> value
* @exception Exception if an error occurs
*/
private String retrieve(XmldbURI docUri, String s_id,
HashMap parameters) throws EXistException, PermissionDeniedException {
DBBroker broker = null;
try {
broker = factory.getBrokerPool().get(user);
NodeId nodeId = factory.getBrokerPool().getNodeFactory().createFromString(s_id);
DocumentImpl doc;
LOG.debug("loading doc " + docUri);
doc = (DocumentImpl) broker.getXMLResource(docUri);
NodeProxy node = new NodeProxy(doc, nodeId);
Serializer serializer = broker.getSerializer();
serializer.reset();
serializer.setProperties(parameters);
return serializer.serialize(node);
} catch (Throwable e) {
handleException(e);
return null;
} finally {
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>retrieveFirstChunk</code>
*
* @param docName a <code>String</code> value
* @param id a <code>String</code> value
* @param parameters a <code>HashMap</code> value
* @return a <code>HashMap</code> value
* @exception Exception if an error occurs
*/
public HashMap retrieveFirstChunk(String docName, String id, HashMap parameters)
throws EXistException, PermissionDeniedException
{
DBBroker broker = null;
String encoding = (String) parameters.get(OutputKeys.ENCODING);
if (encoding == null)
encoding = DEFAULT_ENCODING;
String compression = "no";
if (((String) parameters.get(EXistOutputKeys.COMPRESS_OUTPUT)) != null) {
compression = (String) parameters.get(EXistOutputKeys.COMPRESS_OUTPUT);
}
try {
XmldbURI docUri=XmldbURI.xmldbUriFor(docName);
broker = factory.getBrokerPool().get(user);
NodeId nodeId = factory.getBrokerPool().getNodeFactory().createFromString(id);
DocumentImpl doc;
LOG.debug("loading doc " + docUri);
doc = (DocumentImpl) broker.getXMLResource(docUri);
NodeProxy node = new NodeProxy(doc, nodeId);
Serializer serializer = broker.getSerializer();
serializer.reset();
serializer.setProperties(parameters);
HashMap result = new HashMap();
VirtualTempFile vtempFile = new VirtualTempFile(MAX_DOWNLOAD_CHUNK_SIZE,MAX_DOWNLOAD_CHUNK_SIZE);
vtempFile.setTempPrefix("eXistRPCC");
vtempFile.setTempPostfix(".xml");
OutputStream os=null;
if(compression.equals("yes")) {
LOG.debug("get result with compression");
os = new DeflaterOutputStream(vtempFile);
} else {
os = vtempFile;
}
try {
Writer writer = new OutputStreamWriter(os, encoding);
try {
serializer.serialize(node, writer);
} finally {
writer.close();
}
} finally {
try {
os.close();
} catch(IOException ioe) {
//IgnoreIT(R)
}
if(os!=vtempFile)
try {
vtempFile.close();
} catch(IOException ioe) {
//IgnoreIT(R)
}
}
byte[] firstChunk = vtempFile.getChunk(0);
result.put("data", firstChunk);
int offset = 0;
if(vtempFile.length() > MAX_DOWNLOAD_CHUNK_SIZE) {
offset = firstChunk.length;
int handle = factory.resultSets.add(new SerializedResult(vtempFile));
result.put("handle", Integer.toString(handle));
result.put("supports-long-offset", new Boolean(true));
} else {
vtempFile.delete();
}
result.put("offset", new Integer(offset));
return result;
} catch (Throwable e) {
handleException(e);
return null;
} finally {
factory.getBrokerPool().release(broker);
}
}
public byte[] retrieve(int resultId, int num, HashMap parameters)
throws EXistException, PermissionDeniedException {
String compression = "no";
if (((String) parameters.get(EXistOutputKeys.COMPRESS_OUTPUT)) != null) {
compression = (String) parameters.get(EXistOutputKeys.COMPRESS_OUTPUT);
}
try {
String xml = retrieveAsString(resultId, num, parameters);
String encoding = (String) parameters.get(OutputKeys.ENCODING);
if (encoding == null)
encoding = DEFAULT_ENCODING;
try {
if (compression.equals("no")) {
return xml.getBytes(encoding);
} else {
LOG.debug("get result with compression");
return Compressor.compress(xml.getBytes(encoding));
}
} catch (UnsupportedEncodingException uee) {
LOG.warn(uee);
if (compression.equals("no")) {
return xml.getBytes();
} else {
LOG.debug("get result with compression");
return Compressor.compress(xml.getBytes());
}
}
} catch (Throwable e) {
handleException(e);
return null;
}
}
/**
* The method <code>retrieve</code>
*
* @param resultId an <code>int</code> value
* @param num an <code>int</code> value
* @param parameters a <code>HashMap</code> value
* @return a <code>String</code> value
* @exception Exception if an error occurs
*/
private String retrieveAsString(int resultId, int num,
HashMap parameters) throws Exception {
DBBroker broker = null;
try {
broker = factory.getBrokerPool().get(user);
QueryResult qr = factory.resultSets.getResult(resultId);
if (qr == null)
throw new EXistException("result set unknown or timed out");
qr.touch();
Item item = qr.result.itemAt(num);
if (item == null)
throw new EXistException("index out of range");
if(Type.subTypeOf(item.getType(), Type.NODE)) {
NodeValue nodeValue = (NodeValue)item;
Serializer serializer = broker.getSerializer();
serializer.reset();
for (Iterator i = qr.serialization.entrySet().iterator(); i.hasNext();) {
Map.Entry entry = (Map.Entry) i.next();
parameters.put(entry.getKey().toString(), entry.getValue().toString());
}
serializer.setProperties(parameters);
return serializer.serialize(nodeValue);
} else {
return item.getStringValue();
}
} finally {
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>retrieveFirstChunk</code>
*
* @param resultId an <code>int</code> value
* @param num an <code>int</code> value
* @param parameters a <code>HashMap</code> value
* @return a <code>HashMap</code> value
* @exception Exception if an error occurs
*/
public HashMap retrieveFirstChunk(int resultId, int num, HashMap parameters)
throws EXistException, PermissionDeniedException
{
String encoding = (String) parameters.get(OutputKeys.ENCODING);
if (encoding == null)
encoding = DEFAULT_ENCODING;
String compression = "no";
if (((String) parameters.get(EXistOutputKeys.COMPRESS_OUTPUT)) != null) {
compression = (String) parameters.get(EXistOutputKeys.COMPRESS_OUTPUT);
}
DBBroker broker = null;
try {
broker = factory.getBrokerPool().get(user);
QueryResult qr = factory.resultSets.getResult(resultId);
if (qr == null)
throw new EXistException("result set unknown or timed out: " + resultId);
qr.touch();
Item item = qr.result.itemAt(num);
if (item == null)
throw new EXistException("index out of range");
HashMap result = new HashMap();
VirtualTempFile vtempFile = new VirtualTempFile(MAX_DOWNLOAD_CHUNK_SIZE,MAX_DOWNLOAD_CHUNK_SIZE);
vtempFile.setTempPrefix("eXistRPCC");
vtempFile.setTempPostfix(".xml");
OutputStream os=null;
if(compression.equals("yes")) {
LOG.debug("get result with compression");
os = new DeflaterOutputStream(vtempFile);
} else {
os = vtempFile;
}
try {
Writer writer = new OutputStreamWriter(os, encoding);
try {
if(Type.subTypeOf(item.getType(), Type.NODE)) {
NodeValue nodeValue = (NodeValue)item;
Serializer serializer = broker.getSerializer();
serializer.reset();
for (Iterator i = qr.serialization.entrySet().iterator(); i.hasNext();) {
Map.Entry entry = (Map.Entry) i.next();
parameters.put(entry.getKey().toString(), entry.getValue().toString());
}
serializer.setProperties(parameters);
serializer.serialize(nodeValue, writer);
} else {
writer.write(item.getStringValue());
}
} finally {
try {
writer.close();
} catch(IOException ioe) {
//IgnoreIT(R)
}
}
} finally {
try {
os.close();
} catch(IOException ioe) {
//IgnoreIT(R)
}
if(os!=vtempFile)
try {
vtempFile.close();
} catch(IOException ioe) {
//IgnoreIT(R)
}
}
byte[] firstChunk = vtempFile.getChunk(0);
result.put("data", firstChunk);
int offset = 0;
if(vtempFile.length() > MAX_DOWNLOAD_CHUNK_SIZE) {
offset = firstChunk.length;
int handle = factory.resultSets.add(new SerializedResult(vtempFile));
result.put("handle", Integer.toString(handle));
result.put("supports-long-offset", new Boolean(true));
} else {
vtempFile.delete();
}
result.put("offset", new Integer(offset));
return result;
} catch (Throwable e) {
handleException(e);
return null;
} finally {
factory.getBrokerPool().release(broker);
}
}
public byte[] retrieveAll(int resultId, HashMap parameters) throws EXistException,
PermissionDeniedException {
try {
String xml = retrieveAllAsString(resultId, parameters);
String encoding = (String) parameters.get(OutputKeys.ENCODING);
if (encoding == null)
encoding = DEFAULT_ENCODING;
try {
return xml.getBytes(encoding);
} catch (UnsupportedEncodingException uee) {
LOG.warn(uee);
return xml.getBytes();
}
} catch (Throwable e) {
handleException(e);
return null;
}
}
/**
* The method <code>retrieveAll</code>
*
* @param resultId an <code>int</code> value
* @param parameters a <code>HashMap</code> value
* @return a <code>String</code> value
* @exception Exception if an error occurs
*/
private String retrieveAllAsString(int resultId, HashMap parameters) throws Exception {
DBBroker broker = null;
try {
broker = factory.getBrokerPool().get(user);
QueryResult qr = factory.resultSets.getResult(resultId);
if (qr == null)
throw new EXistException("result set unknown or timed out");
qr.touch();
Serializer serializer = broker.getSerializer();
serializer.reset();
serializer.setProperties(qr.serialization);
SAXSerializer handler = (SAXSerializer) SerializerPool.getInstance().borrowObject(SAXSerializer.class);
StringWriter writer = new StringWriter();
handler.setOutput(writer, getProperties(parameters));
// serialize results
handler.startDocument();
handler.startPrefixMapping("exist", Namespaces.EXIST_NS);
AttributesImpl attribs = new AttributesImpl();
attribs.addAttribute(
"",
"hitCount",
"hitCount",
"CDATA",
Integer.toString(qr.result.getItemCount()));
handler.startElement(
Namespaces.EXIST_NS,
"result",
"exist:result",
attribs);
Item current;
char[] value;
for(SequenceIterator i = qr.result.iterate(); i.hasNext(); ) {
current = i.nextItem();
if(Type.subTypeOf(current.getType(), Type.NODE))
current.toSAX(broker, handler, null);
else {
value = current.toString().toCharArray();
handler.characters(value, 0, value.length);
}
}
handler.endElement(Namespaces.EXIST_NS, "result", "exist:result");
handler.endPrefixMapping("exist");
handler.endDocument();
SerializerPool.getInstance().returnObject(handler);
return writer.toString();
} finally {
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>retrieveAllFirstChunk</code>
*
* @param resultId an <code>int</code> value
* @param parameters a <code>HashMap</code> value
* @return a <code>String</code> value
* @exception Exception if an error occurs
*/
public HashMap retrieveAllFirstChunk(int resultId, HashMap parameters)
throws EXistException, PermissionDeniedException
{
String encoding = (String) parameters.get(OutputKeys.ENCODING);
if (encoding == null)
encoding = DEFAULT_ENCODING;
String compression = "no";
if (((String) parameters.get(EXistOutputKeys.COMPRESS_OUTPUT)) != null) {
compression = (String) parameters.get(EXistOutputKeys.COMPRESS_OUTPUT);
}
DBBroker broker = null;
try {
broker = factory.getBrokerPool().get(user);
QueryResult qr = factory.resultSets.getResult(resultId);
if (qr == null)
throw new EXistException("result set unknown or timed out");
qr.touch();
Serializer serializer = broker.getSerializer();
serializer.reset();
for (Iterator i = qr.serialization.entrySet().iterator(); i.hasNext();) {
Map.Entry entry = (Map.Entry) i.next();
parameters.put(entry.getKey().toString(), entry.getValue().toString());
}
serializer.setProperties(parameters);
SAXSerializer handler = (SAXSerializer) SerializerPool.getInstance().borrowObject(SAXSerializer.class);
HashMap result = new HashMap();
VirtualTempFile vtempFile = new VirtualTempFile(MAX_DOWNLOAD_CHUNK_SIZE,MAX_DOWNLOAD_CHUNK_SIZE);
vtempFile.setTempPrefix("eXistRPCC");
vtempFile.setTempPostfix(".xml");
OutputStream os=null;
if(compression.equals("yes")) {
LOG.debug("get result with compression");
os = new DeflaterOutputStream(vtempFile);
} else {
os = vtempFile;
}
try {
Writer writer = new OutputStreamWriter(os, encoding);
try {
handler.setOutput(writer, getProperties(parameters));
// serialize results
handler.startDocument();
handler.startPrefixMapping("exist", Namespaces.EXIST_NS);
AttributesImpl attribs = new AttributesImpl();
attribs.addAttribute(
"",
"hitCount",
"hitCount",
"CDATA",
Integer.toString(qr.result.getItemCount()));
handler.startElement(
Namespaces.EXIST_NS,
"result",
"exist:result",
attribs);
Item current;
char[] value;
for(SequenceIterator i = qr.result.iterate(); i.hasNext(); ) {
current = i.nextItem();
if(Type.subTypeOf(current.getType(), Type.NODE))
((NodeValue)current).toSAX(broker, handler, null);
else {
value = current.toString().toCharArray();
handler.characters(value, 0, value.length);
}
}
handler.endElement(Namespaces.EXIST_NS, "result", "exist:result");
handler.endPrefixMapping("exist");
handler.endDocument();
SerializerPool.getInstance().returnObject(handler);
} finally {
writer.close();
}
} finally {
try {
os.close();
} catch(IOException ioe) {
//IgnoreIT(R)
}
if(os!=vtempFile)
try {
vtempFile.close();
} catch(IOException ioe) {
//IgnoreIT(R)
}
}
byte[] firstChunk = vtempFile.getChunk(0);
result.put("data", firstChunk);
int offset = 0;
if(vtempFile.length() > MAX_DOWNLOAD_CHUNK_SIZE) {
offset = firstChunk.length;
int handle = factory.resultSets.add(new SerializedResult(vtempFile));
result.put("handle", Integer.toString(handle));
result.put("supports-long-offset", new Boolean(true));
} else {
vtempFile.delete();
}
result.put("offset", new Integer(offset));
return result;
} catch (Throwable e) {
handleException(e);
return null;
} finally {
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>setPermissions</code>
*
* @param resource a <code>String</code> value
* @param owner a <code>String</code> value
* @param ownerGroup a <code>String</code> value
* @param permissions a <code>String</code> value
* @return a <code>boolean</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public boolean setPermissions(String resource, String owner,
String ownerGroup, String permissions) throws EXistException,
PermissionDeniedException, URISyntaxException {
return setPermissions(XmldbURI.xmldbUriFor(resource),owner,ownerGroup,permissions);
}
/**
* The method <code>setPermissions</code>
*
* @param uri a <code>XmldbURI</code> value
* @param owner a <code>String</code> value
* @param ownerGroup a <code>String</code> value
* @param permissions a <code>String</code> value
* @return a <code>boolean</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
*/
private boolean setPermissions(XmldbURI uri, String owner,
String ownerGroup, String permissions) throws EXistException,
PermissionDeniedException {
DBBroker broker = null;
Collection collection = null;
DocumentImpl doc = null;
TransactionManager transact = factory.getBrokerPool().getTransactionManager();
Txn transaction = transact.beginTransaction();
try {
broker = factory.getBrokerPool().get(user);
SecurityManager manager = factory.getBrokerPool()
.getSecurityManager();
collection = broker.openCollection(uri, Lock.WRITE_LOCK);
if (collection == null) {
doc = broker.getXMLResource(uri, Lock.WRITE_LOCK);
if (doc == null) {
transact.abort(transaction);
throw new EXistException("document or collection " + uri + " not found");
}
//TODO : register the lock within the transaction ?
LOG.debug("changing permissions on document " + uri);
Permission perm = doc.getPermissions();
if (perm.validate(user, Permission.WRITE)
|| manager.hasAdminPrivileges(user)) {
if (owner != null) {
if (!(perm.getOwner().equals(user.getName()) || manager.hasAdminPrivileges(user)))
throw new PermissionDeniedException("not allowed to change permissions");
perm.setOwner(owner);
if (!manager.hasGroup(ownerGroup))
manager.addGroup(ownerGroup);
perm.setGroup(ownerGroup);
}
if (permissions != null && permissions.length() > 0)
perm.setPermissions(permissions);
broker.storeXMLResource(transaction, doc);
transact.commit(transaction);
broker.flush();
return true;
}
transact.abort(transaction);
throw new PermissionDeniedException("not allowed to change permissions");
} else {
// keep the write lock in the transaction
transaction.registerLock(collection.getLock(), Lock.WRITE_LOCK);
LOG.debug("changing permissions on collection " + uri);
Permission perm = collection.getPermissions();
if (perm.validate(user, Permission.WRITE)
|| manager.hasAdminPrivileges(user)) {
if (permissions != null)
perm.setPermissions(permissions);
if (owner != null) {
if (!(perm.getOwner().equals(user.getName()) || manager.hasAdminPrivileges(user)))
throw new PermissionDeniedException("not allowed to change permissions");
perm.setOwner(owner);
if (!manager.hasGroup(ownerGroup))
manager.addGroup(ownerGroup);
perm.setGroup(ownerGroup);
}
broker.saveCollection(transaction, collection);
transact.commit(transaction);
broker.flush();
return true;
}
transact.abort(transaction);
throw new PermissionDeniedException("not allowed to change permissions");
}
} catch (SyntaxException e) {
transact.abort(transaction);
throw new EXistException(e.getMessage());
} catch (PermissionDeniedException e) {
transact.abort(transaction);
throw new EXistException(e.getMessage());
} catch (IOException e) {
transact.abort(transaction);
throw new EXistException(e.getMessage());
} finally {
if(doc != null)
doc.getUpdateLock().release(Lock.WRITE_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>setPermissions</code>
*
* @param resource a <code>String</code> value
* @param owner a <code>String</code> value
* @param ownerGroup a <code>String</code> value
* @param permissions an <code>int</code> value
* @return a <code>boolean</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public boolean setPermissions(String resource, String owner,
String ownerGroup, int permissions) throws EXistException,
PermissionDeniedException, URISyntaxException {
return setPermissions(XmldbURI.xmldbUriFor(resource),owner,ownerGroup,permissions);
}
/**
* The method <code>setPermissions</code>
*
* @param uri a <code>XmldbURI</code> value
* @param owner a <code>String</code> value
* @param ownerGroup a <code>String</code> value
* @param permissions an <code>int</code> value
* @return a <code>boolean</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
*/
private boolean setPermissions(XmldbURI uri, String owner,
String ownerGroup, int permissions) throws EXistException,
PermissionDeniedException {
DBBroker broker = null;
Collection collection = null;
DocumentImpl doc = null;
TransactionManager transact = factory.getBrokerPool().getTransactionManager();
Txn transaction = transact.beginTransaction();
try {
broker = factory.getBrokerPool().get(user);
SecurityManager manager = factory.getBrokerPool().getSecurityManager();
collection = broker.openCollection(uri, Lock.WRITE_LOCK);
if (collection == null) {
doc = broker.getXMLResource(uri, Lock.WRITE_LOCK);
if (doc == null) {
transact.abort(transaction);
throw new EXistException("document or collection " + uri + " not found");
}
//TODO : register the lock within the transaction ?
LOG.debug("changing permissions on document " + uri);
Permission perm = doc.getPermissions();
if (perm.validate(user, Permission.WRITE)
|| manager.hasAdminPrivileges(user)) {
if (owner != null) {
if (!(perm.getOwner().equals(user.getName()) || manager.hasAdminPrivileges(user)))
throw new PermissionDeniedException("not allowed to change permissions");
perm.setOwner(owner);
if (!manager.hasGroup(ownerGroup))
manager.addGroup(ownerGroup);
perm.setGroup(ownerGroup);
}
perm.setPermissions(permissions);
broker.storeXMLResource(transaction, doc);
transact.commit(transaction);
broker.flush();
return true;
}
transact.abort(transaction);
throw new PermissionDeniedException("not allowed to change permissions");
}
//keep the write lock in the transaction
transaction.registerLock(collection.getLock(), Lock.WRITE_LOCK);
LOG.debug("changing permissions on collection " + uri);
Permission perm = collection.getPermissions();
if (perm.validate(user, Permission.WRITE)
|| manager.hasAdminPrivileges(user)) {
perm.setPermissions(permissions);
if (owner != null) {
if (!(perm.getOwner().equals(user.getName()) || manager.hasAdminPrivileges(user)))
throw new PermissionDeniedException("not allowed to change permissions");
perm.setOwner(owner);
if (!manager.hasGroup(ownerGroup))
manager.addGroup(ownerGroup);
perm.setGroup(ownerGroup);
}
broker.saveCollection(transaction, collection);
transact.commit(transaction);
broker.flush();
return true;
}
transact.abort(transaction);
throw new PermissionDeniedException("not allowed to change permissions");
} catch (PermissionDeniedException e) {
transact.abort(transaction);
throw new EXistException(e.getMessage());
} catch (IOException e) {
transact.abort(transaction);
throw new EXistException(e.getMessage());
} finally {
if(doc != null)
doc.getUpdateLock().release(Lock.WRITE_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>setUser</code>
*
* @param name a <code>String</code> value
* @param passwd a <code>String</code> value
* @param passwdDigest a <code>String</code> value
* @param groups a <code>Vector</code> value
* @param home a <code>String</code> value
* @return a <code>boolean</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
*/
public boolean setUser(String name, String passwd, String passwdDigest,
Vector groups, String home) throws EXistException,
PermissionDeniedException {
if (passwd.length() == 0)
passwd = null;
SecurityManager manager = factory.getBrokerPool()
.getSecurityManager();
User u;
if (!manager.hasUser(name)) {
if (!manager.hasAdminPrivileges(user))
throw new PermissionDeniedException(
"not allowed to create user");
u = new User(name);
u.setEncodedPassword(passwd);
u.setPasswordDigest(passwdDigest);
} else {
u = manager.getUser(name);
if (!(u.getName().equals(user.getName()) || manager
.hasAdminPrivileges(user)))
throw new PermissionDeniedException(
"you are not allowed to change this user");
u.setEncodedPassword(passwd);
u.setPasswordDigest(passwdDigest);
}
String g;
for (Iterator i = groups.iterator(); i.hasNext(); ) {
g = (String) i.next();
if (!u.hasGroup(g)) {
if(!manager.hasAdminPrivileges(user))
throw new PermissionDeniedException(
"User is not allowed to add groups");
u.addGroup(g);
}
}
if (home != null) {
try {
u.setHome(XmldbURI.xmldbUriFor(home));
} catch(URISyntaxException e) {
throw new EXistException("Invalid home URI",e);
}
}
manager.setUser(u);
return true;
}
/**
* Added by {Marco.Tampucci, Massimo.Martinelli} @isti.cnr.it
*/
public boolean setUser(String name, Vector groups) throws EXistException,
PermissionDeniedException {
SecurityManager manager = factory.getBrokerPool()
.getSecurityManager();
User u;
if (!manager.hasUser(name)) {
if (!manager.hasAdminPrivileges(user))
throw new PermissionDeniedException(
"not allowed to create user");
u = new User(name);
} else {
u = manager.getUser(name);
if (!(u.getName().equals(user.getName()) || manager
.hasAdminPrivileges(user)))
throw new PermissionDeniedException(
"you are not allowed to change this user");
}
String g;
for (Iterator i = groups.iterator(); i.hasNext(); ) {
g = (String) i.next();
if (!u.hasGroup(g)) {
if(!manager.hasAdminPrivileges(user))
throw new PermissionDeniedException(
"User is not allowed to add groups");
u.addGroup(g);
}
}
manager.setUser(u);
return true;
}
/**
* Added by {Marco.Tampucci, Massimo.Martinelli} @isti.cnr.it
*/
public boolean setUser(String name, Vector groups, String rgroup) throws EXistException,
PermissionDeniedException {
SecurityManager manager = factory.getBrokerPool()
.getSecurityManager();
User u;
if (!manager.hasUser(name)) {
if (!manager.hasAdminPrivileges(user))
throw new PermissionDeniedException(
"not allowed to create user");
u = new User(name);
} else {
u = manager.getUser(name);
if (!(u.getName().equals(user.getName()) || manager
.hasAdminPrivileges(user)))
throw new PermissionDeniedException(
"you are not allowed to change this user");
}
String g;
for (Iterator i = groups.iterator(); i.hasNext(); ) {
g = (String) i.next();
if (g.equals(rgroup)) {
if(!manager.hasAdminPrivileges(user))
throw new PermissionDeniedException(
"User is not allowed to remove groups");
u.remGroup(g);
}
}
manager.setUser(u);
return true;
}
/**
* The method <code>lockResource</code>
*
* @param documentPath a <code>String</code> value
* @param userName a <code>String</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
* @exception URISyntaxException if an error occurs
*/
public boolean lockResource(String documentPath, String userName) throws EXistException, PermissionDeniedException, URISyntaxException {
return lockResource(XmldbURI.xmldbUriFor(documentPath),userName);
}
/**
* The method <code>lockResource</code>
*
* @param docURI a <code>XmldbURI</code> value
* @param userName a <code>String</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
*/
private boolean lockResource(XmldbURI docURI, String userName) throws EXistException, PermissionDeniedException {
DBBroker broker = null;
DocumentImpl doc = null;
TransactionManager transact = factory.getBrokerPool().getTransactionManager();
Txn transaction = transact.beginTransaction();
try {
broker = factory.getBrokerPool().get(user);
doc = broker.getXMLResource(docURI, Lock.WRITE_LOCK);
if (doc == null) {
throw new EXistException("Resource " + docURI + " not found");
}
//TODO : register the lock within the transaction ?
if (!doc.getPermissions().validate(user, Permission.UPDATE))
throw new PermissionDeniedException("User is not allowed to lock resource " + docURI);
SecurityManager manager = factory.getBrokerPool().getSecurityManager();
if (!(userName.equals(user.getName()) || manager.hasAdminPrivileges(user)))
throw new PermissionDeniedException("User " + user.getName() + " is not allowed " +
"to lock the resource for user " + userName);
User lockOwner = doc.getUserLock();
if(lockOwner != null && (!lockOwner.equals(user)) && (!manager.hasAdminPrivileges(user)))
throw new PermissionDeniedException("Resource is already locked by user " +
lockOwner.getName());
doc.setUserLock(user);
broker.storeXMLResource(transaction, doc);
transact.commit(transaction);
return true;
} catch (Throwable e) {
transact.abort(transaction);
handleException(e);
return false;
} finally {
if(doc != null)
doc.getUpdateLock().release(Lock.WRITE_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>hasUserLock</code>
*
* @param documentPath a <code>String</code> value
* @return a <code>String</code> value
* @exception Exception if an error occurs
* @exception URISyntaxException if an error occurs
*/
public String hasUserLock(String documentPath) throws URISyntaxException, EXistException, PermissionDeniedException {
return hasUserLock(XmldbURI.xmldbUriFor(documentPath));
}
/**
* The method <code>hasUserLock</code>
*
* @param docURI a <code>XmldbURI</code> value
* @return a <code>String</code> value
* @exception Exception if an error occurs
*/
private String hasUserLock(XmldbURI docURI) throws EXistException, PermissionDeniedException {
DBBroker broker = null;
DocumentImpl doc = null;
try {
broker = factory.getBrokerPool().get(user);
doc = broker.getXMLResource(docURI, Lock.READ_LOCK);
if(!doc.getPermissions().validate(user, Permission.READ))
throw new PermissionDeniedException("Insufficient privileges to read resource");
if (doc == null)
throw new EXistException("Resource " + docURI + " not found");
User u = doc.getUserLock();
return u == null ? "" : u.getName();
} catch (Throwable e) {
handleException(e);
return null;
} finally {
if(doc != null)
doc.getUpdateLock().release(Lock.READ_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>unlockResource</code>
*
* @param documentPath a <code>String</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
* @exception URISyntaxException if an error occurs
*/
public boolean unlockResource(String documentPath) throws URISyntaxException, EXistException, PermissionDeniedException {
return unlockResource(XmldbURI.xmldbUriFor(documentPath));
}
/**
* The method <code>unlockResource</code>
*
* @param docURI a <code>XmldbURI</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
*/
private boolean unlockResource(XmldbURI docURI) throws EXistException, PermissionDeniedException {
DBBroker broker = null;
DocumentImpl doc = null;
try {
broker = factory.getBrokerPool().get(user);
doc = broker.getXMLResource(docURI, Lock.WRITE_LOCK);
if (doc == null)
throw new EXistException("Resource "
+ docURI + " not found");
if (!doc.getPermissions().validate(user, Permission.UPDATE))
throw new PermissionDeniedException("User is not allowed to lock resource " + docURI);
SecurityManager manager = factory.getBrokerPool().getSecurityManager();
User lockOwner = doc.getUserLock();
if(lockOwner != null && (!lockOwner.equals(user)) && (!manager.hasAdminPrivileges(user)))
throw new PermissionDeniedException("Resource is already locked by user " +
lockOwner.getName());
//TODO : start the transaction earlier and register the lock within it ?
TransactionManager transact = factory.getBrokerPool().getTransactionManager();
Txn transaction = transact.beginTransaction();
doc.setUserLock(null);
broker.storeXMLResource(transaction, doc);
transact.commit(transaction);
return true;
} catch (Throwable e) {
handleException(e);
return false;
} finally {
if(doc != null)
doc.getUpdateLock().release(Lock.WRITE_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>summary</code>
*
* @param xpath a <code>String</code> value
* @return a <code>HashMap</code> value
* @exception Exception if an error occurs
*/
public HashMap summary(String xpath) throws EXistException, PermissionDeniedException {
long startTime = System.currentTimeMillis();
DBBroker broker = null;
try {
broker = factory.getBrokerPool().get(user);
QueryResult qr = doQuery(broker, xpath, null, new HashMap());
if (qr == null)
return new HashMap();
if (qr.hasErrors())
throw qr.getException();
HashMap map = new HashMap();
HashMap doctypes = new HashMap();
NodeProxy p;
String docName;
DocumentType doctype;
NodeCount counter;
DoctypeCount doctypeCounter;
for (SequenceIterator i = qr.result.iterate(); i.hasNext(); ) {
Item item = i.nextItem();
if (Type.subTypeOf(item.getType(), Type.NODE)) {
NodeValue nv = (NodeValue) item;
if (nv.getImplementationType() == NodeValue.PERSISTENT_NODE) {
p = (NodeProxy) nv;
docName = p.getDocument().getURI().toString();
doctype = p.getDocument().getDoctype();
if (map.containsKey(docName)) {
counter = (NodeCount) map.get(docName);
counter.inc();
} else {
counter = new NodeCount(p.getDocument());
map.put(docName, counter);
}
if (doctype == null)
continue;
if (doctypes.containsKey(doctype.getName())) {
doctypeCounter = (DoctypeCount) doctypes.get(doctype
.getName());
doctypeCounter.inc();
} else {
doctypeCounter = new DoctypeCount(doctype);
doctypes.put(doctype.getName(), doctypeCounter);
}
}
}
}
HashMap result = new HashMap();
result.put("queryTime", new Integer((int) (System
.currentTimeMillis() - startTime)));
result.put("hits", new Integer(qr.result.getItemCount()));
Vector documents = new Vector();
Vector hitsByDoc;
for (Iterator i = map.values().iterator(); i.hasNext(); ) {
counter = (NodeCount) i.next();
hitsByDoc = new Vector();
hitsByDoc.addElement(counter.doc.getFileURI().toString());
hitsByDoc.addElement(new Integer(counter.doc.getDocId()));
hitsByDoc.addElement(new Integer(counter.count));
documents.addElement(hitsByDoc);
}
result.put("documents", documents);
Vector dtypes = new Vector();
Vector hitsByType;
DoctypeCount docTemp;
for (Iterator i = doctypes.values().iterator(); i.hasNext(); ) {
docTemp = (DoctypeCount) i.next();
hitsByType = new Vector();
hitsByType.addElement(docTemp.doctype.getName());
hitsByType.addElement(new Integer(docTemp.count));
dtypes.addElement(hitsByType);
}
result.put("doctypes", dtypes);
return result;
} catch(Throwable e) {
handleException(e);
return null;
} finally {
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>summary</code>
*
* @param resultId an <code>int</code> value
* @return a <code>HashMap</code> value
* @exception EXistException if an error occurs
* @exception XPathException if an error occurs
*/
public HashMap summary(int resultId) throws EXistException, XPathException {
QueryResult qr = factory.resultSets.getResult(resultId);
if (qr == null)
throw new EXistException("result set unknown or timed out");
qr.touch();
HashMap result = new HashMap();
result.put("queryTime", new Integer((int) qr.queryTime));
if (qr.result == null) {
result.put("hits", new Integer(0));
return result;
}
DBBroker broker = factory.getBrokerPool().get(user);
try {
HashMap map = new HashMap();
HashMap doctypes = new HashMap();
NodeProxy p;
String docName;
DocumentType doctype;
NodeCount counter;
DoctypeCount doctypeCounter;
for (SequenceIterator i = qr.result.iterate(); i.hasNext(); ) {
Item item = i.nextItem();
if (Type.subTypeOf(item.getType(), Type.NODE)) {
NodeValue nv = (NodeValue) item;
if (nv.getImplementationType() == NodeValue.PERSISTENT_NODE) {
p = (NodeProxy) nv;
docName = p.getDocument().getURI().toString();
doctype = p.getDocument().getDoctype();
if (map.containsKey(docName)) {
counter = (NodeCount) map.get(docName);
counter.inc();
} else {
counter = new NodeCount(p.getDocument());
map.put(docName, counter);
}
if (doctype == null)
continue;
if (doctypes.containsKey(doctype.getName())) {
doctypeCounter = (DoctypeCount) doctypes.get(doctype
.getName());
doctypeCounter.inc();
} else {
doctypeCounter = new DoctypeCount(doctype);
doctypes.put(doctype.getName(), doctypeCounter);
}
}
}
}
result.put("hits", new Integer(qr.result.getItemCount()));
Vector documents = new Vector();
Vector hitsByDoc;
for (Iterator i = map.values().iterator(); i.hasNext(); ) {
counter = (NodeCount) i.next();
hitsByDoc = new Vector();
hitsByDoc.addElement(counter.doc.getFileURI().toString());
hitsByDoc.addElement(new Integer(counter.doc.getDocId()));
hitsByDoc.addElement(new Integer(counter.count));
documents.addElement(hitsByDoc);
}
result.put("documents", documents);
Vector dtypes = new Vector();
Vector hitsByType;
DoctypeCount docTemp;
for (Iterator i = doctypes.values().iterator(); i.hasNext(); ) {
docTemp = (DoctypeCount) i.next();
hitsByType = new Vector();
hitsByType.addElement(docTemp.doctype.getName());
hitsByType.addElement(new Integer(docTemp.count));
dtypes.addElement(hitsByType);
}
result.put("doctypes", dtypes);
return result;
} finally {
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>getIndexedElements</code>
*
* @param collectionName a <code>String</code> value
* @param inclusive a <code>boolean</code> value
* @return a <code>Vector</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public Vector getIndexedElements(String collectionName,
boolean inclusive) throws EXistException, PermissionDeniedException, URISyntaxException {
return getIndexedElements(XmldbURI.xmldbUriFor(collectionName),inclusive);
}
/**
* The method <code>getIndexedElements</code>
*
* @param collUri a <code>XmldbURI</code> value
* @param inclusive a <code>boolean</code> value
* @return a <code>Vector</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
*/
private Vector getIndexedElements(XmldbURI collUri,
boolean inclusive) throws EXistException, PermissionDeniedException {
DBBroker broker = null;
Collection collection = null;
try {
broker = factory.getBrokerPool().get(user);
collection = broker.openCollection(collUri, Lock.READ_LOCK);
if (collection == null)
throw new EXistException("collection " + collUri + " not found");
Occurrences occurrences[] = broker.getElementIndex().scanIndexedElements(collection,
inclusive);
Vector result = new Vector(occurrences.length);
for (int i = 0; i < occurrences.length; i++) {
QName qname = (QName)occurrences[i].getTerm();
Vector temp = new Vector(4);
temp.addElement(qname.getLocalName());
temp.addElement(qname.getNamespaceURI());
temp.addElement(qname.getPrefix() == null ? "" : qname.getPrefix());
temp.addElement(new Integer(occurrences[i].getOccurrences()));
result.addElement(temp);
}
return result;
} finally {
if(collection != null)
collection.release(Lock.READ_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>scanIndexTerms</code>
*
* @param collectionName a <code>String</code> value
* @param start a <code>String</code> value
* @param end a <code>String</code> value
* @param inclusive a <code>boolean</code> value
* @return a <code>Vector</code> value
* @exception PermissionDeniedException if an error occurs
* @exception EXistException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public Vector scanIndexTerms(String collectionName,
String start, String end, boolean inclusive)
throws PermissionDeniedException, EXistException, URISyntaxException {
return scanIndexTerms(XmldbURI.xmldbUriFor(collectionName),start,end,inclusive);
}
/**
* The method <code>scanIndexTerms</code>
*
* @param collUri a <code>XmldbURI</code> value
* @param start a <code>String</code> value
* @param end a <code>String</code> value
* @param inclusive a <code>boolean</code> value
* @return a <code>Vector</code> value
* @exception PermissionDeniedException if an error occurs
* @exception EXistException if an error occurs
*/
private Vector scanIndexTerms(XmldbURI collUri,
String start, String end, boolean inclusive)
throws PermissionDeniedException, EXistException {
DBBroker broker = null;
Collection collection = null;
try {
broker = factory.getBrokerPool().get(user);
collection = broker.openCollection(collUri, Lock.READ_LOCK);
if (collection == null)
throw new EXistException("collection " + collUri + " not found");
MutableDocumentSet docs = new DefaultDocumentSet();
collection.allDocs(broker, docs, inclusive, true);
NodeSet nodes = docs.docsToNodeSet();
Vector result = scanIndexTerms(start, end, broker, docs, nodes);
return result;
} finally {
if(collection != null)
collection.release(Lock.READ_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>scanIndexTerms</code>
*
* @param xpath a <code>String</code> value
* @param start a <code>String</code> value
* @param end a <code>String</code> value
* @return a <code>Vector</code> value
* @exception PermissionDeniedException if an error occurs
* @exception EXistException if an error occurs
* @exception XPathException if an error occurs
*/
public Vector scanIndexTerms(String xpath,
String start, String end)
throws PermissionDeniedException, EXistException, XPathException {
DBBroker broker = null;
try {
broker = factory.getBrokerPool().get(user);
XQuery xquery = broker.getXQueryService();
Sequence nodes = xquery.execute(xpath, null, AccessContext.XMLRPC);
Vector result = scanIndexTerms(start, end, broker, nodes.getDocumentSet(), nodes.toNodeSet());
return result;
} finally {
factory.getBrokerPool().release(broker);
}
}
/**
* @param start
* @param end
* @param broker
* @param docs
* @return
* @throws PermissionDeniedException
*/
private Vector scanIndexTerms(String start, String end, DBBroker broker, DocumentSet docs, NodeSet nodes)
throws PermissionDeniedException, EXistException {
TextSearchEngine engine = broker.getTextEngine();
if(engine==null){
throw new EXistException("The legacy fulltext indexing has been disabled "
+ "by default from version 1.4.1. Please consider migrating to the "
+ "new full text indexing.");
}
Occurrences occurrences[] = engine.scanIndexTerms(docs, nodes, start, end);
Vector result = new Vector(occurrences.length);
Vector temp;
for (int i = 0; i < occurrences.length; i++) {
temp = new Vector(2);
temp.addElement(occurrences[i].getTerm().toString());
temp.addElement(new Integer(occurrences[i].getOccurrences()));
result.addElement(temp);
}
return result;
}
/**
* The method <code>synchronize</code>
*
*/
public void synchronize() {
}
/**
* The method <code>getProperties</code>
*
* @param parameters a <code>HashMap</code> value
* @return a <code>Properties</code> value
*/
private Properties getProperties(HashMap parameters) {
Properties properties = new Properties();
for (Iterator i = parameters.entrySet().iterator(); i.hasNext(); ) {
Map.Entry entry = (Map.Entry) i.next();
properties.setProperty((String) entry.getKey(), entry.getValue().toString());
}
return properties;
}
/**
* The class <code>CachedQuery</code>
*
*/
class CachedQuery {
PathExpr expression;
String queryString;
long timestamp;
public CachedQuery(PathExpr expr, String query) {
this.expression = expr;
this.queryString = query;
this.timestamp = System.currentTimeMillis();
}
}
/**
* The class <code>DoctypeCount</code>
*
*/
class DoctypeCount {
int count = 1;
DocumentType doctype;
/**
* Constructor for the DoctypeCount object
*
* @param doctype
* Description of the Parameter
*/
public DoctypeCount(DocumentType doctype) {
this.doctype = doctype;
}
public void inc() {
count++;
}
}
/**
* The class <code>NodeCount</code>
*
*/
class NodeCount {
int count = 1;
DocumentImpl doc;
/**
* Constructor for the NodeCount object
*
* @param doc
* Description of the Parameter
*/
public NodeCount(DocumentImpl doc) {
this.doc = doc;
}
public void inc() {
count++;
}
}
// FIXME: Check it for possible security hole. Check name.
public byte[] getDocumentChunk(String name, int start, int len)
throws EXistException, PermissionDeniedException, IOException {
File file = new File(System.getProperty("java.io.tmpdir")
+ File.separator + name);
if (!file.canRead())
throw new EXistException("unable to read file " + name);
if (file.length() < start+len)
throw new EXistException("address too big " + name);
byte buffer[] = new byte[len];
RandomAccessFile os = new RandomAccessFile(file.getAbsolutePath(), "r");
LOG.debug("Read from: " + start + " to: " + (start + len));
os.seek(start);
os.read(buffer);
os.close();
return buffer;
}
/**
* The method <code>moveOrCopyResource</code>
*
* @param documentPath a <code>String</code> value
* @param destinationPath a <code>String</code> value
* @param newName a <code>String</code> value
* @param move a <code>boolean</code> value
* @return a <code>boolean</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public boolean moveOrCopyResource(String documentPath, String destinationPath,
String newName, boolean move)
throws EXistException, PermissionDeniedException, URISyntaxException {
return moveOrCopyResource(XmldbURI.xmldbUriFor(documentPath),
XmldbURI.xmldbUriFor(destinationPath),XmldbURI.xmldbUriFor(newName),move);
}
/**
* The method <code>moveOrCopyResource</code>
*
* @param docUri a <code>XmldbURI</code> value
* @param destUri a <code>XmldbURI</code> value
* @param newName a <code>XmldbURI</code> value
* @param move a <code>boolean</code> value
* @return a <code>boolean</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
*/
private boolean moveOrCopyResource(XmldbURI docUri, XmldbURI destUri,
XmldbURI newName, boolean move)
throws EXistException, PermissionDeniedException {
TransactionManager transact = factory.getBrokerPool().getTransactionManager();
Txn transaction = transact.beginTransaction();
DBBroker broker = null;
Collection collection = null;
Collection destination = null;
DocumentImpl doc = null;
try {
//TODO : use transaction.registerLock(collection.getLock(), Lock.WRITE_LOCK);
broker = factory.getBrokerPool().get(user);
collection = broker.openCollection(docUri.removeLastSegment(), move ? Lock.WRITE_LOCK : Lock.READ_LOCK);
if (collection == null) {
transact.abort(transaction);
throw new EXistException("Collection " + docUri.removeLastSegment() + " not found");
}
doc = collection.getDocumentWithLock(broker, docUri.lastSegment(), Lock.WRITE_LOCK);
if(doc == null) {
transact.abort(transaction);
throw new EXistException("Document " + docUri + " not found");
}
//TODO : register the lock within the transaction ?
// get destination collection
destination = broker.openCollection(destUri, Lock.WRITE_LOCK);
if(destination == null) {
transact.abort(transaction);
throw new EXistException("Destination collection " + destUri + " not found");
}
if(move)
broker.moveResource(transaction, doc, destination, newName);
else
broker.copyResource(transaction, doc, destination, newName);
transact.commit(transaction);
return true;
} catch (LockException e) {
transact.abort(transaction);
throw new PermissionDeniedException("Could not acquire lock on document " + docUri);
} catch (IOException e) {
transact.abort(transaction);
throw new EXistException("Could not acquire lock on document " + docUri);
} finally {
if(doc != null)
doc.getUpdateLock().release(Lock.WRITE_LOCK);
if(collection != null)
collection.release(move ? Lock.WRITE_LOCK : Lock.READ_LOCK);
if(destination != null)
destination.release(Lock.WRITE_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>moveOrCopyCollection</code>
*
* @param collectionName a <code>String</code> value
* @param destinationPath a <code>String</code> value
* @param newName a <code>String</code> value
* @param move a <code>boolean</code> value
* @return a <code>boolean</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public boolean moveOrCopyCollection(String collectionName, String destinationPath,
String newName, boolean move)
throws EXistException, PermissionDeniedException, URISyntaxException {
return moveOrCopyCollection(XmldbURI.xmldbUriFor(collectionName),
XmldbURI.xmldbUriFor(destinationPath),XmldbURI.xmldbUriFor(newName),move);
}
/**
* The method <code>moveOrCopyCollection</code>
*
* @param collUri a <code>XmldbURI</code> value
* @param destUri a <code>XmldbURI</code> value
* @param newName a <code>XmldbURI</code> value
* @param move a <code>boolean</code> value
* @return a <code>boolean</code> value
* @exception EXistException if an error occurs
* @exception PermissionDeniedException if an error occurs
*/
private boolean moveOrCopyCollection(XmldbURI collUri, XmldbURI destUri,
XmldbURI newName, boolean move)
throws EXistException, PermissionDeniedException {
TransactionManager transact = factory.getBrokerPool().getTransactionManager();
Txn transaction = transact.beginTransaction();
DBBroker broker = null;
Collection collection = null;
Collection destination = null;
try {
broker = factory.getBrokerPool().get(user);
// get source document
//TODO : use transaction.registerLock(collection.getLock(), Lock.WRITE_LOCK);
collection = broker.openCollection(collUri, move ? Lock.WRITE_LOCK : Lock.READ_LOCK);
if (collection == null) {
transact.abort(transaction);
throw new EXistException("Collection " + collUri + " not found");
}
// get destination collection
destination = broker.openCollection(destUri, Lock.WRITE_LOCK);
if(destination == null) {
transact.abort(transaction);
throw new EXistException("Destination collection " + destUri + " not found");
}
if(move)
broker.moveCollection(transaction, collection, destination, newName);
else
broker.copyCollection(transaction, collection, destination, newName);
transact.commit(transaction);
return true;
} catch (LockException e) {
transact.abort(transaction);
throw new PermissionDeniedException(e.getMessage());
} catch (IOException e) {
transact.abort(transaction);
throw new EXistException(e.getMessage());
} finally {
if(collection != null)
collection.release(move ? Lock.WRITE_LOCK : Lock.READ_LOCK);
if(destination != null)
destination.release(Lock.WRITE_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>reindexCollection</code>
*
* @param collectionName a <code>String</code> value
* @exception Exception if an error occurs
* @exception PermissionDeniedException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public boolean reindexCollection(String collectionName) throws URISyntaxException, EXistException, PermissionDeniedException {
reindexCollection(XmldbURI.xmldbUriFor(collectionName));
return true;
}
/**
* The method <code>reindexCollection</code>
*
* @param collUri a <code>XmldbURI</code> value
* @exception Exception if an error occurs
* @exception PermissionDeniedException if an error occurs
*/
private void reindexCollection(XmldbURI collUri) throws EXistException, PermissionDeniedException {
DBBroker broker = null;
try {
broker = factory.getBrokerPool().get(user);
broker.reindexCollection(collUri);
LOG.debug("collection " + collUri + " and sub collection reindexed");
} catch (Throwable e) {
handleException(e);
} finally {
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>backup</code>
*
* @param userbackup a <code>String</code> value
* @param password a <code>String</code> value
* @param destcollection a <code>String</code> value
* @param collection a <code>String</code> value
* @exception Exception if an error occurs
* @exception PermissionDeniedException if an error occurs
*/
public boolean backup(String userbackup, String password,
String destcollection, String collection) throws EXistException, PermissionDeniedException {
try {
Backup backup = new Backup(
userbackup,
password,
destcollection+"-backup",
XmldbURI.xmldbUriFor(XmldbURI.EMBEDDED_SERVER_URI.toString() + collection));
backup.backup(false, null);
} catch (Throwable e) {
handleException(e);
}
return true;
}
/**
* Validate if specified document is Valid.
*
* @param documentPath Path to XML document in database
* @throws java.lang.Exception Generic exception
* @throws PermissionDeniedException User is not allowed to perform action.
* @return TRUE if document is valid, FALSE if not or errors or.....
*/
public boolean isValid(String documentPath)
throws PermissionDeniedException, URISyntaxException, EXistException {
return isValid(XmldbURI.xmldbUriFor(documentPath));
}
/**
* The method <code>isValid</code>
*
* @param docUri a <code>XmldbURI</code> value
* @return a <code>boolean</code> value
* @exception PermissionDeniedException if an error occurs
* @exception Exception if an error occurs
*/
private boolean isValid(XmldbURI docUri) throws EXistException, PermissionDeniedException {
boolean isValid=false;
try {
// Setup validator
Validator validator = new Validator(factory.getBrokerPool());
// Get inputstream
// TODO DWES reconsider
InputStream is = new EmbeddedInputStream( new XmldbURL(docUri) );
// Perform validation
ValidationReport report = validator.validate(is);
// Return validation result
isValid = report.isValid();
} catch (Throwable e) {
handleException(e);
return false;
}
return isValid;
}
/**
* The method <code>getDocType</code>
*
* @param documentPath a <code>String</code> value
* @return a <code>Vector</code> value
* @exception PermissionDeniedException if an error occurs
* @exception EXistException if an error occurs
* @exception URISyntaxException if an error occurs
*/
public Vector getDocType(String documentPath)
throws PermissionDeniedException, EXistException, URISyntaxException {
return getDocType(XmldbURI.xmldbUriFor(documentPath));
}
/**
* The method <code>getDocType</code>
*
* @param docUri a <code>XmldbURI</code> value
* @return a <code>Vector</code> value
* @exception PermissionDeniedException if an error occurs
* @exception EXistException if an error occurs
*/
private Vector getDocType(XmldbURI docUri)
throws PermissionDeniedException, EXistException {
DBBroker broker = null;
DocumentImpl doc = null;
try {
broker = factory.getBrokerPool().get(user);
doc = broker.getXMLResource(docUri, Lock.READ_LOCK);
if (doc == null) {
LOG.debug("document " + docUri + " not found!");
throw new EXistException("document not found");
}
Vector vector = new Vector(3);
if (doc.getDoctype() != null)
{
vector.addElement(doc.getDoctype().getName());
if (doc.getDoctype().getPublicId() != null) {
vector.addElement(doc.getDoctype().getPublicId());
} else {
vector.addElement("");
}
if (doc.getDoctype().getSystemId() != null) {
vector.addElement(doc.getDoctype().getSystemId());
} else {
vector.addElement("");
}
} else
{
vector.addElement("");
vector.addElement("");
vector.addElement("");
}
return vector;
} finally {
if(doc != null)
doc.getUpdateLock().release(Lock.READ_LOCK);
factory.getBrokerPool().release(broker);
}
}
/**
* The method <code>setDocType</code>
*
* @param documentPath a <code>String</code> value
* @param doctypename a <code>String</code> value
* @param publicid a <code>String</code> value
* @param systemid a <code>String</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
* @exception URISyntaxException if an error occurs
*/
public boolean setDocType(String documentPath, String doctypename, String publicid, String systemid) throws
URISyntaxException, EXistException, PermissionDeniedException {
return setDocType(XmldbURI.xmldbUriFor(documentPath),doctypename, publicid, systemid);
}
/**
* The method <code>setDocType</code>
*
* @param docUri a <code>XmldbURI</code> value
* @param doctypename a <code>String</code> value
* @param publicid a <code>String</code> value
* @param systemid a <code>String</code> value
* @return a <code>boolean</code> value
* @exception Exception if an error occurs
*/
private boolean setDocType(XmldbURI docUri, String doctypename, String publicid, String systemid) throws EXistException, PermissionDeniedException {
DBBroker broker = null;
DocumentImpl doc = null;
DocumentType result = null;
TransactionManager transact = factory.getBrokerPool().getTransactionManager();
Txn transaction = transact.beginTransaction();
try {
broker = factory.getBrokerPool().get(user);
doc = broker.getXMLResource(docUri, Lock.WRITE_LOCK);
if (doc == null) {
transact.abort(transaction);
throw new EXistException("Resource " + docUri + " not found");
}
//TODO : register the lock within the transaction ?
if (!doc.getPermissions().validate(user, Permission.UPDATE)) {
transact.abort(transaction);
throw new PermissionDeniedException("User is not allowed to lock resource " + docUri);
}
if (!"".equals(doctypename)) {
result = new DocumentTypeImpl(doctypename,
"".equals(publicid) ? null : publicid,
"".equals(systemid) ? null : systemid );
}
doc.setDocumentType(result);
broker.storeXMLResource(transaction, doc);
transact.commit(transaction);
return true;
} catch (Throwable e) {
transact.abort(transaction);
handleException(e);
return false;
} finally {
if(doc != null)
doc.getUpdateLock().release(Lock.WRITE_LOCK);
factory.getBrokerPool().release(broker);
}
}
public boolean copyResource(String docPath, String destinationPath, String newName) throws EXistException, PermissionDeniedException, URISyntaxException {
return moveOrCopyResource(docPath, destinationPath, newName, false);
}
public boolean copyCollection(String collectionPath, String destinationPath, String newName) throws EXistException, PermissionDeniedException, URISyntaxException {
return moveOrCopyCollection(collectionPath, destinationPath, newName, false);
}
public boolean moveResource(String docPath, String destinationPath, String newName) throws EXistException, PermissionDeniedException, URISyntaxException {
return moveOrCopyResource(docPath, destinationPath, newName, true);
}
public boolean moveCollection(String collectionPath, String destinationPath, String newName) throws EXistException, PermissionDeniedException, URISyntaxException {
return moveOrCopyCollection(collectionPath, destinationPath, newName, true);
}
public List getDocumentChunk(String name, HashMap parameters) throws EXistException, PermissionDeniedException, IOException {
List result = new ArrayList(2);
File file;
file = File.createTempFile("rpc", ".xml");
file.deleteOnExit();
FileOutputStream os = new FileOutputStream(file.getAbsolutePath(), true);
os.write(getDocument(name, parameters));
os.close();
result.add(file.getName());
result.add(Long.toString(file.length()));
return result;
}
public boolean copyCollection(String name, String namedest) throws PermissionDeniedException, EXistException {
try {
createCollection(namedest);
HashMap parametri = new HashMap();
parametri.put(OutputKeys.INDENT, "no");
parametri.put(EXistOutputKeys.EXPAND_XINCLUDES, "no");
parametri.put(OutputKeys.ENCODING, DEFAULT_ENCODING);
HashMap lista = getCollectionDesc(name);
Object[] collezioni = (Object[]) lista.get("collections");
Object[] documents = (Object[]) lista.get("documents");
//ricrea le directory
String nome;
for (int i = 0; i < collezioni.length; i++) {
nome = collezioni[i].toString();
createCollection(namedest + "/" + nome);
copyCollection(name + "/" + nome, namedest + "/" + nome);
}
//Copy i file
HashMap hash;
int p, dsize = documents.length;
for (int i = 0; i < dsize; i++) {
hash = (HashMap<String, Object>) documents[i];
nome = (String) hash.get("name");
//TODO : use dedicated function in XmldbURI
if ((p = nome.lastIndexOf("/")) != Constants.STRING_NOT_FOUND)
nome = nome.substring(p + 1);
byte[] xml = getDocument(name + "/" + nome, parametri);
parse(xml, namedest + "/" + nome);
}
return true;
} catch (Throwable e) {
handleException(e);
return false;
}
}
public int xupdateResource(String resource, byte[] xupdate) throws PermissionDeniedException, EXistException, SAXException {
return xupdateResource(resource, xupdate, DEFAULT_ENCODING);
}
public boolean setPermissions(String resource, int permissions) throws EXistException, PermissionDeniedException, URISyntaxException {
return setPermissions(resource, null, null, permissions);
}
public boolean setPermissions(String resource, String permissions) throws EXistException, PermissionDeniedException, URISyntaxException {
return setPermissions(resource, null, null, permissions);
}
public boolean setUser(String name, String passwd, String digestPassword, Vector groups) throws EXistException, PermissionDeniedException {
return setUser(name, passwd, digestPassword,groups, null);
}
public HashMap querySummary(int resultId) throws EXistException, PermissionDeniedException, XPathException {
return summary(resultId);
}
public int executeQuery(byte[] xpath, HashMap parameters) throws EXistException, PermissionDeniedException {
return executeQuery(xpath, null, parameters);
}
public boolean storeBinary(byte[] data, String docName, String mimeType, boolean replace, Date created, Date modified) throws EXistException, PermissionDeniedException, URISyntaxException {
return storeBinary(data, docName, mimeType, replace ? 1 : 0, created, modified);
}
public boolean storeBinary(byte[] data, String docName, String mimeType, boolean replace) throws EXistException, PermissionDeniedException, URISyntaxException {
return storeBinary(data, docName, mimeType, replace ? 1 : 0, null, null);
}
public boolean parseLocalExt(String localFile, String docName, boolean replace, String mimeType, boolean treatAsXML, Date created, Date modified) throws EXistException, PermissionDeniedException, SAXException, URISyntaxException {
return parseLocalExt(localFile, docName, replace ? 1 : 0, mimeType, treatAsXML ? 1 : 0, created, modified);
}
public boolean parseLocal(String localFile, String docName, boolean replace, String mimeType, Date created, Date modified) throws EXistException, PermissionDeniedException, SAXException, URISyntaxException {
return parseLocal(localFile, docName, replace ? 1 : 0, mimeType, created, modified);
}
public boolean parseLocalExt(String localFile, String docName, boolean replace, String mimeType, boolean treatAsXML) throws EXistException, PermissionDeniedException, SAXException, URISyntaxException {
return parseLocalExt(localFile, docName, replace ? 1 : 0, mimeType, treatAsXML ? 1 : 0, null, null);
}
public boolean parseLocal(String localFile, String docName, boolean replace, String mimeType) throws EXistException, PermissionDeniedException, SAXException, URISyntaxException {
return parseLocal(localFile, docName, replace ? 1 : 0, mimeType, null, null);
}
public String uploadCompressed(String file, byte[] data, int length) throws EXistException, PermissionDeniedException, IOException {
return upload(data, length, file, true);
}
public String uploadCompressed(byte[] data, int length) throws EXistException, PermissionDeniedException, IOException {
return upload(data, length, null, true);
}
public String upload(String file, byte[] chunk, int length) throws EXistException, PermissionDeniedException, IOException {
return upload(chunk, length, file, false);
}
public String upload(byte[] chunk, int length) throws EXistException, PermissionDeniedException, IOException {
return upload(chunk, length, null, false);
}
public boolean parse(String xml, String docName) throws EXistException, PermissionDeniedException, URISyntaxException {
try {
return parse(xml.getBytes(DEFAULT_ENCODING), docName, 0);
} catch (UnsupportedEncodingException e) {
handleException(e);
return false;
}
}
public boolean parse(String xml, String docName, int overwrite) throws EXistException, PermissionDeniedException, URISyntaxException {
try {
return parse(xml.getBytes(DEFAULT_ENCODING), docName, overwrite);
} catch (UnsupportedEncodingException e) {
handleException(e);
return false;
}
}
public boolean parse(byte[] xmlData, String docName) throws EXistException, PermissionDeniedException, URISyntaxException {
return parse(xmlData, docName, 0);
}
/** @deprecated Use XmldbURI version instead */
public HashMap querySummary(String xquery) throws EXistException, PermissionDeniedException {
return summary(xquery);
}
/** @deprecated Use XmldbURI version instead */
public byte[] query(byte[] xquery, int howmany, int start, HashMap parameters) throws EXistException, PermissionDeniedException {
try {
String result = query(new String(xquery, DEFAULT_ENCODING), howmany, start, parameters);
return result.getBytes(DEFAULT_ENCODING);
} catch (UnsupportedEncodingException e) {
handleException(e);
return null;
}
}
public HashMap queryP(byte[] xpath, String docName, String s_id, HashMap parameters) throws EXistException, PermissionDeniedException, URISyntaxException {
try {
return queryP(new String(xpath, DEFAULT_ENCODING), docName, s_id, parameters);
} catch (UnsupportedEncodingException e) {
handleException(e);
return null;
}
}
public HashMap queryP(byte[] xpath, HashMap parameters) throws EXistException, PermissionDeniedException {
try {
return queryP(new String(xpath, DEFAULT_ENCODING), (XmldbURI) null, null, parameters);
} catch (UnsupportedEncodingException e) {
handleException(e);
return null;
}
}
public HashMap compile(byte[] xquery, HashMap parameters) throws EXistException, PermissionDeniedException {
try {
return compile(new String(xquery, DEFAULT_ENCODING), parameters);
} catch (UnsupportedEncodingException e) {
handleException(e);
return null;
}
}
public byte[] retrieve(String doc, String id) throws EXistException, PermissionDeniedException {
return retrieve(doc, id, null);
}
public String getDocumentAsString(String name, int prettyPrint, String stylesheet) throws EXistException, PermissionDeniedException {
HashMap parametri = new HashMap();
if (prettyPrint > 0) {
parametri.put(OutputKeys.INDENT, "yes");
} else {
parametri.put(OutputKeys.INDENT, "no");
}
if (stylesheet != null) {
parametri.put(EXistOutputKeys.STYLESHEET, stylesheet);
}
return getDocumentAsString(name, parametri);
}
public String getDocumentAsString(String name, int prettyPrint) throws EXistException, PermissionDeniedException {
return getDocumentAsString(name, prettyPrint, null);
}
public byte[] getDocument(String name, String encoding, int prettyPrint, String stylesheet) throws EXistException, PermissionDeniedException {
HashMap parametri = new HashMap();
if (prettyPrint > 0) {
parametri.put(OutputKeys.INDENT, "yes");
} else {
parametri.put(OutputKeys.INDENT, "no");
}
if (stylesheet != null) {
parametri.put(EXistOutputKeys.STYLESHEET, stylesheet);
}
parametri.put(OutputKeys.ENCODING, encoding);
//String xml = con.getDocument(user, name, (prettyPrint > 0),
// encoding, stylesheet);
byte[] xml = getDocument(name, parametri);
if (xml == null)
throw new EXistException("document " + name + " not found!");
return xml;
}
public byte[] getDocument(String name, String encoding, int prettyPrint) throws EXistException, PermissionDeniedException {
return getDocument(name, encoding, prettyPrint, null);
}
public boolean shutdown() throws PermissionDeniedException {
return shutdown(0);
}
public boolean shutdown(long delay) throws PermissionDeniedException {
if (!user.hasDbaRole())
throw new PermissionDeniedException("not allowed to shut down" + "the database");
if (delay > 0) {
TimerTask task = new TimerTask() {
public void run() {
try {
BrokerPool.stop();
} catch (EXistException e) {
LOG.warn("shutdown failed", e);
}
}
};
Timer timer = new Timer();
timer.schedule(task, delay);
} else {
try {
BrokerPool.stop();
} catch (EXistException e) {
LOG.warn("shutdown failed", e);
return false;
}
}
return true;
}
public boolean enterServiceMode() throws PermissionDeniedException, EXistException {
BrokerPool brokerPool = factory.getBrokerPool();
brokerPool.enterServiceMode(user);
return true;
}
public void exitServiceMode() throws PermissionDeniedException, EXistException {
BrokerPool brokerPool = factory.getBrokerPool();
brokerPool.exitServiceMode(user);
}
}