use of org.exist.EXistException in project exist by eXist-db.
the class Deployment method checkUserSettings.
private void checkUserSettings(final DBBroker broker, final RequestedPerms requestedPerms) throws PackageException {
final org.exist.security.SecurityManager secman = broker.getBrokerPool().getSecurityManager();
try {
if (requestedPerms.group.filter(g -> !secman.hasGroup(g)).isPresent()) {
secman.addGroup(broker, new GroupAider(requestedPerms.group.get()));
}
if (!secman.hasAccount(requestedPerms.user)) {
final UserAider aider = new UserAider(requestedPerms.user);
aider.setPassword(requestedPerms.password);
requestedPerms.group.ifPresent(aider::addGroup);
secman.addAccount(broker, aider);
}
} catch (final PermissionDeniedException | EXistException e) {
throw new PackageException("Failed to create user: " + requestedPerms.user, e);
}
}
use of org.exist.EXistException in project exist by eXist-db.
the class EmbeddedOutputStream method uploadToDb.
private static void uploadToDb(final BrokerPool pool, final XmldbURL url, final Path tempFile) throws IOException {
try (final DBBroker broker = pool.getBroker()) {
final XmldbURI collectionUri = XmldbURI.create(url.getCollection());
final XmldbURI documentUri = XmldbURI.create(url.getDocumentName());
try (final Collection collection = broker.openCollection(collectionUri, Lock.LockMode.WRITE_LOCK)) {
if (collection == null) {
throw new IOException("Resource " + collectionUri.toString() + " is not a collection.");
}
if (collection.hasChildCollection(broker, documentUri)) {
throw new IOException("Resource " + documentUri.toString() + " is a collection.");
}
final MimeType mime = MimeTable.getInstance().getContentTypeFor(documentUri);
final TransactionManager transact = pool.getTransactionManager();
try (final Txn txn = transact.beginTransaction()) {
broker.storeDocument(txn, documentUri, new FileInputSource(tempFile), mime, collection);
txn.commit();
}
}
} catch (final EXistException | PermissionDeniedException | LockException | SAXException e) {
LOG.error(e);
throw new IOException(e.getMessage(), e);
} finally {
if (LOG.isDebugEnabled()) {
LOG.debug("End document upload");
}
}
}
use of org.exist.EXistException in project exist by eXist-db.
the class NativeBroker method copyResource.
@Override
public void copyResource(final Txn transaction, final DocumentImpl sourceDocument, final Collection targetCollection, final XmldbURI newDocName, final PreserveType preserve) throws PermissionDeniedException, LockException, IOException, TriggerException, EXistException {
assert (sourceDocument != null);
assert (targetCollection != null);
assert (newDocName != null);
if (isReadOnly()) {
throw new IOException(DATABASE_IS_READ_ONLY);
}
if (newDocName.numSegments() != 1) {
throw new IOException("newName name must be just a name i.e. an XmldbURI with one segment!");
}
final XmldbURI sourceDocumentUri = sourceDocument.getURI();
final XmldbURI targetCollectionUri = targetCollection.getURI();
final XmldbURI targetDocumentUri = targetCollectionUri.append(newDocName);
if (!sourceDocument.getPermissions().validate(getCurrentSubject(), Permission.READ)) {
throw new PermissionDeniedException("Account '" + getCurrentSubject().getName() + "' has insufficient privileges to copy the resource '" + sourceDocumentUri + "'.");
}
// we assume the caller holds a READ_LOCK (or better) on sourceDocument#getCollection()
final Collection sourceCollection = sourceDocument.getCollection();
if (!sourceCollection.getPermissions().validate(getCurrentSubject(), Permission.EXECUTE)) {
throw new PermissionDeniedException("Account '" + getCurrentSubject().getName() + "' has insufficient privileges to copy the resource '" + sourceDocumentUri + "'.");
}
if (!targetCollection.getPermissionsNoLock().validate(getCurrentSubject(), Permission.EXECUTE)) {
throw new PermissionDeniedException("Account '" + getCurrentSubject().getName() + "' does not have execute access on the destination collection '" + targetCollectionUri + "'.");
}
if (targetCollection.hasChildCollection(this, newDocName.lastSegment())) {
throw new EXistException("The collection '" + targetCollectionUri + "' already has a sub-collection named '" + newDocName.lastSegment() + "', you cannot create a Document with the same name as an existing collection.");
}
try (final LockedDocument oldLockedDoc = targetCollection.getDocumentWithLock(this, newDocName, LockMode.WRITE_LOCK)) {
final DocumentTrigger trigger = new DocumentTriggers(this, transaction, targetCollection);
final DocumentImpl oldDoc = oldLockedDoc == null ? null : oldLockedDoc.getDocument();
if (oldDoc == null) {
if (!targetCollection.getPermissionsNoLock().validate(getCurrentSubject(), Permission.WRITE)) {
throw new PermissionDeniedException("Account '" + getCurrentSubject().getName() + "' does not have write access on the destination collection '" + targetCollectionUri + "'.");
}
} else {
if (sourceDocument.getDocId() == oldDoc.getDocId()) {
throw new PermissionDeniedException("Cannot copy resource to itself '" + sourceDocumentUri + "'.");
}
if (!oldDoc.getPermissions().validate(getCurrentSubject(), Permission.WRITE)) {
throw new PermissionDeniedException("A resource with the same name already exists in the target collection '" + oldDoc.getURI() + "', and you do not have write access on that resource.");
}
trigger.beforeDeleteDocument(this, transaction, oldDoc);
trigger.afterDeleteDocument(this, transaction, targetDocumentUri);
}
doCopyDocument(transaction, trigger, sourceDocument, targetCollection, newDocName, oldDoc, preserve);
}
}
use of org.exist.EXistException in project exist by eXist-db.
the class NativeValueIndex method remove.
private <T> void remove(final PendingChanges<T> pending, final FunctionE<T, Value, EXistException> dbKeyFn) {
final VariableByteOutputStream nodeIdOs = new VariableByteOutputStream();
for (final Map.Entry<T, List<NodeId>> entry : pending.changes.entrySet()) {
final T key = entry.getKey();
final List<NodeId> storedGIDList = entry.getValue();
final List<NodeId> newGIDList = new ArrayList<>();
os.clear();
try (final ManagedLock<ReentrantLock> bfileLock = lockManager.acquireBtreeWriteLock(dbValues.getLockName())) {
// Compute a key for the value
final Value searchKey = dbKeyFn.apply(key);
final Value value = dbValues.get(searchKey);
// Does the value already has data in the index ?
if (value != null) {
// Add its data to the new list
final VariableByteArrayInput is = new VariableByteArrayInput(value.getData());
while (is.available() > 0) {
final int storedDocId = is.readInt();
final int gidsCount = is.readInt();
final int size = is.readFixedInt();
if (storedDocId != this.doc.getDocId()) {
// data are related to another document:
// append them to any existing data
os.writeInt(storedDocId);
os.writeInt(gidsCount);
os.writeFixedInt(size);
is.copyRaw(os, size);
} else {
// data are related to our document:
// feed the new list with the GIDs
NodeId previous = null;
for (int j = 0; j < gidsCount; j++) {
final NodeId nodeId = broker.getBrokerPool().getNodeFactory().createFromStream(previous, is);
previous = nodeId;
// in the list of removed nodes
if (!containsNode(storedGIDList, nodeId)) {
newGIDList.add(nodeId);
}
}
}
}
// append the data from the new list
if (newGIDList.size() > 0) {
final int gidsCount = newGIDList.size();
// Don't forget this one
FastQSort.sort(newGIDList, 0, gidsCount - 1);
os.writeInt(this.doc.getDocId());
os.writeInt(gidsCount);
// Compute the new GID list
try {
NodeId previous = null;
for (final NodeId nodeId : newGIDList) {
previous = nodeId.write(previous, nodeIdOs);
}
final byte[] nodeIdsData = nodeIdOs.toByteArray();
// clear the buf for the next iteration
nodeIdOs.clear();
// Write length of node IDs (bytes)
os.writeFixedInt(nodeIdsData.length);
// write the node IDs
os.write(nodeIdsData);
} catch (final IOException e) {
LOG.warn("IO error while writing range index: {}", e.getMessage(), e);
// TODO : throw exception?
}
}
// dbValues.remove(value);
if (dbValues.update(value.getAddress(), searchKey, os.data()) == BFile.UNKNOWN_ADDRESS) {
LOG.error("Could not update index data for value '{}'", searchKey);
// TODO: throw exception ?
}
} else {
if (dbValues.put(searchKey, os.data()) == BFile.UNKNOWN_ADDRESS) {
LOG.error("Could not put index data for value '{}'", searchKey);
// TODO : throw exception ?
}
}
} catch (final EXistException | IOException e) {
LOG.error(e.getMessage(), e);
} catch (final LockException e) {
LOG.warn("Failed to acquire lock for '{}'", FileUtils.fileName(dbValues.getFile()), e);
// TODO : return ?
} finally {
os.clear();
}
}
pending.changes.clear();
}
use of org.exist.EXistException in project exist by eXist-db.
the class NativeValueIndex method findAll.
/**
* find.
*
* @param comparison The type of comparison the search is performing
* @param docs The documents to search for matches within
* @param contextSet DOCUMENT ME!
* @param axis DOCUMENT ME!
* @param qnames DOCUMENT ME!
* @param value right hand comparison value
* @param result DOCUMENT ME!
* @return DOCUMENT ME!
* @throws TerminatedException DOCUMENT ME!
*/
private NodeSet findAll(final XQueryWatchDog watchDog, final Comparison comparison, final DocumentSet docs, final NodeSet contextSet, final int axis, final List<QName> qnames, final Indexable value, final NodeSet result) throws TerminatedException {
final SearchCallback cb = new SearchCallback(docs, contextSet, result, axis == NodeSet.ANCESTOR);
final int idxOp = toIndexQueryOp(comparison);
for (final Iterator<Collection> iter = docs.getCollectionIterator(); iter.hasNext(); ) {
final int collectionId = iter.next().getId();
watchDog.proceed(null);
if (qnames == null) {
try (final ManagedLock<ReentrantLock> bfileLock = lockManager.acquireBtreeReadLock(dbValues.getLockName())) {
final Value searchKey = new SimpleValue(collectionId, value);
final IndexQuery query = new IndexQuery(idxOp, searchKey);
if (idxOp == IndexQuery.EQ) {
dbValues.query(query, cb);
} else {
final Value prefixKey = new SimplePrefixValue(collectionId, value.getType());
dbValues.query(query, prefixKey, cb);
}
} catch (final EXistException | BTreeException | IOException e) {
LOG.error(e.getMessage(), e);
} catch (final LockException e) {
LOG.warn("Failed to acquire lock for '{}'", FileUtils.fileName(dbValues.getFile()), e);
}
} else {
for (final QName qname : qnames) {
try (final ManagedLock<ReentrantLock> bfileLock = lockManager.acquireBtreeReadLock(dbValues.getLockName())) {
// Compute a key for the value in the collection
final Value searchKey = new QNameValue(collectionId, qname, value, broker.getBrokerPool().getSymbols());
final IndexQuery query = new IndexQuery(idxOp, searchKey);
if (idxOp == IndexQuery.EQ) {
dbValues.query(query, cb);
} else {
final Value prefixKey = new QNamePrefixValue(collectionId, qname, value.getType(), broker.getBrokerPool().getSymbols());
dbValues.query(query, prefixKey, cb);
}
} catch (final EXistException | BTreeException | IOException e) {
LOG.error(e.getMessage(), e);
} catch (final LockException e) {
LOG.warn("Failed to acquire lock for '{}'", FileUtils.fileName(dbValues.getFile()), e);
}
}
}
}
return result;
}
Aggregations