use of org.exist.dom.persistent.LockedDocument in project exist by eXist-db.
the class XMLDBSetMimeType method eval.
@Override
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
// Get handle to Mime-type info
final MimeTable mimeTable = MimeTable.getInstance();
// Get first parameter
final String pathParameter = new AnyURIValue(args[0].itemAt(0).getStringValue()).toString();
if (pathParameter.matches("^[a-z]+://.*")) {
throw new XPathException("Can not set mime-type for resources outside the database.");
}
XmldbURI pathUri = null;
try {
pathUri = XmldbURI.xmldbUriFor(pathParameter);
} catch (final URISyntaxException ex) {
logger.debug(ex.getMessage());
throw new XPathException("Invalid path '" + pathParameter + "'");
}
// Verify mime-type input
MimeType newMimeType = null;
if (args[1].isEmpty()) {
// No input, use default mimetype
newMimeType = mimeTable.getContentTypeFor(pathParameter);
if (newMimeType == null) {
throw new XPathException("Unable to determine mimetype for '" + pathParameter + "'");
}
} else {
// Mimetype is provided, check if valid
newMimeType = mimeTable.getContentType(args[1].getStringValue());
if (newMimeType == null) {
throw new XPathException("mime-type '" + args[1].getStringValue() + "' is not supported.");
}
}
// Get mime-type of resource
MimeType currentMimeType = getMimeTypeStoredResource(pathUri);
if (currentMimeType == null) {
// stored resource has no mime-type (unexpected situation)
// fall back to document name
logger.debug("Resource '{}' has no mime-type, retrieve from document name.", pathUri);
currentMimeType = mimeTable.getContentTypeFor(pathUri);
// if extension based lookup still fails
if (currentMimeType == null) {
throw new XPathException("Unable to determine mime-type from path '" + pathUri + "'.");
}
}
// in some cases value null is set, then allow to set to new value (repair action)
if (newMimeType.isXMLType() != currentMimeType.isXMLType()) {
throw new XPathException("New mime-type must be a " + currentMimeType.getXMLDBType() + " mime-type");
}
// At this moment it is possible to update the mimetype
final DBBroker broker = context.getBroker();
final BrokerPool brokerPool = broker.getBrokerPool();
// relative collection Path: add the current base URI
pathUri = context.getBaseURI().toXmldbURI().resolveCollectionPath(pathUri);
try (final Txn txn = broker.continueOrBeginTransaction();
final LockedDocument lockedDocument = broker.getXMLResource(pathUri, LockMode.WRITE_LOCK)) {
// try to open the document and acquire a lock
final DocumentImpl doc = lockedDocument == null ? null : lockedDocument.getDocument();
if (doc == null) {
// no document selected, abort
txn.abort();
} else {
// set new mime-type
doc.setMimeType(newMimeType.getName());
// store meta data into database
broker.storeMetadata(txn, doc);
// commit changes
txn.commit();
}
} catch (final Exception e) {
logger.error(e.getMessage());
throw new XPathException(this, e);
}
return Sequence.EMPTY_SEQUENCE;
}
Aggregations