use of org.exist.dom.persistent.LockedDocument in project exist by eXist-db.
the class SystemImportHandler method restoreResourceEntry.
private DeferredPermission restoreResourceEntry(final Attributes atts) throws SAXException {
@Nullable final String skip = atts.getValue("skip");
// Don't process entries which should be skipped
if (skip != null && !"no".equals(skip)) {
return new SkippedEntryDeferredPermission();
}
@Nullable final String name = atts.getValue("name");
if (name == null) {
throw new SAXException("Resource requires a name attribute");
}
final boolean xmlType = Optional.ofNullable(atts.getValue("type")).filter(s -> s.equals("XMLResource")).isPresent();
final String owner = getAttr(atts, "owner", SecurityManager.SYSTEM);
final String group = getAttr(atts, "group", SecurityManager.DBA_GROUP);
final String perms = getAttr(atts, "mode", "644");
final String filename = getAttr(atts, "filename", name);
@Nullable final String mimeTypeStr = atts.getValue("mimetype");
@Nullable final String dateCreatedStr = atts.getValue("created");
@Nullable final String dateModifiedStr = atts.getValue("modified");
@Nullable final String publicId = atts.getValue("publicid");
@Nullable final String systemId = atts.getValue("systemid");
@Nullable final String nameDocType = atts.getValue("namedoctype");
MimeType mimeType = null;
if (mimeTypeStr != null) {
mimeType = MimeTable.getInstance().getContentType(mimeTypeStr);
}
if (mimeType == null) {
mimeType = xmlType ? MimeType.XML_TYPE : MimeType.BINARY_TYPE;
}
Date dateCreated = null;
if (dateCreatedStr != null) {
try {
dateCreated = new DateTimeValue(dateCreatedStr).getDate();
} catch (final XPathException xpe) {
listener.warn("Illegal creation date. Ignoring date...");
}
}
Date dateModified = null;
if (dateModifiedStr != null) {
try {
dateModified = new DateTimeValue(dateModifiedStr).getDate();
} catch (final XPathException xpe) {
listener.warn("Illegal modification date. Ignoring date...");
}
}
final DocumentType docType;
if (publicId != null || systemId != null) {
docType = new DocumentTypeImpl(nameDocType, publicId, systemId);
} else {
docType = null;
}
final XmldbURI docUri;
if (version >= STRICT_URI_VERSION) {
docUri = XmldbURI.create(name);
} else {
try {
docUri = URIUtils.encodeXmldbUriFor(name);
} catch (final URISyntaxException e) {
final String msg = "Could not parse document name into a URI: " + e.getMessage();
listener.error(msg);
LOG.error(msg, e);
return new SkippedEntryDeferredPermission();
}
}
try (final EXistInputSource is = descriptor.getInputSource(filename)) {
if (is == null) {
final String msg = "Failed to restore resource '" + name + "'\nfrom file '" + descriptor.getSymbolicPath(name, false) + "'.\nReason: Unable to obtain its EXistInputSource";
listener.warn(msg);
throw new RuntimeException(msg);
}
try (final Txn transaction = beginTransaction()) {
broker.storeDocument(transaction, docUri, is, mimeType, dateCreated, dateModified, null, docType, null, currentCollection);
try (final LockedDocument doc = currentCollection.getDocumentWithLock(broker, docUri, Lock.LockMode.READ_LOCK)) {
rh.startDocumentRestore(doc.getDocument(), atts);
}
transaction.commit();
final DeferredPermission deferredPermission;
if (name.startsWith(XmldbURI.SYSTEM_COLLECTION)) {
// prevents restore of a backup from changing system collection resource ownership
deferredPermission = new ResourceDeferredPermission(listener, currentCollection.getURI().append(name), SecurityManager.SYSTEM, SecurityManager.DBA_GROUP, Integer.parseInt(perms, 8));
} else {
deferredPermission = new ResourceDeferredPermission(listener, currentCollection.getURI().append(name), owner, group, Integer.parseInt(perms, 8));
}
try (final LockedDocument doc = currentCollection.getDocumentWithLock(broker, docUri, Lock.LockMode.READ_LOCK)) {
rh.endDocumentRestore(doc.getDocument());
}
listener.restoredResource(name);
return deferredPermission;
} catch (final Exception e) {
throw new IOException(e);
}
} catch (final Exception e) {
listener.warn("Failed to restore resource '" + name + "'\nfrom file '" + descriptor.getSymbolicPath(name, false) + "'.\nReason: " + e.getMessage());
LOG.error(e.getMessage(), e);
return new SkippedEntryDeferredPermission();
}
}
use of org.exist.dom.persistent.LockedDocument in project exist by eXist-db.
the class ResourceDeferredPermission method apply.
@Override
public void apply(final DBBroker broker, final Txn transaction) {
try (final LockedDocument lockedDoc = broker.getXMLResource(getTarget(), Lock.LockMode.WRITE_LOCK)) {
final DocumentImpl doc = lockedDoc.getDocument();
final Permission permission = doc.getPermissions();
PermissionFactory.chown(broker, permission, Optional.ofNullable(getOwner()), Optional.ofNullable(getGroup()));
PermissionFactory.chmod(broker, permission, Optional.of(getMode()), Optional.ofNullable(permission instanceof ACLPermission ? getAces() : null));
broker.storeXMLResource(transaction, doc);
} catch (final PermissionDeniedException e) {
final String msg = "ERROR: Failed to set permissions on Document '" + getTarget() + "'.";
LOG.error(msg, e);
getListener().warn(msg);
}
}
use of org.exist.dom.persistent.LockedDocument in project exist by eXist-db.
the class XQueryURLRewrite method getSource.
private SourceInfo getSource(final DBBroker broker, final String moduleLoadPath) throws ServletException {
final SourceInfo sourceInfo;
if (query.startsWith(XmldbURI.XMLDB_URI_PREFIX)) {
// Is the module source stored in the database?
try {
final XmldbURI locationUri = XmldbURI.xmldbUriFor(query);
try (final LockedDocument lockedSourceDoc = broker.getXMLResource(locationUri.toCollectionPathURI(), LockMode.READ_LOCK)) {
if (lockedSourceDoc == null) {
throw new ServletException("XQuery resource: " + query + " not found in database");
}
final DocumentImpl sourceDoc = lockedSourceDoc.getDocument();
if (sourceDoc.getResourceType() != DocumentImpl.BINARY_FILE || !"application/xquery".equals(sourceDoc.getMimeType())) {
throw new ServletException("XQuery resource: " + query + " is not an XQuery or " + "declares a wrong mime-type");
}
sourceInfo = new SourceInfo(new DBSource(broker, (BinaryDocument) sourceDoc, true), locationUri.toString());
} catch (final PermissionDeniedException e) {
throw new ServletException("permission denied to read module source from " + query);
}
} catch (final URISyntaxException e) {
throw new ServletException(e.getMessage(), e);
}
} else {
try {
sourceInfo = new SourceInfo(SourceFactory.getSource(broker, moduleLoadPath, query, true), moduleLoadPath);
} catch (final IOException e) {
throw new ServletException("IO error while reading XQuery source: " + query);
} catch (final PermissionDeniedException e) {
throw new ServletException("Permission denied while reading XQuery source: " + query);
}
}
return sourceInfo;
}
use of org.exist.dom.persistent.LockedDocument in project exist by eXist-db.
the class BinaryDoc method eval.
@Override
public Sequence eval(final Sequence[] args, final Sequence contextSequence) throws XPathException {
final Sequence emptyParamReturnValue = (isCalledAs(FS_BINARY_DOC_NAME) || isCalledAs(FS_BINARY_DOC_CONTENT_DIGEST_NAME)) ? Sequence.EMPTY_SEQUENCE : BooleanValue.FALSE;
if (args[0].isEmpty()) {
return emptyParamReturnValue;
}
final String path = args[0].getStringValue();
try (final LockedDocument lockedDoc = context.getBroker().getXMLResource(XmldbURI.xmldbUriFor(path), LockMode.READ_LOCK)) {
if (lockedDoc == null) {
return emptyParamReturnValue;
}
final DocumentImpl doc = lockedDoc.getDocument();
if (doc.getResourceType() != DocumentImpl.BINARY_FILE) {
return emptyParamReturnValue;
} else if (isCalledAs(FS_BINARY_DOC_NAME)) {
try (final Txn transaction = context.getBroker().continueOrBeginTransaction()) {
final BinaryDocument bin = (BinaryDocument) doc;
final InputStream is = context.getBroker().getBinaryResource(transaction, bin);
final Base64BinaryDocument b64doc = Base64BinaryDocument.getInstance(context, is);
b64doc.setUrl(path);
transaction.commit();
return b64doc;
}
} else if (isCalledAs(FS_BINARY_DOC_CONTENT_DIGEST_NAME)) {
final String algorithm = args[1].getStringValue();
final DigestType digestType;
try {
digestType = DigestType.forCommonName(algorithm);
} catch (final IllegalArgumentException e) {
throw new XPathException(this, "Invalid algorithm: " + algorithm, e);
}
try (final Txn transaction = context.getBroker().getBrokerPool().getTransactionManager().beginTransaction()) {
final BinaryDocument bin = (BinaryDocument) doc;
final MessageDigest messageDigest = context.getBroker().getBinaryResourceContentDigest(transaction, bin, digestType);
final InputStream is = new UnsynchronizedByteArrayInputStream(messageDigest.getValue());
final Sequence result = BinaryValueFromInputStream.getInstance(context, new HexBinaryValueType(), is);
transaction.commit();
return result;
}
} else {
return BooleanValue.TRUE;
}
} catch (final URISyntaxException e) {
logger.error("Invalid resource URI", e);
throw new XPathException(this, "Invalid resource uri", e);
} catch (final PermissionDeniedException e) {
logger.error("{}: permission denied to read resource", path, e);
throw new XPathException(this, path + ": permission denied to read resource");
} catch (final IOException | TransactionException e) {
logger.error("{}: I/O error while reading resource", path, e);
throw new XPathException(this, path + ": I/O error while reading resource", e);
}
}
use of org.exist.dom.persistent.LockedDocument in project exist by eXist-db.
the class XMLDBGetMimeType method eval.
public Sequence eval(Sequence[] args, Sequence contextSequence) throws XPathException {
final String path = new AnyURIValue(args[0].itemAt(0).getStringValue()).toString();
if (path.matches("^[a-z]+://.*")) {
// external
final MimeTable mimeTable = MimeTable.getInstance();
final MimeType mimeType = mimeTable.getContentTypeFor(path);
if (mimeType != null) {
return new StringValue(mimeType.getName());
}
} else {
// database
try {
XmldbURI pathUri = XmldbURI.xmldbUriFor(path);
// relative collection Path: add the current base URI
pathUri = context.getBaseURI().toXmldbURI().resolveCollectionPath(pathUri);
// try to open the document and acquire a lock
try (final LockedDocument lockedDoc = context.getBroker().getXMLResource(pathUri, LockMode.READ_LOCK)) {
if (lockedDoc != null) {
return new StringValue(lockedDoc.getDocument().getMimeType());
}
}
} catch (final Exception e) {
logger.error(e.getMessage());
throw new XPathException(this, e);
}
}
return Sequence.EMPTY_SEQUENCE;
}
Aggregations