public void begin()

in jackrabbit-core/src/main/java/org/apache/jackrabbit/core/state/SharedItemStateManager.java [570:781]


        public void begin() throws ItemStateException, ReferentialIntegrityException {
            shared = new ChangeLog();

            virtualNodeReferences = new ChangeLog[virtualProviders.length];

            // let listener know about change
            try {
                eventChannel.updateCreated(this);
            } catch (ClusterException e) {
                throw new ItemStateException(e.getMessage(), e);
            }

            try {
                writeLock = acquireWriteLock(local);
            } finally {
                if (writeLock == null) {
                    eventChannel.updateCancelled(this);
                }
            }

            boolean succeeded = false;

            try {
                if (usesReferences) {
                    // Update node references based on modifications in change
                    // log (added/modified/removed REFERENCE properties)
                    updateReferences();
                }

                // If enabled, check whether reference targets
                // exist/were not removed
                if (checkReferences) {
                    checkReferentialIntegrity();
                }

                /**
                 * prepare the events. this needs to be after the referential
                 * integrity check, since another transaction could have modified
                 * the states.
                 */
                try {
                    events = factory.createEventStateCollection();
                } catch (RepositoryException e) {
                    String msg = "Unable to create event state collection.";
                    log.error(msg);
                    throw new ItemStateException(msg, e);
                }

                /**
                 * Reconnect all items contained in the change log to their
                 * respective shared item and add the shared items to a
                 * new change log.
                 */
                for (ItemState state : local.modifiedStates()) {
                    state.connect(getItemState(state.getId()));
                    if (state.isStale()) {
                        boolean merged = false;
                        if (state.isNode()) {
                            NodeStateMerger.MergeContext context =
                                    new NodeStateMerger.MergeContext() {
                                        public boolean isAdded(ItemId id) {
                                            try {
                                                ItemState is = local.get(id);
                                                return is != null
                                                        && is.getStatus() == ItemState.STATUS_NEW;
                                            } catch (NoSuchItemStateException e) {
                                                return false;
                                            }
                                        }

                                        public boolean isDeleted(ItemId id) {
                                            return local.deleted(id);
                                        }

                                        public boolean isModified(ItemId id) {
                                            return local.isModified(id);
                                        }

                                        public boolean allowsSameNameSiblings(NodeId id) {
                                            try {
                                                NodeState ns = getNodeState(id);
                                                NodeState parent = getNodeState(ns.getParentId());
                                                Name name = parent.getChildNodeEntry(id).getName();
                                                EffectiveNodeType ent = ntReg.getEffectiveNodeType(
                                                        parent.getNodeTypeName(),
                                                        parent.getMixinTypeNames());
                                                QNodeDefinition def = ent.getApplicableChildNodeDef(name, ns.getNodeTypeName(), ntReg);
                                                return def != null ? def.allowsSameNameSiblings() : false;
                                            } catch (Exception e) {
                                                log.warn("Unable to get node definition", e);
                                                return false;
                                            }
                                        }

                                        public EffectiveNodeType getEffectiveNodeType(Name ntName) throws NoSuchNodeTypeException {
                                            return ntReg.getEffectiveNodeType(ntName);
                                        }

                                        public NodeState getNodeState(NodeId id)
                                                throws ItemStateException {
                                            if (local.has(id)) {
                                                return (NodeState) local.get(id);
                                            } else {
                                                return (NodeState) getItemState(id);
                                            }
                                        }
                                    };

                            merged = NodeStateMerger.merge((NodeState) state, context);
                        }
                        if (!merged) {
                            String msg = state.getId() + " has been modified externally";
                            log.debug(msg);
                            throw new StaleItemStateException(msg);
                        }
                        // merge succeeded, fall through
                    }

                    // update modification count (will be persisted as well)
                    state.getOverlayedState().touch();

                    shared.modified(state.getOverlayedState());
                }
                Iterator<ItemState> deleted = local.deletedStates().iterator();
                while (deleted.hasNext()) {
                    ItemState state = deleted.next();
                    try {
                        state.connect(getItemState(state.getId()));
                        if (state.isStale()) {
                            String msg = state.getId() + " has been modified externally";
                            log.debug(msg);
                            throw new StaleItemStateException(msg);
                        }
                        shared.deleted(state.getOverlayedState());
                    } catch (NoSuchItemStateException e) {
                        // item state was already deleted externally
                        deleted.remove();
                    }
                }
                for (ItemState state : local.addedStates()) {
                    if (state.isNode() && state.getStatus() != ItemState.STATUS_NEW) {
                        // another node with same id had been created
                        // in the meantime, probably caused by mid-air collision
                        // of concurrent versioning operations (JCR-2272)
                        String msg = state.getId()
                                + " has been created externally  (status "
                                + state.getStatus() + ")";
                        log.debug(msg);
                        throw new StaleItemStateException(msg);
                    }
                    state.connect(createInstance(state));
                    shared.added(state.getOverlayedState());
                }

                // filter out virtual node references for later processing
                // (see comment above)
                for (NodeReferences refs : local.modifiedRefs()) {
                    boolean virtual = false;
                    NodeId id = refs.getTargetId();
                    for (int i = 0; i < virtualProviders.length; i++) {
                        if (virtualProviders[i].hasItemState(id)) {
                            ChangeLog virtualRefs = virtualNodeReferences[i];
                            if (virtualRefs == null) {
                                virtualRefs = new ChangeLog();
                                virtualNodeReferences[i] = virtualRefs;
                            }
                            virtualRefs.modified(refs);
                            virtual = true;
                            break;
                        }
                    }
                    if (!virtual) {
                        // if target of node reference does not lie in a virtual
                        // space, add to modified set of normal provider.
                        shared.modified(refs);
                    }
                }

                checkAddedChildNodes();

                /* create event states */
                events.createEventStates(rootNodeId, local, SharedItemStateManager.this);

                // let listener know about change
                try {
                    eventChannel.updatePrepared(this);
                } catch (ClusterException e) {
                    throw new ItemStateException(e.getMessage(), e);
                }

                if (VALIDATE_HIERARCHY) {
                    log.debug("Validating change-set hierarchy");
                    try {
                        validateHierarchy(local);
                    } catch (ItemStateException e) {
                        throw e;
                    } catch (RepositoryException e) {
                        throw new ItemStateException("Invalid hierarchy", e);
                    }
                }

                /* Push all changes from the local items to the shared items */
                local.push();

                succeeded = true;

            } finally {
                if (!succeeded) {
                    cancel();
                }
            }
        }