use of org.apache.jackrabbit.core.value.InternalValue in project jackrabbit by apache.
the class VersionManagerImplBase method checkoutCheckin.
/**
* Performs a checkin or checkout operation. if <code>checkin</code> is
* <code>true</code> the node is checked in. if <code>checkout</code> is
* <code>true</code> the node is checked out. if both flags are <code>true</code>
* the checkin is performed prior to the checkout and the operation is
* equivalent to a checkpoint operation.
*
* @param state node state
* @param checkin if <code>true</code> the node is checked in.
* @param checkout if <code>true</code> the node is checked out.
* @param created create time of the new version (if any),
* or <code>null</code> for the current time
* @return the node id of the base version or <code>null</code> for a pure
* checkout.
* @throws RepositoryException if an error occurs
*/
protected NodeId checkoutCheckin(NodeStateEx state, boolean checkin, boolean checkout, Calendar created) throws RepositoryException {
assert (checkin || checkout);
// check if versionable
boolean isFull = checkVersionable(state);
// check flags
if (isCheckedOut(state)) {
if (checkout && !checkin) {
// pure checkout
String msg = safeGetJCRPath(state) + ": Node is already checked-out. ignoring.";
log.debug(msg);
return null;
}
} else {
if (!checkout) {
// pure checkin
String msg = safeGetJCRPath(state) + ": Node is already checked-in. ignoring.";
log.debug(msg);
if (isFull) {
return getBaseVersionId(state);
} else {
// get base version from version history
return vMgr.getHeadVersionOfNode(state.getNodeId()).getId();
}
}
checkin = false;
}
NodeId baseId = isFull && checkout ? vMgr.canCheckout(state, currentActivity) : null;
// perform operation
WriteOperation ops = startWriteOperation();
try {
// the 2 cases could be consolidated but is clearer this way
if (checkin) {
// check for configuration
if (state.getEffectiveNodeType().includesNodeType(NameConstants.NT_CONFIGURATION)) {
// collect the base versions and the the rep:versions property of the configuration
Set<NodeId> baseVersions = collectBaseVersions(state);
InternalValue[] vs = new InternalValue[baseVersions.size()];
int i = 0;
for (NodeId id : baseVersions) {
vs[i++] = InternalValue.create(id);
}
state.setPropertyValues(NameConstants.REP_VERSIONS, PropertyType.REFERENCE, vs);
state.store();
}
InternalVersion v = vMgr.checkin(session, state, created);
baseId = v.getId();
if (isFull) {
state.setPropertyValue(NameConstants.JCR_BASEVERSION, InternalValue.create(baseId));
state.setPropertyValues(NameConstants.JCR_PREDECESSORS, PropertyType.REFERENCE, InternalValue.EMPTY_ARRAY);
state.removeProperty(NameConstants.JCR_ACTIVITY);
}
}
if (checkout) {
if (isFull) {
state.setPropertyValues(NameConstants.JCR_PREDECESSORS, PropertyType.REFERENCE, new InternalValue[] { InternalValue.create(baseId) });
if (currentActivity != null) {
state.setPropertyValue(NameConstants.JCR_ACTIVITY, InternalValue.create(currentActivity));
}
}
}
state.setPropertyValue(NameConstants.JCR_ISCHECKEDOUT, InternalValue.create(checkout));
state.store();
ops.save();
return baseId;
} catch (ItemStateException e) {
throw new RepositoryException(e);
} finally {
ops.close();
}
}
use of org.apache.jackrabbit.core.value.InternalValue in project jackrabbit by apache.
the class InternalVersionManagerBase method calculateCheckinVersionName.
/**
* Calculates the name of the new version that will be created by a
* checkin call. The name is determined as follows:
* <ul>
* <li> first the predecessor version with the shortest name is searched.
* <li> if that predecessor version is the root version, the new version gets
* the name "{number of successors}+1" + ".0"
* <li> if that predecessor version has no successor, the last digit of it's
* version number is incremented.
* <li> if that predecessor version has successors but the incremented name
* does not exist, that name is used.
* <li> otherwise a ".0" is added to the name until a non conflicting name
* is found.
* </ul>
*
* Example Graph:
* <pre>
* jcr:rootVersion
* | |
* 1.0 2.0
* |
* 1.1
* |
* 1.2 ---\ ------\
* | \ \
* 1.3 1.2.0 1.2.0.0
* | |
* 1.4 1.2.1 ----\
* | | \
* 1.5 1.2.2 1.2.1.0
* | | |
* 1.6 | 1.2.1.1
* |-----/
* 1.7
* </pre>
*
* @param history the version history
* @param node the node to checkin
* @param simple if <code>true</code> indicates simple versioning
* @return the new version name
* @throws RepositoryException if an error occurs.
*/
protected String calculateCheckinVersionName(InternalVersionHistoryImpl history, NodeStateEx node, boolean simple) throws RepositoryException {
if (history == null) {
String message = "Node " + node.getNodeId() + " has no version history";
log.error(message);
throw new VersionException(message);
}
InternalVersion best = null;
if (simple) {
// 1. in simple versioning just take the 'head' version
Name[] names = history.getVersionNames();
best = history.getVersion(names[names.length - 1]);
} else {
// 1. search a predecessor, suitable for generating the new name
InternalValue[] values = node.getPropertyValues(NameConstants.JCR_PREDECESSORS);
if (values == null || values.length == 0) {
String message;
if (values == null) {
message = "Mandatory jcr:predecessors property missing on node " + node.getNodeId();
} else {
message = "Mandatory jcr:predecessors property is empty on node " + node.getNodeId();
}
log.error(message);
throw new VersionException(message);
}
for (InternalValue value : values) {
InternalVersion pred = history.getVersion(value.getNodeId());
if (pred == null) {
String message = "Could not instantiate InternalVersion for nodeId " + value.getNodeId() + " (VHR + " + history.getId() + ", node " + node.getNodeId() + ")";
log.error(message);
throw new VersionException(message);
}
if (best == null || pred.getName().getLocalName().length() < best.getName().getLocalName().length()) {
best = pred;
}
}
}
if (best == null) {
String message = "Could not find 'best' predecessor node for " + node.getNodeId();
log.error(message);
throw new VersionException(message);
}
// 2. generate version name (assume no namespaces in version names)
String versionName = best.getName().getLocalName();
int pos = versionName.lastIndexOf('.');
if (pos > 0) {
String newVersionName = versionName.substring(0, pos + 1) + (Integer.parseInt(versionName.substring(pos + 1)) + 1);
while (history.hasVersion(NameFactoryImpl.getInstance().create("", newVersionName))) {
versionName += ".0";
newVersionName = versionName;
}
return newVersionName;
} else {
// best is root version
return String.valueOf(best.getSuccessors().size() + 1) + ".0";
}
}
use of org.apache.jackrabbit.core.value.InternalValue in project jackrabbit by apache.
the class VersionManagerImplMerge method setMergeFailed.
/**
* Updates the merge failed property of the given state/
* @param state the state to update
* @param set the set of ids
* @throws RepositoryException if an error occurs
*/
private void setMergeFailed(NodeStateEx state, Set<NodeId> set) throws RepositoryException {
if (set.isEmpty()) {
state.removeProperty(NameConstants.JCR_MERGEFAILED);
} else {
InternalValue[] vals = new InternalValue[set.size()];
Iterator<NodeId> iter = set.iterator();
int i = 0;
while (iter.hasNext()) {
NodeId id = iter.next();
vals[i++] = InternalValue.create(id);
}
state.setPropertyValues(NameConstants.JCR_MERGEFAILED, PropertyType.REFERENCE, vals, true);
}
}
use of org.apache.jackrabbit.core.value.InternalValue in project jackrabbit by apache.
the class ChangeLogRecord method writeEventRecord.
/**
* Write an event record
*
* @param event event state
* @throws JournalException if an error occurs
*/
private void writeEventRecord(EventState event) throws JournalException {
record.writeChar(EVENT_IDENTIFIER);
record.writeByte(event.getType());
record.writeNodeId(event.getParentId());
record.writePath(event.getParentPath());
record.writeNodeId(event.getChildId());
record.writePathElement(event.getChildRelPath());
record.writeQName(event.getNodeType());
Set<Name> mixins = event.getMixinNames();
record.writeInt(mixins.size());
for (Name mixin : mixins) {
record.writeQName(mixin);
}
record.writeString(event.getUserId());
if (event.getType() == Event.NODE_MOVED) {
// write info map
Map<String, InternalValue> info = event.getInfo();
record.writeInt(info.size());
for (Map.Entry<String, InternalValue> entry : info.entrySet()) {
String key = entry.getKey();
InternalValue value = entry.getValue();
record.writeString(key);
if (value == null) {
// use undefined for null value
record.writeInt(PropertyType.UNDEFINED);
} else {
record.writeInt(value.getType());
record.writeString(value.toString());
}
}
}
}
use of org.apache.jackrabbit.core.value.InternalValue in project jackrabbit by apache.
the class ChangeLogRecord method readEventRecord.
/**
* Read an event record.
*
* @throws JournalException if an error occurs
*/
private void readEventRecord() throws JournalException {
int type = record.readByte();
NodeId parentId = record.readNodeId();
Path parentPath = record.readPath();
NodeId childId = record.readNodeId();
Path childRelPath = record.readPathElement();
Name ntName = record.readQName();
Set<Name> mixins = new HashSet<Name>();
int mixinCount = record.readInt();
for (int i = 0; i < mixinCount; i++) {
mixins.add(record.readQName());
}
String userId = record.readString();
Map<String, InternalValue> info = null;
if (type == Event.NODE_MOVED) {
info = new HashMap<String, InternalValue>();
// read info map
int infoSize = record.readInt();
for (int i = 0; i < infoSize; i++) {
String key = record.readString();
int propType = record.readInt();
InternalValue value;
if (propType == PropertyType.UNDEFINED) {
// indicates null value
value = null;
} else {
value = InternalValue.valueOf(record.readString(), propType);
}
info.put(key, value);
}
}
EventState es = createEventState(type, parentId, parentPath, childId, childRelPath, ntName, mixins, userId);
if (info != null) {
es.setInfo(info);
}
events.add(es);
}
Aggregations