throws IOException, PermissionDeniedException, CollectionDoesNotExistException {
if(LOG.isDebugEnabled())
LOG.debug(String.format("Create '%s' in '%s'", newName, xmldbUri));
XmldbURI newNameUri = XmldbURI.create(newName);
// Get mime, or NULL when not available
MimeType mime = MimeTable.getInstance().getContentTypeFor(newName);
if (mime == null) {
mime = MimeType.BINARY_TYPE;
}
// References to the database
DBBroker broker = null;
Collection collection = null;
// create temp file and store. Existdb needs to read twice from a stream.
BufferedInputStream bis = new BufferedInputStream(is);
VirtualTempFile vtf = new VirtualTempFile();
BufferedOutputStream bos = new BufferedOutputStream(vtf);
// Perform actual copy
IOUtils.copy(bis, bos);
bis.close();
bos.close();
vtf.close();
// To support LockNullResource, a 0-byte XML document can received. Since 0-byte
// XML documents are not supported a small file will be created.
if (mime.isXMLType() && vtf.length() == 0L) {
if(LOG.isDebugEnabled())
LOG.debug(String.format("Creating dummy XML file for null resource lock '%s'", newNameUri));
vtf = new VirtualTempFile();
IOUtils.write("<null_resource/>", vtf);
vtf.close();
}
// Start transaction
TransactionManager txnManager = brokerPool.getTransactionManager();
Txn txn = txnManager.beginTransaction();
try {
broker = brokerPool.get(subject);
// Check if collection exists. not likely to happen since availability is checked
// by ResourceFactory
collection = broker.openCollection(xmldbUri, Lock.WRITE_LOCK);
if (collection == null) {
LOG.debug(String.format("Collection %s does not exist", xmldbUri));
txnManager.abort(txn);
throw new CollectionDoesNotExistException(xmldbUri + "");
}
if (mime.isXMLType()) {
if(LOG.isDebugEnabled())
LOG.debug(String.format("Inserting XML document '%s'", mime.getName()));
// Stream into database
VirtualTempFileInputSource vtfis = new VirtualTempFileInputSource(vtf);
IndexInfo info = collection.validateXMLResource(txn, broker, newNameUri, vtfis);
DocumentImpl doc = info.getDocument();
doc.getMetadata().setMimeType(mime.getName());
collection.store(txn, broker, info, vtfis, false);
} else {
if(LOG.isDebugEnabled())
LOG.debug(String.format("Inserting BINARY document '%s'", mime.getName()));
// Stream into database
InputStream fis = vtf.getByteStream();
bis = new BufferedInputStream(fis);
collection.addBinaryResource(txn, broker, newNameUri, bis, mime.getName(), length);
bis.close();
}
// Commit change
txnManager.commit(txn);
if (LOG.isDebugEnabled()) {
LOG.debug("Document created sucessfully");
}
} catch (EXistException | SAXException e) {
LOG.error(e);
txnManager.abort(txn);
throw new IOException(e);
} catch (LockException e) {
LOG.error(e);
txnManager.abort(txn);
throw new PermissionDeniedException(xmldbUri + "");
} catch (IOException | PermissionDeniedException e) {
LOG.error(e);
txnManager.abort(txn);
throw e;
} finally {
if (vtf != null) {
vtf.delete();
}
// TODO: check if can be done earlier
if (collection != null) {
collection.release(Lock.WRITE_LOCK);
}
txnManager.close(txn);
brokerPool.release(broker);
if(LOG.isDebugEnabled())
LOG.debug("Finished creation");
}
// Send the result back to the client
XmldbURI newResource = xmldbUri.append(newName);
return newResource;
}