package org.exist.soap;
import org.apache.log4j.Logger;
import org.exist.EXistException;
import org.exist.collections.Collection;
import org.exist.collections.IndexInfo;
import org.exist.dom.BinaryDocument;
import org.exist.dom.DefaultDocumentSet;
import org.exist.dom.DocumentImpl;
import org.exist.dom.DocumentSet;
import org.exist.dom.MutableDocumentSet;
import org.exist.dom.QName;
import org.exist.security.Permission;
import org.exist.security.PermissionDeniedException;
import org.exist.security.User;
import org.exist.security.xacml.AccessContext;
import org.exist.storage.BrokerPool;
import org.exist.storage.DBBroker;
import org.exist.storage.lock.Lock;
import org.exist.storage.sync.Sync;
import org.exist.storage.txn.TransactionException;
import org.exist.storage.txn.TransactionManager;
import org.exist.storage.txn.Txn;
import org.exist.util.LockException;
import org.exist.util.MimeType;
import org.exist.util.Occurrences;
import org.exist.xmldb.XmldbURI;
import org.exist.xquery.XPathException;
import org.exist.xupdate.Modification;
import org.exist.xupdate.XUpdateProcessor;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import javax.xml.parsers.ParserConfigurationException;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.StringReader;
import java.net.URISyntaxException;
import java.rmi.RemoteException;
import java.util.Iterator;
import java.util.Vector;
/**
* Provides the actual implementations for the methods defined in
* {@link org.exist.soap.Admin}.
*
*@author Wolfgang Meier <wolfgang@exist-db.org>
*/
public class AdminSoapBindingImpl implements org.exist.soap.Admin {
private static Logger LOG = Logger.getLogger(Admin.class.getName());
private BrokerPool pool;
/** Constructor for the AdminSoapBindingImpl object */
public AdminSoapBindingImpl() {
try {
pool = BrokerPool.getInstance();
} catch (Exception e) {
throw new RuntimeException("failed to initialize broker pool");
}
}
public java.lang.String connect(java.lang.String userId, java.lang.String password) throws java.rmi.RemoteException {
User u = pool.getSecurityManager().getUser(userId);
if (u == null)
throw new RemoteException("user " + userId + " does not exist");
if (!u.validate(password))
throw new RemoteException("the supplied password is invalid");
LOG.debug("user " + userId + " connected");
return SessionManager.getInstance().createSession(u);
}
public void disconnect(java.lang.String sessionId) throws java.rmi.RemoteException {
SessionManager manager = SessionManager.getInstance();
Session session = manager.getSession(sessionId);
if (session != null) {
LOG.debug("disconnecting session " + sessionId);
manager.disconnect(sessionId);
}
}
public boolean createCollection(java.lang.String sessionId, java.lang.String path) throws java.rmi.RemoteException {
try {
return createCollection(sessionId,XmldbURI.xmldbUriFor(path));
} catch(URISyntaxException e) {
throw new RemoteException("Invalid collection URI",e);
}
}
public boolean createCollection(java.lang.String sessionId, XmldbURI path) throws java.rmi.RemoteException {
Session session = getSession(sessionId);
DBBroker broker = null;
TransactionManager transact = pool.getTransactionManager();
Txn txn = transact.beginTransaction();
try {
broker = pool.get(session.getUser());
LOG.debug("creating collection " + path);
org.exist.collections.Collection coll =
broker.getOrCreateCollection(txn, path);
if (coll == null) {
LOG.debug("failed to create collection");
return false;
}
broker.saveCollection(txn, coll);
transact.commit(txn);
broker.flush();
broker.sync(Sync.MINOR_SYNC);
return true;
} catch (Exception e) {
transact.abort(txn);
LOG.debug(e.getMessage(), e);
throw new RemoteException(e.getMessage());
} finally {
pool.release(broker);
}
}
public boolean removeCollection(java.lang.String sessionId, java.lang.String path) throws java.rmi.RemoteException {
try {
return removeCollection(sessionId,XmldbURI.xmldbUriFor(path));
} catch(URISyntaxException e) {
throw new RemoteException("Invalid collection URI",e);
}
}
public boolean removeCollection(java.lang.String sessionId, XmldbURI path) throws java.rmi.RemoteException {
Session session = getSession(sessionId);
DBBroker broker = null;
TransactionManager transact = pool.getTransactionManager();
Txn txn = transact.beginTransaction();
try {
broker = pool.get(session.getUser());
Collection collection = broker.getCollection(path);
if(collection == null) {
transact.abort(txn);
return false;
}
boolean removed = broker.removeCollection(txn, collection);
transact.commit(txn);
return removed;
} catch (Exception e) {
transact.abort(txn);
LOG.debug(e.getMessage(), e);
throw new RemoteException(e.getMessage(), e);
} finally {
pool.release(broker);
}
}
public boolean removeDocument(java.lang.String sessionId, java.lang.String path) throws java.rmi.RemoteException {
try {
return removeDocument(sessionId,XmldbURI.xmldbUriFor(path));
} catch(URISyntaxException e) {
throw new RemoteException("Invalid document URI",e);
}
}
public boolean removeDocument(java.lang.String sessionId, XmldbURI path) throws java.rmi.RemoteException {
Session session = getSession(sessionId);
DBBroker broker = null;
TransactionManager transact = pool.getTransactionManager();
Txn txn = transact.beginTransaction();
try {
broker = pool.get(session.getUser());
XmldbURI collectionUri = path.removeLastSegment();
XmldbURI docUri = path.lastSegment();
if (collectionUri==null || docUri==null) {
transact.abort(txn);
throw new EXistException("Illegal document path");
}
Collection collection = broker.getCollection(collectionUri);
if (collection == null) {
transact.abort(txn);
throw new EXistException(
"Collection " + collectionUri + " not found");
}
DocumentImpl doc = collection.getDocument(broker, docUri);
if(doc == null)
throw new EXistException("Document " + docUri + " not found");
if(doc.getResourceType() == DocumentImpl.BINARY_FILE)
collection.removeBinaryResource(txn, broker, doc);
else
collection.removeXMLResource(txn, broker, docUri);
transact.commit(txn);
return true;
} catch (Exception e) {
transact.abort(txn);
LOG.debug(e.getMessage(), e);
throw new RemoteException(e.getMessage(), e);
} finally {
pool.release(broker);
}
}
public void store(java.lang.String sessionId, byte[] data, java.lang.String encoding, java.lang.String path, boolean replace) throws java.rmi.RemoteException {
try {
store(sessionId,data,encoding,XmldbURI.xmldbUriFor(path),replace);
} catch(URISyntaxException e) {
throw new RemoteException("Invalid document URI",e);
}
}
public void store(java.lang.String sessionId, byte[] data, java.lang.String encoding, XmldbURI path, boolean replace) throws java.rmi.RemoteException {
Session session = getSession(sessionId);
DBBroker broker = null;
TransactionManager transact = pool.getTransactionManager();
Txn txn = transact.beginTransaction();
try {
broker = pool.get(session.getUser());
XmldbURI collectionUri = path.removeLastSegment();
XmldbURI docUri = path.lastSegment();
if (collectionUri==null || docUri==null) {
transact.abort(txn);
throw new EXistException("Illegal document path");
}
Collection collection = broker.getCollection(collectionUri);
if (collection == null) {
transact.abort(txn);
throw new EXistException("Collection " + collectionUri + " not found");
}
if(!replace) {
DocumentImpl old = collection.getDocument(broker, docUri);
if(old != null) {
transact.abort(txn);
throw new RemoteException("Document exists and overwrite is not allowed");
}
}
long startTime = System.currentTimeMillis();
// TODO check XML/Binary resource
// IndexInfo info = collection.validate(txn, broker, path, new InputSource(new ByteArrayInputStream(data)));
IndexInfo info = collection.validateXMLResource(txn, broker, docUri, new InputSource(new ByteArrayInputStream(data)));
info.getDocument().getMetadata().setMimeType(MimeType.XML_TYPE.getName());
collection.store(txn, broker, info, new InputSource(new ByteArrayInputStream(data)), false);
transact.commit(txn);
LOG.debug(
"parsing "
+ path
+ " took "
+ (System.currentTimeMillis() - startTime)
+ "ms.");
} catch (Exception e) {
transact.abort(txn);
LOG.debug(e.getMessage(), e);
throw new RemoteException(e.getMessage(), e);
} finally {
pool.release(broker);
}
}
private Session getSession(String id) throws java.rmi.RemoteException {
Session session = SessionManager.getInstance().getSession(id);
if (session == null)
throw new java.rmi.RemoteException(
"Session is invalid or timed out");
return session;
}
public int xupdate(java.lang.String sessionId, java.lang.String collectionName, java.lang.String xupdate) throws java.rmi.RemoteException {
try {
return xupdate(sessionId,XmldbURI.xmldbUriFor(collectionName), xupdate);
} catch(URISyntaxException e) {
throw new RemoteException("Invalid collection URI",e);
}
}
public int xupdate(java.lang.String sessionId, XmldbURI collectionName, java.lang.String xupdate) throws java.rmi.RemoteException {
DBBroker broker = null;
Session session = getSession(sessionId);
TransactionManager transact = pool.getTransactionManager();
Txn transaction = transact.beginTransaction();
try {
broker = pool.get(session.getUser());
Collection collection = broker.getCollection(collectionName);
if (collection == null) {
transact.abort(transaction);
throw new RemoteException(
"collection " + collectionName + " not found");
}
DocumentSet docs =
collection.allDocs(broker, new DefaultDocumentSet(), true, true);
XUpdateProcessor processor =
new XUpdateProcessor(broker, docs, AccessContext.SOAP);
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 RemoteException(e.getMessage(), e);
} catch (IOException e) {
transact.abort(transaction);
throw new RemoteException(e.getMessage(), e);
} catch (EXistException e) {
transact.abort(transaction);
throw new RemoteException(e.getMessage(), e);
} catch (SAXException e) {
transact.abort(transaction);
throw new RemoteException(e.getMessage(), e);
} catch (PermissionDeniedException e) {
transact.abort(transaction);
throw new RemoteException(e.getMessage(), e);
} catch (XPathException e) {
transact.abort(transaction);
throw new RemoteException(e.getMessage(), e);
} catch (LockException e) {
transact.abort(transaction);
throw new RemoteException(e.getMessage(), e);
} finally {
pool.release(broker);
}
}
public int xupdateResource(java.lang.String sessionId, java.lang.String documentName, java.lang.String xupdate) throws java.rmi.RemoteException {
try {
return xupdateResource(sessionId,XmldbURI.xmldbUriFor(documentName), xupdate);
} catch(URISyntaxException e) {
throw new RemoteException("Invalid document URI",e);
}
}
public int xupdateResource(java.lang.String sessionId, XmldbURI documentName, java.lang.String xupdate) throws java.rmi.RemoteException {
DBBroker broker = null;
Session session = getSession(sessionId);
TransactionManager transact = pool.getTransactionManager();
Txn transaction = transact.beginTransaction();
try {
broker = pool.get(session.getUser());
// TODO check XML/Binary resource
// DocumentImpl doc = (DocumentImpl)broker.getDocument(documentName);
DocumentImpl doc = (DocumentImpl)broker.getXMLResource(documentName);
if (doc == null) {
transact.abort(transaction);
throw new RemoteException(
"document " + documentName + " not found");
}
if(!doc.getPermissions().validate(broker.getUser(), Permission.READ)) {
transact.abort(transaction);
throw new RemoteException("Not allowed to read resource");
}
MutableDocumentSet docs = new DefaultDocumentSet();
docs.add(doc);
XUpdateProcessor processor =
new XUpdateProcessor(broker, docs, AccessContext.SOAP);
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 RemoteException(e.getMessage(), e);
} catch (IOException e) {
transact.abort(transaction);
throw new RemoteException(e.getMessage(), e);
} catch (EXistException e) {
transact.abort(transaction);
throw new RemoteException(e.getMessage(), e);
} catch (SAXException e) {
transact.abort(transaction);
throw new RemoteException(e.getMessage(), e);
} catch (PermissionDeniedException e) {
transact.abort(transaction);
throw new RemoteException(e.getMessage(), e);
} catch (XPathException e) {
transact.abort(transaction);
throw new RemoteException(e.getMessage(), e);
} catch (LockException e) {
transact.abort(transaction);
throw new RemoteException(e.getMessage(), e);
} finally {
pool.release(broker);
}
}
public void storeBinary(java.lang.String sessionId, byte[] data, java.lang.String path, java.lang.String mimeType, boolean replace) throws java.rmi.RemoteException {
try {
storeBinary(sessionId,data,XmldbURI.xmldbUriFor(path), mimeType, replace);
} catch(URISyntaxException e) {
throw new RemoteException("Invalid document URI",e);
}
}
public void storeBinary(java.lang.String sessionId, byte[] data, XmldbURI path, java.lang.String mimeType, boolean replace) throws java.rmi.RemoteException {
DBBroker broker = null;
Session session = getSession(sessionId);
Collection collection = null;
TransactionManager transact = pool.getTransactionManager();
Txn txn = transact.beginTransaction();
try {
broker = pool.get(session.getUser());
XmldbURI collectionUri = path.removeLastSegment();
XmldbURI docUri = path.lastSegment();
if (collectionUri==null || docUri==null) {
transact.abort(txn);
throw new EXistException("Illegal document path");
}
collection = broker.openCollection(collectionUri, Lock.WRITE_LOCK);
if (collection == null)
throw new EXistException("Collection " + collectionUri
+ " not found");
if (!replace) {
DocumentImpl old = collection.getDocument(broker, docUri);
if (old != null)
throw new PermissionDeniedException(
"Old document exists and overwrite is not allowed");
}
LOG.debug("Storing binary resource to collection " + collection.getURI());
/*DocumentImpl doc = */
collection.addBinaryResource(txn, broker, docUri, data, mimeType);
// if (created != null)
// doc.setCreated(created.getTime());
// if (modified != null)
// doc.setLastModified(modified.getTime());
transact.commit(txn);
} catch (Exception e) {
transact.abort(txn);
throw new RemoteException(e.getMessage(), e);
} finally {
if(collection != null)
collection.release(Lock.WRITE_LOCK);
pool.release(broker);
}
// documentCache.clear();
// return doc != null;
}
public byte[] getBinaryResource(java.lang.String sessionId, java.lang.String path) throws java.rmi.RemoteException {
try {
return getBinaryResource(sessionId,XmldbURI.xmldbUriFor(path));
} catch(URISyntaxException e) {
throw new RemoteException("Invalid document URI",e);
}
}
public byte[] getBinaryResource(java.lang.String sessionId, XmldbURI name) throws java.rmi.RemoteException {
DBBroker broker = null;
Session session = getSession(sessionId);
DocumentImpl doc = null;
try {
broker = pool.get(session.getUser());
// TODO check XML/Binary resource
// doc = (DocumentImpl) broker.openXmlDocument(name, Lock.READ_LOCK);
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(session.getUser(), Permission.READ))
throw new PermissionDeniedException("Insufficient privileges to read resource");
InputStream is = broker.getBinaryResource((BinaryDocument) doc);
byte [] data = new byte[(int)broker.getBinaryResourceSize((BinaryDocument) doc)];
is.read(data);
is.close();
return data;
} catch (Exception ex) {
throw new RemoteException(ex.getMessage());
} finally {
if(doc != null)
doc.getUpdateLock().release(Lock.READ_LOCK);
pool.release(broker);
}
}
public org.exist.soap.CollectionDesc getCollectionDesc(java.lang.String sessionId, java.lang.String path) throws java.rmi.RemoteException {
try {
return getCollectionDesc(sessionId,XmldbURI.xmldbUriFor(path));
} catch(URISyntaxException e) {
throw new RemoteException("Invalid collection URI",e);
}
}
public org.exist.soap.CollectionDesc getCollectionDesc(java.lang.String sessionId, XmldbURI collectionName) throws java.rmi.RemoteException {
DBBroker broker = null;
Session session = getSession(sessionId);
Collection collection = null;
try {
broker = pool.get(session.getUser());
if (collectionName == null)
collectionName = XmldbURI.ROOT_COLLECTION_URI;
collection = broker.openCollection(collectionName, Lock.READ_LOCK);
if (collection == null)
throw new EXistException("collection " + collectionName
+ " not found!");
CollectionDesc desc = new CollectionDesc();
Vector docs = new Vector();
Vector collections = new Vector();
if (collection.getPermissions().validate(session.getUser(), Permission.READ)) {
DocumentImpl doc;
// Hashtable hash;
Permission perms;
for (Iterator i = collection.iterator(broker); i.hasNext(); ) {
doc = (DocumentImpl) i.next();
perms = doc.getPermissions();
DocumentDesc dd = new DocumentDesc();
// hash = new Hashtable(4);
dd.setName(doc.getFileURI().toString());
dd.setOwner(perms.getOwner());
dd.setGroup(perms.getOwnerGroup());
dd.setPermissions(perms.getPermissions());
dd.setType(doc.getResourceType() == DocumentImpl.BINARY_FILE
? DocumentType.BinaryResource
: DocumentType.XMLResource);
docs.addElement(dd);
}
for (Iterator i = collection.collectionIterator(); i.hasNext(); )
collections.addElement(((XmldbURI)i.next()).toString());
}
Permission perms = collection.getPermissions();
desc.setCollections(new Strings((String[]) collections.toArray(new String[collections.size()])));
desc.setDocuments(new DocumentDescs((DocumentDesc[])docs.toArray(new DocumentDesc[docs.size()])));
desc.setName(collection.getURI().toString());
desc.setCreated(collection.getCreationTime());
desc.setOwner(perms.getOwner());
desc.setGroup(perms.getOwnerGroup());
desc.setPermissions(perms.getPermissions());
return desc;
} catch (Exception ex){
throw new RemoteException(ex.getMessage());
} finally {
if(collection != null)
collection.release(Lock.READ_LOCK);
pool.release(broker);
}
}
public void setPermissions(java.lang.String sessionId, java.lang.String resource, java.lang.String owner, java.lang.String ownerGroup, int permissions) throws java.rmi.RemoteException {
try {
setPermissions(sessionId,XmldbURI.xmldbUriFor(resource),owner,ownerGroup,permissions);
} catch(URISyntaxException e) {
throw new RemoteException("Invalid collection URI",e);
}
}
public void setPermissions(java.lang.String sessionId, XmldbURI resource, java.lang.String owner, java.lang.String ownerGroup, int permissions) throws java.rmi.RemoteException {
DBBroker broker = null;
Session session = getSession(sessionId);
Collection collection = null;
DocumentImpl doc = null;
TransactionManager transact = pool.getTransactionManager();
Txn transaction = transact.beginTransaction();
try {
broker = pool.get(session.getUser());
org.exist.security.SecurityManager manager = pool
.getSecurityManager();
collection = broker.openCollection(resource, Lock.WRITE_LOCK);
if (collection == null) {
// TODO check XML/Binary resource
// doc = (DocumentImpl) broker.openDocument(resource, Lock.WRITE_LOCK);
doc = (DocumentImpl) broker.getXMLResource(resource, Lock.WRITE_LOCK);
if (doc == null)
throw new RemoteException("document or collection "
+ resource + " not found");
LOG.debug("changing permissions on document " + resource);
Permission perm = doc.getPermissions();
if (perm.getOwner().equals(session.getUser().getName())
|| manager.hasAdminPrivileges(session.getUser())) {
if (owner != null) {
perm.setOwner(owner);
perm.setGroup(ownerGroup);
}
perm.setPermissions(permissions);
// TODO check XML/Binary resource
// broker.storeDocument(transaction, doc);
broker.storeXMLResource(transaction, doc);
transact.commit(transaction);
broker.flush();
return;
// return true;
}
transact.abort(transaction);
throw new PermissionDeniedException("not allowed to change permissions");
}
LOG.debug("changing permissions on collection " + resource);
Permission perm = collection.getPermissions();
if (perm.getOwner().equals(session.getUser().getName())
|| manager.hasAdminPrivileges(session.getUser())) {
perm.setPermissions(permissions);
if (owner != null) {
perm.setOwner(owner);
perm.setGroup(ownerGroup);
}
transaction.registerLock(collection.getLock(), Lock.WRITE_LOCK);
broker.saveCollection(transaction, collection);
transact.commit(transaction);
broker.flush();
return;
}
transact.abort(transaction);
throw new PermissionDeniedException("not allowed to change permissions");
} catch (IOException e) {
transact.abort(transaction);
throw new RemoteException(e.getMessage());
} catch (PermissionDeniedException e) {
transact.abort(transaction);
throw new RemoteException(e.getMessage());
} catch (TransactionException e) {
throw new RemoteException(e.getMessage());
} catch (EXistException e) {
throw new RemoteException(e.getMessage());
} finally {
if(doc != null)
doc.getUpdateLock().release(Lock.WRITE_LOCK);
pool.release(broker);
}
}
private void moveOrCopyResource(String sessionId, String docPath, String destinationPath,
String newName, boolean move)
throws RemoteException {
try {
moveOrCopyResource(sessionId,XmldbURI.xmldbUriFor(docPath),XmldbURI.xmldbUriFor(destinationPath),XmldbURI.xmldbUriFor(newName),move);
} catch(URISyntaxException e) {
throw new RemoteException("Invalid collection URI",e);
}
}
private void moveOrCopyResource(String sessionId, XmldbURI docPath, XmldbURI destinationPath,
XmldbURI newName, boolean move)
throws RemoteException {
TransactionManager transact = pool.getTransactionManager();
Txn transaction = transact.beginTransaction();
DBBroker broker = null;
Session session = getSession(sessionId);
Collection collection = null;
Collection destination = null;
DocumentImpl doc = null;
try {
broker = pool.get(session.getUser());
XmldbURI collectionUri = docPath.removeLastSegment();
XmldbURI docUri = docPath.lastSegment();
if (collectionUri==null || docUri==null) {
transact.abort(transaction);
throw new EXistException("Illegal document path");
}
collection = broker.openCollection(collectionUri, move ? Lock.WRITE_LOCK : Lock.READ_LOCK);
if (collection == null) {
transact.abort(transaction);
throw new RemoteException("Collection " + collectionUri
+ " not found");
}
doc = collection.getDocumentWithLock(broker, docUri, Lock.WRITE_LOCK);
if(doc == null) {
transact.abort(transaction);
throw new RemoteException("Document " + docUri + " not found");
}
// get destination collection
destination = broker.openCollection(destinationPath, Lock.WRITE_LOCK);
if(destination == null) {
transact.abort(transaction);
throw new RemoteException("Destination collection " + destinationPath + " not found");
}
if(move)
// TODO check XML/Binary resource
// broker.moveResource(transaction, doc, destination, newName);
broker.moveResource(transaction, doc, destination, newName);
else
// TODO check XML/Binary resource
// broker.copyResource(transaction, doc, destination, newName);
broker.copyResource(transaction, doc, destination, newName);
transact.commit(transaction);
// documentCache.clear();
return;
} catch (LockException e) {
transact.abort(transaction);
throw new RemoteException("Could not acquire lock on document " + docPath);
} catch (PermissionDeniedException e) {
transact.abort(transaction);
throw new RemoteException("Could not move/copy document " + docPath);
} catch (IOException e) {
transact.abort(transaction);
throw new RemoteException(e.getMessage());
} catch (TransactionException e) {
throw new RemoteException("Error commiting transaction " + e.getMessage());
} catch (EXistException e) {
throw new RemoteException(e.getMessage());
} finally {
if(destination != null)
destination.release(Lock.WRITE_LOCK);
if(doc != null)
doc.getUpdateLock().release(Lock.WRITE_LOCK);
if(collection != null)
collection.release(move ? Lock.WRITE_LOCK : Lock.READ_LOCK);
pool.release(broker);
}
}
private boolean moveOrCopyCollection(String sessionId, String collectionPath, String destinationPath,
String newName, boolean move)
throws EXistException, PermissionDeniedException, RemoteException {
try {
return moveOrCopyCollection(sessionId,XmldbURI.xmldbUriFor(collectionPath),XmldbURI.xmldbUriFor(destinationPath),XmldbURI.xmldbUriFor(newName),move);
} catch(URISyntaxException e) {
throw new RemoteException("Invalid collection URI",e);
}
}
private boolean moveOrCopyCollection(String sessionId, XmldbURI collectionPath, XmldbURI destinationPath,
XmldbURI newName, boolean move)
throws EXistException, PermissionDeniedException, RemoteException {
TransactionManager transact = pool.getTransactionManager();
Txn transaction = transact.beginTransaction();
DBBroker broker = null;
Session session = getSession(sessionId);
Collection collection = null;
Collection destination = null;
try {
User user = session.getUser();
broker = pool.get(user);
// get source document
collection = broker.openCollection(collectionPath, move ? Lock.WRITE_LOCK : Lock.READ_LOCK);
if (collection == null) {
transact.abort(transaction);
throw new EXistException("Collection " + collectionPath
+ " not found");
}
// get destination collection
destination = broker.openCollection(destinationPath, Lock.WRITE_LOCK);
if(destination == null) {
transact.abort(transaction);
throw new EXistException("Destination collection " + destinationPath + " not found");
}
if(move)
broker.moveCollection(transaction, collection, destination, newName);
else
broker.copyCollection(transaction, collection, destination, newName);
transact.commit(transaction);
// documentCache.clear();
return true;
} catch (IOException e) {
transact.abort(transaction);
throw new RemoteException(e.getMessage());
} catch (LockException e) {
transact.abort(transaction);
throw new PermissionDeniedException(e.getMessage());
} finally {
if(collection != null)
collection.release(move ? Lock.WRITE_LOCK : Lock.READ_LOCK);
if(destination != null)
destination.release(Lock.WRITE_LOCK);
pool.release(broker);
}
}
public void copyResource(java.lang.String sessionId, java.lang.String docPath, java.lang.String destinationPath, java.lang.String newName) throws java.rmi.RemoteException {
moveOrCopyResource(sessionId,docPath,destinationPath,newName,false);
}
public void copyCollection(java.lang.String sessionId, java.lang.String collectionPath, java.lang.String destinationPath, java.lang.String newName) throws java.rmi.RemoteException {
try {
moveOrCopyCollection(sessionId,collectionPath,destinationPath,newName,false);
} catch (RemoteException e) {
throw new RemoteException(e.getMessage());
} catch (EXistException e) {
throw new RemoteException(e.getMessage());
} catch (PermissionDeniedException e) {
throw new RemoteException(e.getMessage());
}
}
public void setUser(java.lang.String sessionId, java.lang.String name, java.lang.String password, org.exist.soap.Strings groups, java.lang.String home) throws java.rmi.RemoteException {
if (password.length() == 0)
password = null;
Session session = getSession(sessionId);
User user = session.getUser();
org.exist.security.SecurityManager manager = pool.getSecurityManager();
if(name.equals(org.exist.security.SecurityManager.GUEST_USER) &&
(!manager.hasAdminPrivileges(user)))
throw new RemoteException(
"guest user cannot be modified");
User u;
if (!manager.hasUser(name)) {
if (!manager.hasAdminPrivileges(user))
throw new RemoteException(
"not allowed to create user");
u = new User(name);
u.setPasswordDigest(password);
} else {
u = manager.getUser(name);
if (!(u.getName().equals(user.getName()) || manager
.hasAdminPrivileges(user)))
throw new RemoteException(
"you are not allowed to change this user");
u.setPasswordDigest(password);
}
for (int i = 0; i < groups.getElements().length; i++ ) {
if (!u.hasGroup(groups.getElements()[i])) {
if(!manager.hasAdminPrivileges(user))
throw new RemoteException(
"User is not allowed to add groups");
u.addGroup(groups.getElements()[i]);
}
}
if (home != null) {
try {
u.setHome(XmldbURI.xmldbUriFor(home));
} catch(URISyntaxException e) {
throw new RemoteException("Invalid collection URI",e);
}
}
manager.setUser(u);
}
public org.exist.soap.UserDesc getUser(java.lang.String sessionId, java.lang.String user) throws java.rmi.RemoteException {
User u = pool.getSecurityManager().getUser(user);
if (u == null)
throw new RemoteException("user " + user + " does not exist");
UserDesc desc = new UserDesc();
desc.setName(u.getName());
/*
Vector groups = new Vector();
for (Iterator i = u.getGroups(); i.hasNext(); )
groups.addElement(i.next());
desc.setGroups(new Strings((String[])groups.toArray(new String[groups.size()])));
*/
desc.setGroups(new Strings(u.getGroups()));
if (u.getHome() != null) {
desc.setHome(u.getHome().toString());
}
return desc;
}
public void removeUser(java.lang.String sessionId, java.lang.String name) throws java.rmi.RemoteException {
User user = getSession(sessionId).getUser();
org.exist.security.SecurityManager manager = pool
.getSecurityManager();
if (!manager.hasAdminPrivileges(user))
throw new RemoteException(
"you are not allowed to remove users");
try {
manager.deleteUser(name);
} catch (PermissionDeniedException e) {
throw new RemoteException(e.getMessage());
}
}
public org.exist.soap.UserDescs getUsers(java.lang.String sessionId) throws java.rmi.RemoteException {
User users[] = pool.getSecurityManager().getUsers();
UserDesc[] r = new UserDesc[users.length];
for (int i = 0; i < users.length; i++) {
r[i] = new UserDesc();
r[i].setName(users[i].getName());
/*
Vector groups = new Vector();
for (Iterator j = users[i].getGroups(); j.hasNext(); )
groups.addElement(j.next());
r[i].setGroups(new Strings((String[])groups.toArray(new String[groups.size()])));
*/
r[i].setGroups(new Strings(users[i].getGroups()));
if (users[i].getHome() != null)
r[i].setHome(users[i].getHome().toString());
}
return new UserDescs(r);
}
public org.exist.soap.Strings getGroups(java.lang.String sessionId) throws java.rmi.RemoteException {
String[] groups = pool.getSecurityManager().getGroups();
Vector v = new Vector(groups.length);
for (int i = 0; i < groups.length; i++) {
v.addElement(groups[i]);
}
return new Strings((String[])v.toArray(new String[v.size()]));
}
public void moveCollection(java.lang.String sessionId, java.lang.String collectionPath, java.lang.String destinationPath, java.lang.String newName) throws java.rmi.RemoteException {
try {
moveOrCopyCollection(sessionId,collectionPath,destinationPath,newName,true);
} catch (RemoteException e) {
throw new RemoteException(e.getMessage());
} catch (EXistException e) {
throw new RemoteException(e.getMessage());
} catch (PermissionDeniedException e) {
throw new RemoteException(e.getMessage());
}
}
public void moveResource(java.lang.String sessionId, java.lang.String docPath, java.lang.String destinationPath, java.lang.String newName) throws java.rmi.RemoteException {
moveOrCopyResource(sessionId,docPath,destinationPath,newName,true);
}
public void lockResource(java.lang.String sessionId, java.lang.String path, java.lang.String userName) throws java.rmi.RemoteException {
try {
lockResource(sessionId,XmldbURI.xmldbUriFor(path),userName);
} catch(URISyntaxException e) {
throw new RemoteException("Invalid collection URI",e);
}
}
public void lockResource(java.lang.String sessionId, XmldbURI path, java.lang.String userName) throws java.rmi.RemoteException {
DBBroker broker = null;
Session session = getSession(sessionId);
User user = session.getUser();
DocumentImpl doc = null;
TransactionManager transact = pool.getTransactionManager();
Txn transaction = transact.beginTransaction();
try {
broker = pool.get(user);
// TODO check XML/Binary resource
// doc = (DocumentImpl) broker.openDocument(path, Lock.WRITE_LOCK);
doc = broker.getXMLResource(path, Lock.WRITE_LOCK);
if (doc == null) {
throw new EXistException("Resource "
+ path + " not found");
}
if (!doc.getPermissions().validate(user, Permission.UPDATE))
throw new PermissionDeniedException("User is not allowed to lock resource " + path);
org.exist.security.SecurityManager manager = pool.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());
User lo = manager.getUser(userName);
doc.setUserLock(lo);
// TODO check XML/Binary resource
// broker.storeDocument(transaction, doc);
broker.storeXMLResource(transaction, doc);
transact.commit(transaction);
return;
} catch (Exception e) {
transact.abort(transaction);
throw new RemoteException(e.getMessage());
} finally {
if(doc != null)
doc.getUpdateLock().release(Lock.WRITE_LOCK);
pool.release(broker);
}
}
public void unlockResource(java.lang.String sessionId, java.lang.String path) throws java.rmi.RemoteException {
try {
unlockResource(sessionId,XmldbURI.xmldbUriFor(path));
} catch(URISyntaxException e) {
throw new RemoteException("Invalid collection URI",e);
}
}
public void unlockResource(java.lang.String sessionId, XmldbURI path) throws java.rmi.RemoteException {
DBBroker broker = null;
Session session = getSession(sessionId);
User user = session.getUser();
DocumentImpl doc = null;
try {
broker = pool.get(user);
// TODO check XML/Binary resource
// doc = (DocumentImpl) broker.openDocument(path, Lock.WRITE_LOCK);
doc = (DocumentImpl) broker.getXMLResource(path, Lock.WRITE_LOCK);
if (doc == null)
throw new EXistException("Resource "
+ path + " not found");
if (!doc.getPermissions().validate(user, Permission.UPDATE))
throw new PermissionDeniedException("User is not allowed to lock resource " + path);
org.exist.security.SecurityManager manager = pool.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());
TransactionManager transact = pool.getTransactionManager();
Txn transaction = transact.beginTransaction();
doc.setUserLock(null);
// TODO check XML/Binary resource
// broker.storeDocument(transaction, doc);
broker.storeXMLResource(transaction, doc);
transact.commit(transaction);
return;
} catch (Exception ex){
throw new RemoteException(ex.getMessage());
} finally {
if(doc != null)
doc.getUpdateLock().release(Lock.WRITE_LOCK);
pool.release(broker);
}
}
public java.lang.String hasUserLock(java.lang.String sessionId, java.lang.String path) throws java.rmi.RemoteException {
try {
return hasUserLock(sessionId,XmldbURI.xmldbUriFor(path));
} catch(URISyntaxException e) {
throw new RemoteException("Invalid collection URI",e);
}
}
public java.lang.String hasUserLock(java.lang.String sessionId, XmldbURI path) throws java.rmi.RemoteException {
DBBroker broker = null;
Session session = getSession(sessionId);
User user = session.getUser();
DocumentImpl doc = null;
try {
broker = pool.get(user);
// TODO check XML/Binary resource
// doc = (DocumentImpl) broker.openDocument(path, Lock.READ_LOCK);
doc = (DocumentImpl) broker.getXMLResource(path, Lock.READ_LOCK);
if (doc == null)
throw new EXistException("Resource "
+ path + " not found");
if(!doc.getPermissions().validate(user, Permission.READ))
throw new PermissionDeniedException("Insufficient privileges to read resource");
if (doc == null)
throw new EXistException("Resource " + path + " not found");
User u = doc.getUserLock();
return u == null ? "" : u.getName();
} catch (Exception ex) {
throw new RemoteException(ex.getMessage());
} finally {
if(doc != null)
doc.getUpdateLock().release(Lock.READ_LOCK);
pool.release(broker);
}
}
public org.exist.soap.Permissions getPermissions(java.lang.String sessionId, java.lang.String resource) throws java.rmi.RemoteException {
try {
return getPermissions(sessionId,XmldbURI.xmldbUriFor(resource));
} catch(URISyntaxException e) {
throw new RemoteException("Invalid collection URI",e);
}
}
public org.exist.soap.Permissions getPermissions(java.lang.String sessionId, XmldbURI resource) throws java.rmi.RemoteException {
DBBroker broker = null;
Session session = getSession(sessionId);
User user = session.getUser();
try {
broker = pool.get(user);
Collection collection = null;
try {
collection = broker.openCollection(resource, Lock.READ_LOCK);
Permission perm = null;
if (collection == null) {
// TODO check XML/Binary resource
// DocumentImpl doc = (DocumentImpl) broker.openDocument(resource, Lock.READ_LOCK);
DocumentImpl doc = null;
try {
doc = (DocumentImpl) broker.getXMLResource(resource, Lock.READ_LOCK);
if (doc == null)
throw new EXistException("document or collection " + resource + " not found");
perm = doc.getPermissions();
} finally {
if (doc != null)
doc.getUpdateLock().release(Lock.READ_LOCK);
}
} else {
perm = collection.getPermissions();
}
Permissions p = new Permissions();
p.setOwner(perm.getOwner());
p.setGroup(perm.getOwnerGroup());
p.setPermissions(perm.getPermissions());
return p;
} finally {
if (collection != null)
collection.release(Lock.READ_LOCK);
}
} catch (Exception ex) {
throw new RemoteException(ex.getMessage());
} finally {
pool.release(broker);
}
}
public org.exist.soap.EntityPermissionsList listCollectionPermissions(java.lang.String sessionId, java.lang.String name) throws java.rmi.RemoteException {
try {
return listCollectionPermissions(sessionId,XmldbURI.xmldbUriFor(name));
} catch(URISyntaxException e) {
throw new RemoteException("Invalid collection URI",e);
}
}
public org.exist.soap.EntityPermissionsList listCollectionPermissions(java.lang.String sessionId, XmldbURI name) throws java.rmi.RemoteException {
DBBroker broker = null;
Session session = getSession(sessionId);
User user = session.getUser();
Collection collection = null;
try {
broker = pool.get(user);
collection = broker.openCollection(name, Lock.READ_LOCK);
if (collection == null)
throw new EXistException("Collection " + name + " not found");
if (!collection.getPermissions().validate(user, Permission.READ))
throw new PermissionDeniedException(
"not allowed to read collection " + name);
EntityPermissions[] result = new EntityPermissions[collection.getChildCollectionCount()];
XmldbURI child, path;
Collection childColl;
Permission perm;
int cnt = 0;
for (Iterator i = collection.collectionIterator(); i.hasNext(); ) {
child = (XmldbURI) i.next();
path = name.append(child);
childColl = broker.getCollection(path);
perm = childColl.getPermissions();
result[cnt] = new EntityPermissions();
result[cnt].setName(child.toString());
result[cnt].setOwner(perm.getOwner());
result[cnt].setGroup(perm.getOwnerGroup());
result[cnt].setPermissions(perm.getPermissions());
cnt++;
}
return new EntityPermissionsList(result);
} catch (Exception ex) {
throw new RemoteException(ex.getMessage());
} finally {
if(collection != null)
collection.release(Lock.READ_LOCK);
pool.release(broker);
}
}
public org.exist.soap.EntityPermissionsList listDocumentPermissions(java.lang.String sessionId, java.lang.String name) throws java.rmi.RemoteException {
try {
return listDocumentPermissions(sessionId,XmldbURI.xmldbUriFor(name));
} catch(URISyntaxException e) {
throw new RemoteException("Invalid collection URI",e);
}
}
public org.exist.soap.EntityPermissionsList listDocumentPermissions(java.lang.String sessionId, XmldbURI name) throws java.rmi.RemoteException {
DBBroker broker = null;
Session session = getSession(sessionId);
User user = session.getUser();
Collection collection = null;
try {
broker = pool.get(user);
collection = broker.openCollection(name, Lock.READ_LOCK);
if (collection == null)
throw new EXistException("Collection " + name + " not found");
if (!collection.getPermissions().validate(user, Permission.READ))
throw new PermissionDeniedException(
"not allowed to read collection " + name);
EntityPermissions[] result = new EntityPermissions[collection.getDocumentCount()];
DocumentImpl doc;
Permission perm;
int cnt = 0;
for (Iterator i = collection.iterator(broker); i.hasNext(); ) {
doc = (DocumentImpl) i.next();
perm = doc.getPermissions();
result[cnt] = new EntityPermissions();
result[cnt].setName(doc.getFileURI().toString());
result[cnt].setOwner(perm.getOwner());
result[cnt].setGroup(perm.getOwnerGroup());
result[cnt].setPermissions(perm.getPermissions());
cnt++;
}
return new EntityPermissionsList(result);
} catch (Exception ex) {
throw new RemoteException(ex.getMessage());
} finally {
if(collection != null)
collection.release(Lock.READ_LOCK);
pool.release(broker);
}
}
public org.exist.soap.IndexedElements getIndexedElements(java.lang.String sessionId, java.lang.String collectionName, boolean inclusive) throws java.rmi.RemoteException {
try {
return getIndexedElements(sessionId,XmldbURI.xmldbUriFor(collectionName),inclusive);
} catch(URISyntaxException e) {
throw new RemoteException("Invalid collection URI",e);
}
}
public org.exist.soap.IndexedElements getIndexedElements(java.lang.String sessionId, XmldbURI collectionName, boolean inclusive) throws java.rmi.RemoteException {
DBBroker broker = null;
Session session = getSession(sessionId);
User user = session.getUser();
Collection collection = null;
try {
broker = pool.get(user);
collection = broker.openCollection(collectionName, Lock.READ_LOCK);
if (collection == null)
throw new EXistException("collection " + collectionName
+ " not found");
Occurrences occurrences[] = broker.getElementIndex().scanIndexedElements(collection,
inclusive);
IndexedElement[] result = new IndexedElement[occurrences.length];
for (int i = 0; i < occurrences.length; i++) {
QName qname = (QName)occurrences[i].getTerm();
result[i] = new IndexedElement(qname.getLocalName(),qname.getNamespaceURI(),
qname.getPrefix() == null ? "" : qname.getPrefix(),
occurrences[i].getOccurrences());
}
return new IndexedElements(result);
} catch (Exception ex) {
throw new RemoteException(ex.getMessage());
} finally {
if(collection != null)
collection.release(Lock.READ_LOCK);
pool.release(broker);
}
}
}