use of org.apache.jackrabbit.core.id.PropertyId in project jackrabbit by apache.
the class NodeStateEx method store.
/**
* stores the given persistent state recursively
*
* @param state node state to store
* @throws ItemStateException if an error occurs
*/
private void store(NodeState state, boolean recursively) throws ItemStateException {
if (state.getStatus() != ItemState.STATUS_EXISTING) {
// first store all transient properties
for (Name propName : state.getPropertyNames()) {
PropertyState pstate = (PropertyState) stateMgr.getItemState(new PropertyId(state.getNodeId(), propName));
if (pstate.getStatus() != ItemState.STATUS_EXISTING) {
stateMgr.store(pstate);
}
}
if (recursively) {
// now store all child node entries
for (ChildNodeEntry entry : state.getChildNodeEntries()) {
NodeState nstate = (NodeState) stateMgr.getItemState(entry.getId());
store(nstate, true);
}
}
// and store itself
stateMgr.store(state);
}
}
use of org.apache.jackrabbit.core.id.PropertyId in project jackrabbit by apache.
the class NodeStateMerger method merge.
/**
* Tries to silently merge the given <code>state</code> with its
* externally (e.g. through another session) modified overlayed state
* in order to avoid an <code>InvalidItemStateException</code>.
* <p>
* See http://issues.apache.org/jira/browse/JCR-584.
* See also http://issues.apache.org/jira/browse/JCR-3290.
*
* @param state node state whose modified overlayed state should be
* merged
* @param context used for analyzing the context of the modifications
* @return true if the changes could be successfully merged into the
* given node state; false otherwise
*/
static boolean merge(NodeState state, MergeContext context) {
NodeState overlayedState = (NodeState) state.getOverlayedState();
if (overlayedState == null || state.getModCount() == overlayedState.getModCount()) {
return false;
}
synchronized (overlayedState) {
synchronized (state) {
// child node entries order
if (!state.getReorderedChildNodeEntries().isEmpty()) {
// a reorder operation
return false;
}
// the primary node type
if (!state.getNodeTypeName().equals(overlayedState.getNodeTypeName())) {
// the primary node type has changed either in 'state' or 'overlayedState'.
return false;
}
// mixin types
if (!mergeMixinTypes(state, overlayedState, context)) {
return false;
}
// parent id
if (state.getParentId() != null && !state.getParentId().equals(overlayedState.getParentId())) {
return false;
}
// child node entries
if (!state.getChildNodeEntries().equals(overlayedState.getChildNodeEntries())) {
ArrayList<ChildNodeEntry> added = new ArrayList<ChildNodeEntry>();
ArrayList<ChildNodeEntry> removed = new ArrayList<ChildNodeEntry>();
for (ChildNodeEntry cne : state.getAddedChildNodeEntries()) {
// locally added or moved?
if (context.isAdded(cne.getId()) || (context.isModified(cne.getId()) && isParent(state, cne, context))) {
// check for name collisions with other state
if (overlayedState.hasChildNodeEntry(cne.getName())) {
// conflicting names
if (cne.getIndex() < 2) {
// check if same-name siblings are allowed
if (!context.allowsSameNameSiblings(cne.getId())) {
return false;
}
}
// assume same-name siblings are allowed since index is >= 2
}
added.add(cne);
}
}
for (ChildNodeEntry cne : state.getRemovedChildNodeEntries()) {
// locally removed?
if (context.isDeleted(cne.getId()) || context.isModified(cne.getId())) {
// a child node entry has been removed from this node state
removed.add(cne);
}
}
// copy child node entries from other state and
// re-apply changes made on this state
state.setChildNodeEntries(overlayedState.getChildNodeEntries());
for (ChildNodeEntry cne : removed) {
state.removeChildNodeEntry(cne.getId());
}
for (ChildNodeEntry cne : added) {
state.addChildNodeEntry(cne.getName(), cne.getId());
}
}
// property names
if (!state.getPropertyNames().equals(overlayedState.getPropertyNames())) {
HashSet<Name> added = new HashSet<Name>();
HashSet<Name> removed = new HashSet<Name>();
for (Name name : state.getAddedPropertyNames()) {
PropertyId propId = new PropertyId(state.getNodeId(), name);
if (context.isAdded(propId)) {
added.add(name);
}
}
for (Name name : state.getRemovedPropertyNames()) {
PropertyId propId = new PropertyId(state.getNodeId(), name);
if (context.isDeleted(propId)) {
// a property name has been removed from this state
removed.add(name);
}
}
// copy property names from other and
// re-apply changes made on this state
state.setPropertyNames(overlayedState.getPropertyNames());
for (Name name : added) {
state.addPropertyName(name);
}
for (Name name : removed) {
state.removePropertyName(name);
}
}
// finally sync modification count
state.setModCount(overlayedState.getModCount());
return true;
}
}
}
use of org.apache.jackrabbit.core.id.PropertyId in project jackrabbit by apache.
the class SessionItemStateManager method createTransientPropertyState.
/**
* @param overlayedState
* @param initialStatus
* @return
* @throws ItemStateException
*/
public PropertyState createTransientPropertyState(PropertyState overlayedState, int initialStatus) throws ItemStateException {
PropertyId id = overlayedState.getPropertyId();
// check map; synchronized to ensure an entry is not created twice.
synchronized (transientStore) {
if (transientStore.containsKey(id)) {
String msg = "there's already a property state instance with id " + id;
log.debug(msg);
throw new ItemStateException(msg);
}
PropertyState state = new PropertyState(overlayedState, initialStatus, true);
// put transient state in the map
transientStore.put(id, state);
state.setContainer(this);
return state;
}
}
use of org.apache.jackrabbit.core.id.PropertyId in project jackrabbit by apache.
the class SessionItemStateManager method createTransientPropertyState.
/**
* @param parentId
* @param propName
* @param initialStatus
* @return
* @throws ItemStateException
*/
public PropertyState createTransientPropertyState(NodeId parentId, Name propName, int initialStatus) throws ItemStateException {
PropertyId id = new PropertyId(parentId, propName);
// check map; synchronized to ensure an entry is not created twice.
synchronized (transientStore) {
if (transientStore.containsKey(id)) {
String msg = "there's already a property state instance with id " + id;
log.debug(msg);
throw new ItemStateException(msg);
}
PropertyState state = new PropertyState(id, initialStatus, true);
// put transient state in the map
transientStore.put(id, state);
state.setContainer(this);
return state;
}
}
use of org.apache.jackrabbit.core.id.PropertyId in project jackrabbit by apache.
the class WorkspaceImporter method processProperty.
protected void processProperty(NodeState node, PropInfo pInfo) throws RepositoryException {
PropertyState prop;
QPropertyDefinition def;
Name name = pInfo.getName();
int type = pInfo.getType();
if (node.hasPropertyName(name)) {
// a property with that name already exists...
PropertyId idExisting = new PropertyId(node.getNodeId(), name);
prop = (PropertyState) itemOps.getItemState(idExisting);
def = itemOps.findApplicablePropertyDefinition(prop.getName(), prop.getType(), prop.isMultiValued(), node);
if (def.isProtected()) {
// skip protected property
log.debug("skipping protected property " + itemOps.safeGetJCRPath(idExisting));
return;
}
if (!def.isAutoCreated() || (prop.getType() != type && type != PropertyType.UNDEFINED) || def.isMultiple() != prop.isMultiValued()) {
throw new ItemExistsException(itemOps.safeGetJCRPath(prop.getPropertyId()));
}
} else {
// there's no property with that name,
// find applicable definition
def = pInfo.getApplicablePropertyDef(itemOps.getEffectiveNodeType(node));
if (def.isProtected()) {
// skip protected property
log.debug("skipping protected property " + name);
return;
}
// create new property
prop = itemOps.createPropertyState(node, name, type, def);
}
// check multi-valued characteristic
TextValue[] values = pInfo.getTextValues();
if (values.length != 1 && !def.isMultiple()) {
throw new ConstraintViolationException(itemOps.safeGetJCRPath(prop.getPropertyId()) + " is not multi-valued");
}
// convert serialized values to InternalValue objects
int targetType = pInfo.getTargetType(def);
InternalValue[] iva = new InternalValue[values.length];
for (int i = 0; i < values.length; i++) {
iva[i] = values[i].getInternalValue(targetType);
}
// set values
prop.setValues(iva);
// make sure property is valid according to its definition
itemOps.validate(prop);
if (prop.getType() == PropertyType.REFERENCE || prop.getType() == PropertyType.WEAKREFERENCE) {
// store reference for later resolution
refTracker.processedReference(prop);
}
// store property
itemOps.store(prop);
}
Aggregations