use of org.apache.jackrabbit.core.value.InternalValue in project jackrabbit by apache.
the class BundleWriter method writeState.
/**
* Serializes a property entry. The serialization begins with the
* property name followed by a single byte that encodes the type and
* multi-valuedness of the property:
* <pre>
* +-------------------------------+
* | mv count | type |
* +-------------------------------+
* </pre>
* <p>
* The lower four bits encode the property type (0-12 in JCR 2.0) and
* higher bits indicate whether this is a multi-valued property and how
* many property values there are. A value of 0 is reserved for
* single-valued properties (that are guaranteed to always have just a
* single value), and all non-zero values indicate a multi-valued property.
* <p>
* In multi-valued properties the exact value of the "mv count" field is
* the number of property values plus one and truncated at 15 (the highest
* four-bit value). If there are 14 or more (14 + 1 == 15) property values,
* then the number of additional values is serialized as a variable-length
* integer (see {@link #writeVarInt(int)}) right after this byte.
* <p>
* The modification count of the property state is written next as a
* variable-length integer, followed by the serializations of all the
* values of this property.
*
* @param state the property entry to store
* @throws IOException if an I/O error occurs.
*/
private void writeState(NodePropBundle.PropertyEntry state) throws IOException {
writeName(state.getName());
InternalValue[] values = state.getValues();
int type = state.getType();
if (type < 0 || type > 0xf) {
throw new IOException("Illegal property type " + type);
}
if (state.isMultiValued()) {
int len = values.length + 1;
if (len < 0x0f) {
out.writeByte(len << 4 | type);
} else {
out.writeByte(0xf0 | type);
writeVarInt(len - 0x0f);
}
} else {
if (values.length != 1) {
throw new IOException("Single values property with " + values.length + " values: " + state.getName());
}
out.writeByte(type);
}
writeVarInt(state.getModCount());
// values
for (int i = 0; i < values.length; i++) {
InternalValue val = values[i];
switch(type) {
case PropertyType.BINARY:
try {
long size = val.getLength();
if (val.isInDataStore()) {
out.writeInt(BundleBinding.BINARY_IN_DATA_STORE);
writeString(val.toString());
} else if (binding.dataStore != null) {
writeSmallBinary(val, state, i);
} else if (size < 0) {
log.warn("Blob has negative size. Potential loss of data. " + "id={} idx={}", state.getId(), String.valueOf(i));
out.writeInt(0);
values[i] = InternalValue.create(new byte[0]);
val.discard();
} else if (size > binding.getMinBlobSize()) {
// special handling required for binary value:
// spool binary value to file in blob store
out.writeInt(BundleBinding.BINARY_IN_BLOB_STORE);
String blobId = state.getBlobId(i);
if (blobId == null) {
BLOBStore blobStore = binding.getBlobStore();
try {
InputStream in = val.getStream();
try {
blobId = blobStore.createId(state.getId(), i);
blobStore.put(blobId, in, size);
state.setBlobId(blobId, i);
} finally {
IOUtils.closeQuietly(in);
}
} catch (Exception e) {
String msg = "Error while storing blob. id=" + state.getId() + " idx=" + i + " size=" + size;
log.error(msg, e);
throw new IOExceptionWithCause(msg, e);
}
try {
// backed by resource in blob store and delete temp file
if (blobStore instanceof ResourceBasedBLOBStore) {
values[i] = InternalValue.create(((ResourceBasedBLOBStore) blobStore).getResource(blobId));
} else {
values[i] = InternalValue.create(blobStore.get(blobId));
}
} catch (Exception e) {
log.error("Error while reloading blob. truncating. id=" + state.getId() + " idx=" + i + " size=" + size, e);
values[i] = InternalValue.create(new byte[0]);
}
val.discard();
}
// store id of blob as property value
// value
writeString(blobId);
} else {
// delete evt. blob
byte[] data = writeSmallBinary(val, state, i);
// replace value instance with value
// backed by resource in blob store and delete temp file
values[i] = InternalValue.create(data);
val.discard();
}
} catch (RepositoryException e) {
String msg = "Error while storing blob. id=" + state.getId() + " idx=" + i + " value=" + val;
log.error(msg, e);
throw new IOExceptionWithCause(msg, e);
}
break;
case PropertyType.DOUBLE:
try {
out.writeDouble(val.getDouble());
} catch (RepositoryException e) {
throw convertToIOException(type, e);
}
break;
case PropertyType.DECIMAL:
try {
writeDecimal(val.getDecimal());
} catch (RepositoryException e) {
throw convertToIOException(type, e);
}
break;
case PropertyType.LONG:
try {
writeVarLong(val.getLong());
} catch (RepositoryException e) {
throw convertToIOException(type, e);
}
break;
case PropertyType.BOOLEAN:
try {
out.writeBoolean(val.getBoolean());
} catch (RepositoryException e) {
throw convertToIOException(type, e);
}
break;
case PropertyType.NAME:
try {
writeName(val.getName());
} catch (RepositoryException e) {
throw convertToIOException(type, e);
}
break;
case PropertyType.WEAKREFERENCE:
case PropertyType.REFERENCE:
writeNodeId(val.getNodeId());
break;
case PropertyType.DATE:
try {
writeDate(val.getCalendar());
} catch (RepositoryException e) {
throw convertToIOException(type, e);
}
break;
case PropertyType.STRING:
case PropertyType.PATH:
case PropertyType.URI:
writeString(val.toString());
break;
default:
throw new IOException("Inknown property type: " + type);
}
}
}
use of org.apache.jackrabbit.core.value.InternalValue in project jackrabbit by apache.
the class XMLPersistenceManager method store.
/**
* {@inheritDoc}
*/
protected void store(PropertyState state) throws ItemStateException {
if (!initialized) {
throw new IllegalStateException("not initialized");
}
String propFilePath = buildPropFilePath(state.getPropertyId());
FileSystemResource propFile = new FileSystemResource(itemStateFS, propFilePath);
try {
propFile.makeParentDirs();
OutputStream os = propFile.getOutputStream();
// write property state to xml file
Writer writer = null;
try {
String encoding = DEFAULT_ENCODING;
try {
writer = new BufferedWriter(new OutputStreamWriter(os, encoding));
} catch (UnsupportedEncodingException e) {
// should never get here!
OutputStreamWriter osw = new OutputStreamWriter(os);
encoding = osw.getEncoding();
writer = new BufferedWriter(osw);
}
String typeName;
int type = state.getType();
try {
typeName = PropertyType.nameFromValue(type);
} catch (IllegalArgumentException iae) {
// should never be getting here
throw new ItemStateException("unexpected property-type ordinal: " + type, iae);
}
writer.write("<?xml version=\"1.0\" encoding=\"" + encoding + "\"?>\n");
writer.write("<" + PROPERTY_ELEMENT + " " + NAME_ATTRIBUTE + "=\"" + Text.encodeIllegalXMLCharacters(state.getName().toString()) + "\" " + PARENTUUID_ATTRIBUTE + "=\"" + state.getParentId() + "\" " + MULTIVALUED_ATTRIBUTE + "=\"" + Boolean.toString(state.isMultiValued()) + "\" " + MODCOUNT_ATTRIBUTE + "=\"" + state.getModCount() + "\" " + TYPE_ATTRIBUTE + "=\"" + typeName + "\">\n");
// values
writer.write("\t<" + VALUES_ELEMENT + ">\n");
InternalValue[] values = state.getValues();
if (values != null) {
for (int i = 0; i < values.length; i++) {
writer.write("\t\t<" + VALUE_ELEMENT + ">");
InternalValue val = values[i];
if (val != null) {
if (type == PropertyType.BINARY) {
// special handling required for binary value:
// put binary value in BLOB store
InputStream in = val.getStream();
String blobId = blobStore.createId(state.getPropertyId(), i);
try {
blobStore.put(blobId, in, val.getLength());
} finally {
IOUtils.closeQuietly(in);
}
// store id of BLOB as property value
writer.write(blobId);
// in BLOB store and discard old value instance (e.g. temp file)
if (blobStore instanceof ResourceBasedBLOBStore) {
// optimization: if the BLOB store is resource-based
// retrieve the resource directly rather than having
// to read the BLOB from an input stream
FileSystemResource fsRes = ((ResourceBasedBLOBStore) blobStore).getResource(blobId);
values[i] = InternalValue.create(fsRes);
} else {
in = blobStore.get(blobId);
try {
values[i] = InternalValue.create(in);
} finally {
try {
in.close();
} catch (IOException e) {
// ignore
}
}
}
val.discard();
} else {
writer.write(Text.encodeIllegalXMLCharacters(val.toString()));
}
}
writer.write("</" + VALUE_ELEMENT + ">\n");
}
}
writer.write("\t</" + VALUES_ELEMENT + ">\n");
writer.write("</" + PROPERTY_ELEMENT + ">\n");
} finally {
writer.close();
}
} catch (Exception e) {
String msg = "failed to store property state: " + state.getParentId() + "/" + state.getName();
log.debug(msg);
throw new ItemStateException(msg, e);
}
}
use of org.apache.jackrabbit.core.value.InternalValue in project jackrabbit by apache.
the class Serializer method deserialize.
/**
* Deserializes a <code>PropertyState</code> object from the given binary
* <code>stream</code>. Binary values are retrieved from the specified
* <code>BLOBStore</code>.
*
* @param state <code>state</code> to deserialize
* @param stream the stream where the <code>state</code> should be
* deserialized from
* @param blobStore handler for BLOB data
* @throws Exception if an error occurs during the deserialization
* @see #serialize(PropertyState, OutputStream, BLOBStore)
*/
public static void deserialize(PropertyState state, InputStream stream, BLOBStore blobStore) throws Exception {
DataInputStream in = new DataInputStream(stream);
// type
int type = in.readInt();
state.setType(type);
// multiValued
boolean multiValued = in.readBoolean();
state.setMultiValued(multiValued);
// definitionId
in.readUTF();
// modCount
short modCount = in.readShort();
state.setModCount(modCount);
// values
// count
int count = in.readInt();
InternalValue[] values = new InternalValue[count];
for (int i = 0; i < count; i++) {
InternalValue val;
if (type == PropertyType.BINARY) {
// value (i.e. blobId)
String s = in.readUTF();
// in the BLOB store
if (blobStore instanceof ResourceBasedBLOBStore) {
// optimization: if the BLOB store is resource-based
// retrieve the resource directly rather than having
// to read the BLOB from an input stream
FileSystemResource fsRes = ((ResourceBasedBLOBStore) blobStore).getResource(s);
val = InternalValue.create(fsRes);
} else {
InputStream is = blobStore.get(s);
try {
val = InternalValue.create(is);
} finally {
try {
is.close();
} catch (IOException e) {
// ignore
}
}
}
} else {
/**
* because writeUTF(String) has a size limit of 65k,
* Strings are serialized as <length><byte[]>
*/
//s = in.readUTF(); // value
// lenght of byte[]
int len = in.readInt();
byte[] bytes = new byte[len];
// byte[]
in.readFully(bytes);
String s = new String(bytes, ENCODING);
val = InternalValue.valueOf(s, type);
}
values[i] = val;
}
state.setValues(values);
}
use of org.apache.jackrabbit.core.value.InternalValue in project jackrabbit by apache.
the class VersionManagerImplRestore method internalRestoreFrozen.
/**
* Restores the properties and child nodes from the frozen state.
*
* @param state state to restore
* @param freeze the frozen node
* @param vsel version selector
* @param restored set of restored versions
* @param removeExisting remove existing flag
* @param copy if <code>true</code> a pure copy is performed
* @throws RepositoryException if an error occurs
* @throws ItemStateException if an error occurs
*/
protected void internalRestoreFrozen(NodeStateEx state, InternalFrozenNode freeze, VersionSelector vsel, Set<InternalVersion> restored, boolean removeExisting, boolean copy) throws RepositoryException, ItemStateException {
// check uuid
if (state.getEffectiveNodeType().includesNodeType(NameConstants.MIX_REFERENCEABLE)) {
if (!state.getNodeId().equals(freeze.getFrozenId())) {
String msg = "Unable to restore version of " + safeGetJCRPath(state) + ". UUID changed.";
log.error(msg);
throw new ItemExistsException(msg);
}
}
// check primary type
if (!freeze.getFrozenPrimaryType().equals(state.getState().getNodeTypeName())) {
// todo: implement
String msg = "Unable to restore version of " + safeGetJCRPath(state) + ". PrimaryType change not supported yet.";
log.error(msg);
throw new UnsupportedRepositoryOperationException(msg);
}
// adjust mixins
state.setMixins(freeze.getFrozenMixinTypes());
// For each property P present on F (other than jcr:frozenPrimaryType,
// jcr:frozenMixinTypes and jcr:frozenUuid):
// - If P has an OPV of COPY or VERSION then F/P is copied to N/P,
// replacing any existing N/P.
// - F will never have a property with an OPV of IGNORE, INITIALIZE, COMPUTE
// or ABORT (see 15.2 Check-In: Creating a Version).
Set<Name> propNames = new HashSet<Name>();
PropertyState[] props = freeze.getFrozenProperties();
for (PropertyState prop : props) {
// don't restore jcr:activity
Name name = prop.getName();
if (!name.equals(NameConstants.JCR_ACTIVITY)) {
state.copyFrom(prop);
propNames.add(name);
}
}
// remove properties that do not exist in the frozen representation
for (PropertyState prop : state.getProperties()) {
Name propName = prop.getName();
if (!propNames.contains(propName)) {
int opv = state.getDefinition(prop).getOnParentVersion();
if (opv == OnParentVersionAction.COPY || opv == OnParentVersionAction.VERSION || opv == OnParentVersionAction.ABORT) {
state.removeProperty(propName);
} else if (opv == OnParentVersionAction.INITIALIZE) {
InternalValue[] values = computeAutoValues(state, state.getDefinition(prop), true);
if (values != null) {
state.setPropertyValues(propName, prop.getType(), values, prop.isMultiValued());
}
} else if (opv == OnParentVersionAction.COMPUTE) {
InternalValue[] values = computeAutoValues(state, state.getDefinition(prop), false);
if (values != null) {
state.setPropertyValues(propName, prop.getType(), values, prop.isMultiValued());
}
}
}
}
// add 'auto-create' properties that do not exist yet
for (QPropertyDefinition def : state.getEffectiveNodeType().getAutoCreatePropDefs()) {
if (!state.hasProperty(def.getName())) {
InternalValue[] values = computeAutoValues(state, def, true);
if (values != null) {
state.setPropertyValues(def.getName(), def.getRequiredType(), values, def.isMultiple());
}
}
}
// For each child node C present on N but not on F:
// - If C has an OPV of COPY, VERSION or ABORT then N/C is removed.
// Note that while a node with a child item of OPV ABORT cannot be
// versioned, it is legal for a previously versioned node to have such
// a child item added to it and then for it to be restored to the state
// that it had before that item was added, as this step indicates.
// - If C has an OPV of IGNORE then no change is made to N/C.
// - If C has an OPV of INITIALIZE then N/C is re-initialized as if it
// were newly created, as defined in its node type.
// - If C has an OPV of COMPUTE then N/C may be re-initialized according
// to an implementation-specific mechanism.
LinkedList<ChildNodeEntry> toDelete = new LinkedList<ChildNodeEntry>();
for (ChildNodeEntry entry : state.getState().getChildNodeEntries()) {
if (!freeze.hasFrozenChildNode(entry.getName(), entry.getIndex())) {
NodeStateEx child = state.getNode(entry.getName(), entry.getIndex());
int opv = child.getDefinition().getOnParentVersion();
if (copy || opv == OnParentVersionAction.COPY || opv == OnParentVersionAction.VERSION || opv == OnParentVersionAction.ABORT) {
toDelete.addFirst(entry);
} else if (opv == OnParentVersionAction.INITIALIZE) {
log.warn("OPV.INITIALIZE not supported yet on restore of existing child nodes: " + safeGetJCRPath(child));
} else if (opv == OnParentVersionAction.COMPUTE) {
log.warn("OPV.COMPUTE not supported yet on restore of existing child nodes: " + safeGetJCRPath(child));
}
}
}
for (ChildNodeEntry entry : toDelete) {
state.removeNode(entry.getName(), entry.getIndex());
}
// need to sync with state manager
state.store();
// create a map that contains a int->NodeStateEx mapping for each child name
Map<Name, Map<Integer, NodeStateEx>> entryToNodeStateExMapping = new HashMap<Name, Map<Integer, NodeStateEx>>();
for (ChildNodeEntry entry : state.getState().getChildNodeEntries()) {
Map<Integer, NodeStateEx> id2stateMap = entryToNodeStateExMapping.get(entry.getName());
if (id2stateMap == null) {
id2stateMap = new HashMap<Integer, NodeStateEx>();
}
id2stateMap.put(entry.getIndex(), state.getNode(entry.getName(), entry.getIndex()));
entryToNodeStateExMapping.put(entry.getName(), id2stateMap);
}
// COMPUTE or ABORT (see 15.2 Check-In: Creating a Version).
for (ChildNodeEntry entry : freeze.getFrozenChildNodes()) {
InternalFreeze child = freeze.getFrozenChildNode(entry.getName(), entry.getIndex());
NodeStateEx restoredChild = null;
if (child instanceof InternalFrozenNode) {
// - If C has an OPV of COPY or VERSION:
// - B is true, then F/C and its subgraph is copied to N/C, replacing
// any existing N/C and its subgraph and any node in the workspace
// with the same identifier as C or a node in the subgraph of C is
// removed.
// - B is false, then F/C and its subgraph is copied to N/C, replacing
// any existing N/C and its subgraph unless there exists a node in the
// workspace with the same identifier as C, or a node in the subgraph
// of C, in which case an ItemExistsException is thrown , all
// changes made by the restore are rolled back leaving N unchanged.
InternalFrozenNode f = (InternalFrozenNode) child;
// if node is present, remove it
Map<Integer, NodeStateEx> id2stateMap = entryToNodeStateExMapping.get(entry.getName());
if (id2stateMap != null && id2stateMap.containsKey(entry.getIndex())) {
state.removeNode(id2stateMap.get(entry.getIndex()));
}
// check for existing
if (f.getFrozenId() != null) {
if (stateMgr.hasItemState(f.getFrozenId())) {
NodeStateEx existing = state.getNode(f.getFrozenId());
if (removeExisting) {
NodeStateEx parent = existing.getParent();
parent.removeNode(existing);
parent.store();
} else if (existing.getState().isShareable()) {
// if existing node is shareable, then clone it
restoredChild = state.moveFrom(existing, existing.getName(), true);
} else if (!existing.hasAncestor(state.getNodeId())) {
String msg = "Unable to restore node, item already exists " + "outside of restored tree: " + safeGetJCRPath(existing);
log.error(msg);
throw new ItemExistsException(msg);
}
}
}
if (restoredChild == null) {
restoredChild = state.addNode(f.getName(), f.getFrozenPrimaryType(), f.getFrozenId());
restoredChild.setMixins(f.getFrozenMixinTypes());
}
internalRestoreFrozen(restoredChild, f, vsel, restored, removeExisting, true);
} else if (child instanceof InternalFrozenVersionHistory) {
// Each child node C of N where C has an OPV of VERSION and C is
// mix:versionable, is represented in F not as a copy of N/C but as
// special node containing a reference to the version history of
// C. On restore, the following occurs:
// - If the workspace currently has an already existing node corresponding
// to C's version history and the removeExisting flag of the restore is
// set to true, then that instance of C becomes the child of the restored N.
// - If the workspace currently has an already existing node corresponding
// to C's version history and the removeExisting flag of the restore is
// set to false then an ItemExistsException is thrown.
// - If the workspace does not have an instance of C then one is restored from
// C's version history:
// - If the restore was initiated through a restoreByLabel where L is
// the specified label and there is a version of C with the label L then
// that version is restored.
// - If the version history of C does not contain a version with the label
// L or the restore was initiated by a method call that does not specify
// a label then the workspace in which the restore is being performed
// will determine which particular version of C will be restored. This
// determination depends on the configuration of the workspace and
// is outside the scope of this specification.
InternalFrozenVersionHistory fh = (InternalFrozenVersionHistory) child;
InternalVersionHistory vh = vMgr.getVersionHistory(fh.getVersionHistoryId());
// get desired version from version selector
InternalVersion v = vsel.select(vh);
Name oldVersion = null;
// check if representing versionable already exists somewhere
NodeId nodeId = vh.getVersionableId();
if (stateMgr.hasItemState(nodeId)) {
restoredChild = state.getNode(nodeId);
if (restoredChild.getParentId().equals(state.getNodeId())) {
// if same parent, ignore
} else if (removeExisting) {
NodeStateEx parent = restoredChild.getNode(restoredChild.getParentId());
state.moveFrom(restoredChild, fh.getName(), false);
parent.store();
// get old version name
oldVersion = getBaseVersion(restoredChild).getName();
} else {
// since we delete the OPV=Copy children beforehand, all
// found nodes must be outside of this tree
String msg = "Unable to restore node, item already exists " + "outside of restored tree: " + safeGetJCRPath(restoredChild);
log.error(msg);
throw new ItemExistsException(msg);
}
}
// check existing version of item exists
if (restoredChild == null) {
if (v == null) {
// if version selector was unable to select version,
// choose the initial one
List<InternalVersion> vs = vh.getRootVersion().getSuccessors();
if (vs.isEmpty()) {
String msg = "Unable to select appropriate version for " + child.getName() + " using " + vsel;
log.error(msg);
throw new VersionException(msg);
}
v = vs.get(0);
}
InternalFrozenNode f = v.getFrozenNode();
restoredChild = state.addNode(fh.getName(), f.getFrozenPrimaryType(), f.getFrozenId());
restoredChild.setMixins(f.getFrozenMixinTypes());
} else {
if (v == null || oldVersion == null || v.getName().equals(oldVersion)) {
v = null;
}
}
if (v != null) {
try {
internalRestore(restoredChild, v, vsel, removeExisting);
} catch (RepositoryException e) {
log.error("Error while restoring node: " + e);
log.error(" child path: " + restoredChild);
log.error(" selected version: " + v.getName());
StringBuilder avail = new StringBuilder();
for (Name name : vh.getVersionNames()) {
avail.append(name);
avail.append(", ");
}
log.error(" available versions: " + avail);
log.error(" versionselector: " + vsel);
throw e;
}
// add this version to set
restored.add(v);
}
}
if (restoredChild != null && state.getEffectiveNodeType().hasOrderableChildNodes()) {
// In a repository that supports orderable child nodes, the relative
// ordering of the set of child nodes C that are copied from F is
// preserved.
// order at end
ArrayList<ChildNodeEntry> list = new ArrayList<ChildNodeEntry>(state.getState().getChildNodeEntries());
ChildNodeEntry toReorder = null;
boolean isLast = true;
for (ChildNodeEntry e : list) {
if (e.getId().equals(restoredChild.getNodeId())) {
toReorder = e;
} else if (toReorder != null) {
isLast = false;
}
}
if (toReorder != null && !isLast) {
list.remove(toReorder);
list.add(toReorder);
state.getState().setChildNodeEntries(list);
}
}
}
}
use of org.apache.jackrabbit.core.value.InternalValue in project jackrabbit by apache.
the class InternalVersionHistoryImpl method checkin.
/**
* Checks in a node. It creates a new version with the given name and freezes
* the state of the given node.
*
* @param name new version name
* @param src source node to version
* @param created optional created date
* @return the newly created version
* @throws RepositoryException if an error occurs
*/
synchronized InternalVersionImpl checkin(Name name, NodeStateEx src, Calendar created) throws RepositoryException {
// copy predecessors from src node
InternalValue[] predecessors;
if (src.hasProperty(NameConstants.JCR_PREDECESSORS)) {
predecessors = src.getPropertyValues(NameConstants.JCR_PREDECESSORS);
// check all predecessors
for (InternalValue pred : predecessors) {
NodeId predId = pred.getNodeId();
// check if version exist
if (!nameCache.containsValue(predId)) {
throw new RepositoryException("Invalid predecessor in source node: " + predId);
}
}
} else {
// with simple versioning, the node does not contain a predecessors
// property and we just use the 'head' version as predecessor
Iterator<NodeId> iter = nameCache.values().iterator();
NodeId last = null;
while (iter.hasNext()) {
last = iter.next();
}
if (last == null) {
// should never happen
last = rootVersion.getId();
}
predecessors = new InternalValue[] { InternalValue.create(last) };
}
NodeId versionId = vMgr.getNodeIdFactory().newNodeId();
NodeStateEx vNode = node.addNode(name, NameConstants.NT_VERSION, versionId, true);
// check for jcr:activity
if (src.hasProperty(NameConstants.JCR_ACTIVITY)) {
InternalValue act = src.getPropertyValue(NameConstants.JCR_ACTIVITY);
vNode.setPropertyValue(NameConstants.JCR_ACTIVITY, act);
}
// initialize 'created', 'predecessors' and 'successors'
if (created == null) {
created = getCurrentTime();
}
vNode.setPropertyValue(NameConstants.JCR_CREATED, InternalValue.create(created));
vNode.setPropertyValues(NameConstants.JCR_PREDECESSORS, PropertyType.REFERENCE, predecessors);
vNode.setPropertyValues(NameConstants.JCR_SUCCESSORS, PropertyType.REFERENCE, InternalValue.EMPTY_ARRAY);
// checkin source node
InternalFrozenNodeImpl.checkin(vNode, NameConstants.JCR_FROZENNODE, src);
// update version graph
boolean isConfiguration = src.getEffectiveNodeType().includesNodeType(NameConstants.NT_CONFIGURATION);
InternalVersionImpl version = isConfiguration ? new InternalBaselineImpl(this, vNode, name) : new InternalVersionImpl(this, vNode, name);
version.internalAttach();
// and store
node.store();
vMgr.versionCreated(version);
// update cache
versionCache.put(version.getId(), version);
nameCache.put(version.getName(), version.getId());
return version;
}
Aggregations