Package org.modeshape.jcr.cache

Examples of org.modeshape.jcr.cache.ChildReference


                        for (NodeKey removed : changedChildren.getRemovals()) {
                            CachedNode persistent = persistedCache.getNode(removed);
                            if (persistent != null) {
                                if (appended != null && appended.hasChild(persistent.getKey())) {
                                    // the same node has been both removed and appended => reordered at the end
                                    ChildReference appendedChildRef = node.getChildReferences(this).getChild(persistent.getKey());
                                    newPath = pathFactory().create(sessionPaths.getPath(node), appendedChildRef.getSegment());
                                    Path oldPath = workspacePaths.getPath(persistent);
                                    changes.nodeReordered(persistent.getKey(), primaryType, mixinTypes, node.getKey(), newPath,
                                                          oldPath, null, queryable);
                                }
                            }

                        }
                    }

                    // Now change the children ...
                    translator.changeChildren(doc, changedChildren, appended);

                    // Generate events for renames, as this is only captured in the parent node ...
                    Map<NodeKey, Name> newNames = changedChildren.getNewNames();
                    if (!newNames.isEmpty()) {
                        for (Map.Entry<NodeKey, Name> renameEntry : newNames.entrySet()) {
                            NodeKey renamedKey = renameEntry.getKey();
                            CachedNode oldRenamedNode = persistedCache.getNode(renamedKey);
                            if (oldRenamedNode == null) {
                                // The node was created in this session, so we can ignore this ...
                                continue;
                            }
                            Path renamedFromPath = workspacePaths.getPath(oldRenamedNode);
                            Path renamedToPath = pathFactory().create(renamedFromPath.getParent(), renameEntry.getValue());
                            changes.nodeRenamed(renamedKey, renamedToPath, renamedFromPath.getLastSegment(), primaryType,
                                                mixinTypes, queryable);
                            if (isExternal) {
                                renamedExternalNodes.add(renamedKey);
                            }
                        }
                    }

                    // generate reordering events for nodes which have not been reordered to the end
                    Map<NodeKey, SessionNode.Insertions> insertionsByBeforeKey = changedChildren.getInsertionsByBeforeKey();
                    for (SessionNode.Insertions insertion : insertionsByBeforeKey.values()) {
                        for (ChildReference insertedRef : insertion.inserted()) {
                            CachedNode insertedNodePersistent = persistedCache.getNode(insertedRef);
                            CachedNode insertedNode = getNode(insertedRef.getKey());
                            Path nodeNewPath = sessionPaths.getPath(insertedNode);
                            if (insertedNodePersistent != null) {
                                Path nodeOldPath = workspacePaths.getPath(insertedNodePersistent);
                                Path insertedBeforePath = null;
                                CachedNode insertedBeforeNode = persistedCache.getNode(insertion.insertedBefore());
                                if (insertedBeforeNode != null) {
                                    insertedBeforePath = workspacePaths.getPath(insertedBeforeNode);
                                    boolean isSnsReordering = nodeOldPath.getLastSegment().getName()
                                                                         .equals(insertedBeforePath.getLastSegment().getName());
                                    if (isSnsReordering) {
                                        nodeNewPath = insertedBeforePath;
                                    }
                                }
                                changes.nodeReordered(insertedRef.getKey(), insertedNode.getPrimaryType(this),
                                                      insertedNode.getMixinTypes(this), node.getKey(), nodeNewPath, nodeOldPath,
                                                      insertedBeforePath, queryable);

                            } else {
                                // if the node is new and reordered at the same time (most likely due to either a version restore
                                // or explicit reordering of transient nodes) there is no "old path"
                                CachedNode insertedBeforeNode = getNode(insertion.insertedBefore().getKey());
                                Path insertedBeforePath = sessionPaths.getPath(insertedBeforeNode);
                                changes.nodeReordered(insertedRef.getKey(), insertedNode.getPrimaryType(this),
                                                      insertedNode.getMixinTypes(this), node.getKey(), nodeNewPath, null,
                                                      insertedBeforePath, queryable);
                            }
                        }
                    }
                }

                ReferrerChanges referrerChanges = node.getReferrerChanges();
                boolean nodeChanged = false;
                if (referrerChanges != null && !referrerChanges.isEmpty()) {
                    translator.changeReferrers(doc, referrerChanges);
                    changes.nodeChanged(key, newPath, primaryType, mixinTypes, queryable);
                    nodeChanged = true;
                }

                // write the federated segments
                for (Map.Entry<String, String> federatedSegment : node.getAddedFederatedSegments().entrySet()) {
                    String externalNodeKey = federatedSegment.getKey();
                    String childName = federatedSegment.getValue();
                    translator.addFederatedSegment(doc, externalNodeKey, childName);
                    if (!nodeChanged) {
                        changes.nodeChanged(key, newPath, primaryType, mixinTypes, queryable);
                        nodeChanged = true;
                    }
                }
                Set<String> removedFederatedSegments = node.getRemovedFederatedSegments();
                if (!removedFederatedSegments.isEmpty()) {
                    translator.removeFederatedSegments(doc, node.getRemovedFederatedSegments());
                    if (!nodeChanged) {
                        changes.nodeChanged(key, newPath, primaryType, mixinTypes, queryable);
                        nodeChanged = true;
                    }
                }

                // write additional node "metadata", meaning various flags which have internal meaning
                if (!queryable) {
                    // we are only interested if the node is not queryable, as by default all nodes are queryable.
                    translator.setQueryable(doc, false);
                }

                if (node.isNew()) {
                    // We need to create the schematic entry for the new node ...
                    if (documentStore.storeDocument(keyStr, doc) != null) {
                        if (replacedNodes != null && replacedNodes.contains(key)) {
                            // Then a node is being removed and recreated with the same key ...
                            documentStore.localStore().put(keyStr, doc);
                        } else if (removedNodes != null && removedNodes.contains(key)) {
                            // Then a node is being removed and recreated with the same key ...
                            documentStore.localStore().put(keyStr, doc);
                            removedNodes.remove(key);
                        } else {
                            // We couldn't create the entry because one already existed ...
                            throw new DocumentAlreadyExistsException(keyStr);
                        }
                    }
                } else {
                    boolean externalNodeChanged = isExternal
                                                  && (hasPropertyChanges || node.hasNonPropertyChanges() || node.changedChildren()
                                                                                                                .renameCount() > 0);

                    // writable connectors *may* change their data in-place, so the update operation needs to be called only
                    // after the index changes have finished.
                    if (externalNodeChanged) {
                        // in the case of external nodes, only if there are changes should the update be called
                        documentStore.updateDocument(keyStr, doc, node);
                    }
                }

                // The above code doesn't properly generate events for newly linked or unlinked nodes (e.g., shareable nodes
                // in JCR), because NODE_ADDED or NODE_REMOVED events are generated based upon the creation or removal of the
                // child nodes, whereas linking and unlinking nodes don't result in creation/removal of nodes. Instead,
                // the linked/unlinked node is modified with the addition/removal of additional parents.
                //
                // NOTE that this happens somewhat rarely (as linked/shared nodes are used far less frequently) ...
                //
                if (additionalParents != null) {
                    // Generate NODE_ADDED events for each of the newly-added parents ...
                    for (NodeKey parentKey : additionalParents.getAdditions()) {
                        // Find the mutable parent node (if it exists) ...
                        SessionNode parent = this.changedNodes.get(parentKey);
                        if (parent != null) {
                            // Then the parent was changed in this session, so find the one-and-only child reference ...
                            ChildReference ref = parent.getChildReferences(this).getChild(key);
                            Path parentPath = sessionPaths.getPath(parent);
                            Path childPath = pathFactory().create(parentPath, ref.getSegment());
                            changes.nodeCreated(key, parentKey, childPath, primaryType, mixinTypes, null, queryable);
                        }
                    }
                    // Generate NODE_REMOVED events for each of the newly-removed parents ...
                    for (NodeKey parentKey : additionalParents.getRemovals()) {
                        // We need to read some information from the parent node before it was changed ...
                        CachedNode persistedParent = persistedCache.getNode(parentKey);
                        if (persistedParent != null) {
                            // Find the path to the removed child ...
                            ChildReference ref = persistedParent.getChildReferences(this).getChild(key);
                            if (ref != null) {
                                Path parentPath = workspacePaths.getPath(persistedParent);
                                Path childPath = pathFactory().create(parentPath, ref.getSegment());
                                changes.nodeRemoved(key, parentKey, childPath, primaryType, mixinTypes, queryable);
                            }
                        }
                    }
                }
View Full Code Here


                    return original.hasNext();
                }

                @Override
                public ChildReference next() {
                    ChildReference ref = original.next();
                    return ref.with(context.consume(ref.getName(), ref.getKey()));
                }

                @Override
                public void remove() {
                    throw new UnsupportedOperationException();
                }
            };
        }
        // There ARE changes, so the iterator needs to take these into account ...
        return new Iterator<ChildReference>() {
            private Iterator<ChildReference> delegate = original;
            private Iterator<ChildReference> iter = delegate;
            private ChildReference next;
            private ChildReference nextAfterIter;

            @Override
            public boolean hasNext() {
                while (next == null && iter.hasNext()) {
                    // Verify the next reference is valid ...
                    ChildReference next = iter.next();

                    // See if there are any nodes inserted before this node ...
                    ChildInsertions insertions = changes.insertionsBefore(next);
                    if (insertions != null && nextAfterIter != next) { // prevent circular references
                        if (nextAfterIter == null) {
                            nextAfterIter = next;
                        }
                        iter = insertions.inserted().iterator();
                        continue;
                    }

                    // See if this child has been removed but not inserted ...
                    if (changes.isRemoved(next) && changes.inserted(next.getKey()) == null) continue;

                    // See if this child has been renamed ...
                    Name newName = changes.renamed(next.getKey());
                    if (newName != null) {
                        next = next.with(newName, 1);
                    }

                    this.next = next;
                }
                if (iter != delegate) {
                    // This was an insertion iterator, so switch back to the delegate iterator ...
                    try {
                        iter = delegate;
                        // But the next ref will actually be the 'next' we found before the inserted ...
                        next = nextAfterIter;
                        return true;
                    } finally {
                        nextAfterIter = null;
                    }
                }
                return next != null;
            }

            @Override
            public ChildReference next() {
                try {
                    if (next == null) {
                        if (!hasNext()) {
                            throw new NoSuchElementException();
                        }
                    }
                    return next.with(context.consume(next.getName(), next.getKey()));
                } finally {
                    next = null;
                }
            }
View Full Code Here

    protected CachedNode getNodeAtPath( Path path,
                                        NodeCache cache ) {
        CachedNode node = cache.getNode(cache.getRootKey());
        for (Segment segment : path) {
            ChildReference childRef = node.getChildReferences(cache).getChild(segment);
            if (childRef == null) return null;
            node = cache.getNode(childRef);
        }
        return node;
    }
View Full Code Here

        List<?> children = document.getArray(CHILDREN);
        LinkedHashSet<ChildReference> newChildren = new LinkedHashSet<ChildReference>();
        if (children != null) {
            // process existing children
            for (Object value : children) {
                ChildReference ref = childReferenceFrom(value);
                if (ref == null) {
                    continue;
                }
                NodeKey childKey = ref.getKey();
                // Are nodes inserted before this node?
                Insertions insertions = insertionsByBeforeKey.remove(childKey);
                if (insertions != null) {
                    for (ChildReference inserted : insertions.inserted()) {
                        newChildren.add(inserted);
                    }
                }
                if (removals.remove(childKey)) {
                    // The node is removed ...
                } else {
                    // The node remains ...
                    Name newName = newNames.get(childKey);
                    if (newName != null) {
                        // But has been renamed ...
                        ref = ref.with(newName, 1);
                    }
                    newChildren.add(ref);
                }
            }
        }
View Full Code Here

            String keyStr = doc.getString(KEY);
            NodeKey key = new NodeKey(keyStr);
            String nameStr = doc.getString(NAME);
            Name name = names.create(nameStr, decoder);
            // We always use 1 for the SNS index, since the SNS index is dependent upon SNS nodes before it
            return new ChildReference(key, name, 1);
        }
        return null;
    }
View Full Code Here

        if (context == null) context = new SingleNameContext();
        Lock lock = this.lock.readLock();
        try {
            lock.lock();

            ChildReference ref = childReferencesByKey.get(key);
            if (ref != null) {
                // It's in this list but there are no changes ...
                List<ChildReference> childrenWithSameName = this.childReferences.get(ref.getName());
                assert childrenWithSameName != null;
                assert childrenWithSameName.size() != 0;
                // Consume the child references until we find the reference ...
                for (ChildReference child : childrenWithSameName) {
                    int index = context.consume(child.getName(), child.getKey());
View Full Code Here

        }
    }

    public void append( NodeKey key,
                        Name name ) {
        ChildReference reference = new ChildReference(key, name, 1);
        Lock lock = this.lock.writeLock();
        try {
            lock.lock();
            ChildReference old = this.childReferencesByKey.put(reference.getKey(), reference);
            if (old != null && old.getName().equals(name)) {
                // We already have this key/name pair, so we don't need to add it again ...
                return;
            }
            // We've not seen this node key yet, so it is okay. In fact, we should not see any
            // node key more than once, since that is clearly an unexpected condition (as a child
View Full Code Here

        Lock lock = this.lock.writeLock();
        try {
            lock.lock();
            for (ChildReference reference : references) {
                reference = reference.with(1);
                ChildReference old = this.childReferencesByKey.put(reference.getKey(), reference);
                if (old != null && old.getName().equals(reference.getName())) {
                    // We already have this key/name pair, so we don't need to add it again ...
                    continue;
                }
                // We've not seen this node key yet, so it is okay. In fact, we should not see any
                // node key more than once, since that is clearly an unexpected condition (as a child
View Full Code Here

    public ChildReference remove( NodeKey key ) {
        Lock lock = this.lock.writeLock();
        try {
            lock.lock();
            ChildReference existing = this.childReferencesByKey.remove(key);
            if (existing != null) {
                this.childReferences.remove(existing.getName(), existing);
            }
            return existing;
        } finally {
            lock.unlock();
        }
View Full Code Here

     * @throws NodeNotFoundInParentException if the node doesn't exist in the referenced parent
     */
    protected final Segment getSegment( NodeCache cache,
                                        CachedNode parent ) {
        if (parent != null) {
            ChildReference ref = parent.getChildReferences(cache).getChild(key, new BasicContext());
            if (ref == null) {
                // This node doesn't exist in the parent
                throw new NodeNotFoundInParentException(key, parent.getKey());
            }
            return ref.getSegment();
        }
        // This is the root node ...
        return workspace(cache).childReferenceForRoot().getSegment();
    }
View Full Code Here

TOP

Related Classes of org.modeshape.jcr.cache.ChildReference

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.