Search in sources :

Example 36 with Database

use of org.exist.Database in project exist by eXist-db.

the class MutableCollection method validateXMLResourceInternal.

/**
 * Validates an XML document et prepares it for further storage. Launches prepare and postValidate triggers.
 * Since the process is dependant from the collection configuration, the collection acquires a write lock during
 * the process.
 *
 * @param transaction The database transaction
 * @param broker      The database broker
 * @param name        the name (without path) of the document
 * @param validator   A function which validates the document of throws an Exception
 *
 * @return An {@link IndexInfo} with a write lock on the document.
 */
private IndexInfo validateXMLResourceInternal(final Txn transaction, final DBBroker broker, final XmldbURI name, final CollectionConfiguration config, final Consumer2E<IndexInfo, SAXException, EXistException> validator) throws EXistException, PermissionDeniedException, TriggerException, SAXException, LockException, IOException {
    // Make the necessary operations if we process a collection configuration document
    checkConfigurationDocument(transaction, broker, name);
    final Database db = broker.getBrokerPool();
    if (db.isReadOnly()) {
        throw new IOException("Database is read-only");
    }
    ManagedDocumentLock documentWriteLock = null;
    DocumentImpl oldDoc = null;
    db.getProcessMonitor().startJob(ProcessMonitor.ACTION_VALIDATE_DOC, name);
    try {
        try (final ManagedCollectionLock collectionLock = lockManager.acquireCollectionWriteLock(path)) {
            // acquire the WRITE_LOCK on the Document, this lock is released in storeXMLInternal via IndexInfo
            documentWriteLock = lockManager.acquireDocumentWriteLock(getURI().append(name.lastSegment()));
            oldDoc = documents.get(name.lastSegmentString());
            checkPermissionsForAddDocument(broker, oldDoc);
            // NOTE: the new `document` object actually gets discarded in favour of the `oldDoc` below if there is an oldDoc and it is XML (so we can use -1 as the docId because it will never be used)
            final int docId = (oldDoc != null && oldDoc.getResourceType() == DocumentImpl.XML_FILE) ? -1 : broker.getNextResourceId(transaction);
            DocumentImpl document = new DocumentImpl((BrokerPool) db, this, docId, name);
            checkCollectionConflict(name);
            manageDocumentInformation(oldDoc, document);
            final Indexer indexer = new Indexer(broker, transaction);
            final IndexInfo info = new IndexInfo(indexer, config, documentWriteLock);
            info.setCreating(oldDoc == null);
            info.setOldDocPermissions(oldDoc != null ? oldDoc.getPermissions() : null);
            indexer.setDocument(document, config);
            indexer.setValidating(true);
            final DocumentTriggers trigger = new DocumentTriggers(broker, transaction, indexer, this, broker.isTriggersEnabled() ? config : null);
            trigger.setValidating(true);
            info.setTriggers(trigger);
            if (oldDoc == null) {
                trigger.beforeCreateDocument(broker, transaction, getURI().append(name));
            } else {
                trigger.beforeUpdateDocument(broker, transaction, oldDoc);
            }
            if (LOG.isDebugEnabled()) {
                LOG.debug("Scanning document {}", getURI().append(name));
            }
            validator.accept(info);
            // new document is valid: remove old document
            if (oldDoc != null) {
                if (LOG.isDebugEnabled()) {
                    LOG.debug("removing old document {}", oldDoc.getFileURI());
                }
                updateModificationTime(document);
                /**
                 * Matching {@link StreamListener#endReplaceDocument(Txn)} call is in
                 * {@link #storeXMLInternal(Txn, DBBroker, IndexInfo, Consumer2E)}
                 */
                final StreamListener listener = broker.getIndexController().getStreamListener(document, StreamListener.ReindexMode.REPLACE_DOCUMENT);
                listener.startReplaceDocument(transaction);
                if (oldDoc.getResourceType() == DocumentImpl.BINARY_FILE) {
                    // TODO : use a more elaborated method ? No triggers...
                    broker.removeBinaryResource(transaction, (BinaryDocument) oldDoc);
                    documents.remove(oldDoc.getFileURI().lastSegmentString());
                    addDocument(transaction, broker, document);
                } else {
                    // TODO : use a more elaborated method ? No triggers...
                    broker.removeXMLResource(transaction, oldDoc, false);
                    oldDoc.copyOf(broker, document, oldDoc);
                    indexer.setDocumentObject(oldDoc);
                    // old has become new at this point
                    document = oldDoc;
                }
                if (LOG.isDebugEnabled()) {
                    LOG.debug("removed old document {}", oldDoc.getFileURI());
                }
            } else {
                addDocument(transaction, broker, document);
            }
            trigger.setValidating(false);
            return info;
        }
    } catch (final EXistException | PermissionDeniedException | SAXException | LockException | IOException e) {
        // if there is an exception and we hold the document WRITE_LOCK we must release it
        if (documentWriteLock != null) {
            documentWriteLock.close();
        }
        throw e;
    } finally {
        db.getProcessMonitor().endJob();
    }
}
Also used : EXistException(org.exist.EXistException) SAXException(org.xml.sax.SAXException) Indexer(org.exist.Indexer) LockException(org.exist.util.LockException) Database(org.exist.Database) PermissionDeniedException(org.exist.security.PermissionDeniedException) StreamListener(org.exist.indexing.StreamListener)

Example 37 with Database

use of org.exist.Database in project exist by eXist-db.

the class MutableCollection method addBinaryResource.

@Deprecated
@Override
public BinaryDocument addBinaryResource(final Txn transaction, final DBBroker broker, final XmldbURI name, final InputStream is, final String mimeType, final long size, final Date created, final Date modified, @Nullable final Permission permission) throws EXistException, PermissionDeniedException, LockException, TriggerException, IOException {
    final Database db = broker.getBrokerPool();
    if (db.isReadOnly()) {
        throw new IOException("Database is read-only");
    }
    final XmldbURI uri = getURI().append(name.lastSegment());
    try (final ManagedCollectionLock collectionLock = lockManager.acquireCollectionWriteLock(path);
        final ManagedDocumentLock docLock = lockManager.acquireDocumentWriteLock(uri)) {
        final DocumentImpl oldDoc = getDocument(broker, name);
        final int docId = broker.getNextResourceId(transaction);
        final BinaryDocument blob;
        if (oldDoc != null) {
            blob = new BinaryDocument(docId, oldDoc);
        } else {
            blob = new BinaryDocument(broker.getBrokerPool(), this, docId, name);
        }
        return addBinaryResource(db, transaction, broker, blob, is, mimeType, size, created, modified, permission, DBBroker.PreserveType.DEFAULT, oldDoc, collectionLock);
    }
}
Also used : Database(org.exist.Database) XmldbURI(org.exist.xmldb.XmldbURI)

Example 38 with Database

use of org.exist.Database in project exist by eXist-db.

the class MutableCollection method addBinaryResource.

@Deprecated
@Override
public BinaryDocument addBinaryResource(final Txn transaction, final DBBroker broker, final BinaryDocument blob, final InputStream is, final String mimeType, final long size, final Date created, final Date modified, final DBBroker.PreserveType preserve) throws EXistException, PermissionDeniedException, LockException, TriggerException, IOException {
    final Database db = broker.getBrokerPool();
    if (db.isReadOnly()) {
        throw new IOException("Database is read-only");
    }
    final XmldbURI docUri = blob.getFileURI();
    try (final ManagedCollectionLock collectionLock = lockManager.acquireCollectionWriteLock(path);
        final ManagedDocumentLock docLock = lockManager.acquireDocumentWriteLock(blob.getURI())) {
        final DocumentImpl oldDoc = getDocument(broker, docUri);
        return addBinaryResource(db, transaction, broker, blob, is, mimeType, size, created, modified, null, preserve, oldDoc, collectionLock);
    }
}
Also used : Database(org.exist.Database) XmldbURI(org.exist.xmldb.XmldbURI)

Example 39 with Database

use of org.exist.Database in project exist by eXist-db.

the class MutableCollection method storeXMLInternal.

/**
 * Stores an XML document in the database. {@link #validateXMLResourceInternal(Txn, DBBroker, XmldbURI,
 * CollectionConfiguration, Consumer2E)}should have been called previously in order to acquire a write lock
 * for the document. Launches the finish trigger.
 *
 * @param transaction The database transaction
 * @param broker      The database broker
 * @param info        Tracks information between validate and store phases
 * @param parserFn    A function which parses the XML document
 */
private void storeXMLInternal(final Txn transaction, final DBBroker broker, final IndexInfo info, final Consumer2E<IndexInfo, EXistException, SAXException> parserFn) throws EXistException, SAXException, PermissionDeniedException {
    final DocumentImpl document = info.getIndexer().getDocument();
    final Database db = broker.getBrokerPool();
    try {
        if (LOG.isDebugEnabled()) {
            LOG.debug("storing document {} ...", document.getDocId());
        }
        // Sanity check
        if (!lockManager.isDocumentLockedForWrite(document.getURI())) {
            LOG.warn("document is not locked for write !");
        }
        db.getProcessMonitor().startJob(ProcessMonitor.ACTION_STORE_DOC, document.getFileURI());
        parserFn.accept(info);
        broker.storeXMLResource(transaction, document);
        broker.flush();
        broker.closeDocument();
        // broker.checkTree(document);
        LOG.debug("document stored.");
    } finally {
        // This lock has been acquired in validateXMLResourceInternal()
        info.getDocumentLock().close();
        broker.getBrokerPool().getProcessMonitor().endJob();
    }
    if (info.isCreating()) {
        info.getTriggers().afterCreateDocument(broker, transaction, document);
    } else {
        final StreamListener listener = broker.getIndexController().getStreamListener();
        listener.endReplaceDocument(transaction);
        info.getTriggers().afterUpdateDocument(broker, transaction, document);
    }
    db.getNotificationService().notifyUpdate(document, (info.isCreating() ? UpdateListener.ADD : UpdateListener.UPDATE));
    // Is it a collection configuration file ?
    final XmldbURI docName = document.getFileURI();
    // TODO: *resolve* URI against CollectionConfigurationManager.CONFIG_COLLECTION_URI
    if (getURI().startsWith(XmldbURI.CONFIG_COLLECTION_URI) && docName.endsWith(CollectionConfiguration.COLLECTION_CONFIG_SUFFIX_URI)) {
        broker.sync(Sync.MAJOR);
        final CollectionConfigurationManager manager = broker.getBrokerPool().getConfigurationManager();
        if (manager != null) {
            try {
                manager.invalidate(getURI(), broker.getBrokerPool());
                manager.loadConfiguration(broker, this);
            } catch (final PermissionDeniedException | LockException pde) {
                throw new EXistException(pde.getMessage(), pde);
            } catch (final CollectionConfigurationException e) {
                // DIZ: should this exception really been thrown? bugid=1807744
                throw new EXistException("Error while reading new collection configuration: " + e.getMessage(), e);
            }
        }
    }
}
Also used : LockException(org.exist.util.LockException) Database(org.exist.Database) PermissionDeniedException(org.exist.security.PermissionDeniedException) EXistException(org.exist.EXistException) XmldbURI(org.exist.xmldb.XmldbURI) StreamListener(org.exist.indexing.StreamListener)

Example 40 with Database

use of org.exist.Database in project exist by eXist-db.

the class AbstractGroupTest method addManager_calls_assertCanModifyGroup.

@Test
public void addManager_calls_assertCanModifyGroup() throws PermissionDeniedException, NoSuchMethodException {
    DBBroker mockBroker = EasyMock.createMock(DBBroker.class);
    AbstractRealm mockRealm = EasyMock.createMock(AbstractRealm.class);
    Subject mockSubject = EasyMock.createMock(Subject.class);
    Database mockDatabase = EasyMock.createMock(Database.class);
    Group partialMockGroup = EasyMock.createMockBuilder(AbstractGroup.class).withConstructor(DBBroker.class, AbstractRealm.class, int.class, String.class, List.class).withArgs(mockBroker, mockRealm, 1, "testGroup", null).addMockedMethod("assertCanModifyGroup", Account.class).addMockedMethod(AbstractGroup.class.getDeclaredMethod("_addManager", Account.class)).createNiceMock();
    // expectations
    expect(mockRealm.getDatabase()).andReturn(mockDatabase);
    expect(mockDatabase.getActiveBroker()).andReturn(mockBroker);
    expect(mockBroker.getCurrentSubject()).andReturn(mockSubject);
    partialMockGroup.assertCanModifyGroup(mockSubject);
    replay(mockRealm, mockDatabase, mockBroker, partialMockGroup);
    // test
    partialMockGroup.addManager((Account) null);
    verify(mockRealm, mockDatabase, mockBroker, partialMockGroup);
}
Also used : DBBroker(org.exist.storage.DBBroker) Database(org.exist.Database) Test(org.junit.Test)

Aggregations

Database (org.exist.Database)42 DBBroker (org.exist.storage.DBBroker)34 Test (org.junit.Test)29 EXistException (org.exist.EXistException)6 SecurityManager (org.exist.security.SecurityManager)5 BrokerPool (org.exist.storage.BrokerPool)4 XmldbURI (org.exist.xmldb.XmldbURI)4 XQuery (org.exist.xquery.XQuery)4 IOException (java.io.IOException)3 Random (java.util.Random)3 PermissionDeniedException (org.exist.security.PermissionDeniedException)3 CompiledXQuery (org.exist.xquery.CompiledXQuery)3 Ignore (org.junit.Ignore)3 StringWriter (java.io.StringWriter)2 Collection (org.exist.collections.Collection)2 Configuration (org.exist.config.Configuration)2 StreamListener (org.exist.indexing.StreamListener)2 SecurityManagerImpl (org.exist.security.internal.SecurityManagerImpl)2 Serializer (org.exist.storage.serializers.Serializer)2 Configuration (org.exist.util.Configuration)2