stefan 2004/07/16 09:34:36
Added: proposals/jcrri/src/org/apache/slide/jcr/core/version
VersionHistoryImpl.java VersionImpl.java
VersionIteratorImpl.java VersionManager.java
Log:
jcrri
Revision Changes Path
1.1
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/version/VersionHistoryImpl.java
Index: VersionHistoryImpl.java
===================================================================
/*
* $Id: VersionHistoryImpl.java,v 1.1 2004/07/16 16:34:36 stefan Exp $
*
* Copyright 2002-2004 Day Management AG, Switzerland.
*
* Licensed under the Day RI License, Version 2.0 (the "License"),
* as a reference implementation of the following specification:
*
* Content Repository API for Java Technology, revision 0.13
* <http://www.jcp.org/en/jsr/detail?id=170>
*
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License files at
*
* http://www.day.com/content/en/licenses/day-ri-license-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.slide.jcr.core.version;
import org.apache.log4j.Logger;
import org.apache.slide.jcr.core.*;
import org.apache.slide.jcr.core.state.NodeState;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.NodeDef;
import javax.jcr.version.Version;
import javax.jcr.version.VersionHistory;
import javax.jcr.version.VersionIterator;
import java.util.HashMap;
/**
* This Class implements a version history.
*
* @author Tobias Strasser
* @version $Revision: 1.1 $, $Date: 2004/07/16 16:34:36 $
*/
public class VersionHistoryImpl extends NodeImpl implements VersionHistory {
/**
* default logger
*/
private static Logger log = Logger.getLogger(VersionHistoryImpl.class);
/**
* the name of the 'jcr:rootVersion' node
*/
public static final QName NODENAME_ROOTVERSION = new
QName(NamespaceRegistryImpl.NS_JCR_URI, "rootVersion");
/**
* the cache of the version labels (initialized on first usage)
* key = version label (String)
* value = version name (String)
*/
private HashMap labelCache = null;
/**
* Creates a new VersionHistory object for the given node.
* <p/>
* Currently, it just casts the given node into a VersionHistoryImpl, but
* this might change, if in the future spec the VersionHistory does not
* extend Node anymore.
*
* @param node
* @return a VersionHistory
*/
protected static VersionHistoryImpl create(NodeImpl node) {
return (VersionHistoryImpl) node;
}
/**
* Creates a new VersionHistoryImpl object. This is only called by the
* item manager, when creating new node instances.
*
* @see
org.apache.slide.jcr.core.ItemManager#createNodeInstance(org.apache.slide.jcr.core.state.NodeState,
javax.jcr.nodetype.NodeDef)
*/
public VersionHistoryImpl(ItemManager itemMgr, TicketImpl ticket, NodeId id,
NodeState state, NodeDef definition,
ItemLifeCycleListener[] listeners)
throws RepositoryException {
super(itemMgr, ticket, id, state, definition, listeners);
}
/**
* @see VersionHistory#getRootVersion()
*/
public Version getRootVersion() throws RepositoryException {
return (Version)
getNode(NODENAME_ROOTVERSION.toJCRName(ticket.getNamespaceResolver()));
}
/**
* @see VersionHistory#getAllVersions()
*/
public VersionIterator getAllVersions() throws RepositoryException {
return new VersionIteratorImpl(getRootVersion());
}
/**
* @see VersionHistory#getVersion(java.lang.String)
*/
public Version getVersion(String versionName) throws RepositoryException {
return (Version) getNode(versionName);
}
/**
* @see VersionHistory#getVersionByLabel(java.lang.String)
*/
public Version getVersionByLabel(String label) throws RepositoryException {
initLabelCache();
return labelCache.containsKey(label)
? (Version) getNode((String) labelCache.get(label))
: null;
}
/**
* Initializes the label cache
*
* @throws RepositoryException
*/
private void initLabelCache() throws RepositoryException {
if (labelCache != null) {
return;
}
labelCache = new HashMap();
NodeIterator iter = getNodes();
while (iter.hasNext()) {
// assuming all subnodes are 'versions'
Version v = (Version) iter.nextNode();
String[] labels = v.getVersionLabels();
for (int i = 0; i < labels.length; i++) {
if (labelCache.containsKey(labels[i])) {
log.error("Label " + labels[i] + " duplicate: in " + v.getName() +
" and in " + labelCache.get(labels[i]));
} else {
labelCache.put(labels[i], v.getName());
}
}
}
}
/**
* Adds a version label to the internal cache.
*
* @param version
* @param label
* @return <code>true</code> if the label was added; <code>false</code> if not
* @throws RepositoryException
*/
protected boolean addVersionLabel(Version version, String label) throws
RepositoryException {
initLabelCache();
if (!labelCache.containsKey(label)) {
// if not exists, add
labelCache.put(label, version.getName());
return true;
} else if (labelCache.get(label).equals(version.getName())) {
// if already defined to this version, ignore
return false;
} else {
// already defined eslwhere, throw
throw new RepositoryException("Version label " + label + " already defined
for version " + version.getName());
}
}
/**
* Removes the label from the intenal cache
*
* @param label
* @throws RepositoryException if the label does not exist
*/
protected void removeVersionLabel(String label) throws RepositoryException {
initLabelCache();
if (labelCache.remove(label) == null) {
throw new RepositoryException("Version label " + label + " is not in
version history.");
}
}
}
1.1
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/version/VersionImpl.java
Index: VersionImpl.java
===================================================================
/*
* $Id: VersionImpl.java,v 1.1 2004/07/16 16:34:36 stefan Exp $
*
* Copyright 2002-2004 Day Management AG, Switzerland.
*
* Licensed under the Day RI License, Version 2.0 (the "License"),
* as a reference implementation of the following specification:
*
* Content Repository API for Java Technology, revision 0.13
* <http://www.jcp.org/en/jsr/detail?id=170>
*
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License files at
*
* http://www.day.com/content/en/licenses/day-ri-license-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.slide.jcr.core.version;
import org.apache.slide.jcr.core.*;
import org.apache.slide.jcr.core.state.NodeState;
import javax.jcr.RepositoryException;
import javax.jcr.StringValue;
import javax.jcr.Value;
import javax.jcr.nodetype.NodeDef;
import javax.jcr.version.Version;
import java.util.Calendar;
/**
* This Class implements the Version representation of the node.
*
* @author Tobias Strasser
* @version $Revision: 1.1 $, $Date: 2004/07/16 16:34:36 $
*/
public class VersionImpl extends NodeImpl implements Version {
/**
* name of the 'jcr:versionLabels' property
*/
public static final QName PROPNAME_VERSION_LABELS = new
QName(NamespaceRegistryImpl.NS_JCR_URI, "uuid");
/**
* name of the 'jcr:predecessors' property
*/
public static final QName PROPNAME_PREDESESSORS = new
QName(NamespaceRegistryImpl.NS_JCR_URI, "predecessors");
/**
* name of the 'jcr:successors' property
*/
public static final QName PROPNAME_SUCCESSORS = new
QName(NamespaceRegistryImpl.NS_JCR_URI, "successors");
/**
* name of the 'jcr:isCheckedOut' property
*/
public static final QName PROPNAME_IS_CHECKED_OUT = new
QName(NamespaceRegistryImpl.NS_JCR_URI, "isCheckedOut");
/**
* name of the 'jcr:versionHistory' property
*/
public static final QName PROPNAME_VERSION_HISTORY = new
QName(NamespaceRegistryImpl.NS_JCR_URI, "versionHistory");
/**
* name of the 'jcr:frozenUUID' property
*/
public static final QName PROPNAME_FROZEN_UUID = new
QName(NamespaceRegistryImpl.NS_JCR_URI, "frozenUUID");
/**
* name of the 'jcr:frozenPrimaryType' property
*/
public static final QName PROPNAME_FROZEN_PRIMARY_TYPE = new
QName(NamespaceRegistryImpl.NS_JCR_URI, "frozenPrimaryType");
/**
* name of the 'jcr:frozenMixinTypes' property
*/
public static final QName PROPNAME_FROZEN_MIXIN_TYPES = new
QName(NamespaceRegistryImpl.NS_JCR_URI, "frozenMixinTypes");
/**
* name of the 'jcr:baseVersion' property
*/
public static final QName PROPNAME_BASE_VERSION = new
QName(NamespaceRegistryImpl.NS_JCR_URI, "baseVersion");
/**
* Creates a new Version node. This is only called by the ItemManager when
* creating new node instances.
*
* @see
org.apache.slide.jcr.core.ItemManager#createNodeInstance(org.apache.slide.jcr.core.state.NodeState,
javax.jcr.nodetype.NodeDef)
*/
public VersionImpl(ItemManager itemMgr, TicketImpl ticket, NodeId id,
NodeState state, NodeDef definition,
ItemLifeCycleListener[] listeners)
throws RepositoryException {
super(itemMgr, ticket, id, state, definition, listeners);
}
/**
* @see Version#getCreated()
*/
public Calendar getCreated() throws RepositoryException {
// no check for NULL needed since its mandatory
return
getProperty(PROPNAME_CREATED.toJCRName(ticket.getNamespaceResolver())).getDate();
}
/**
* @see Version#getVersionLabels()
*/
public String[] getVersionLabels() throws RepositoryException {
if
(hasProperty(PROPNAME_VERSION_LABELS.toJCRName(ticket.getNamespaceResolver()))) {
Value[] values =
getProperty(PROPNAME_VERSION_LABELS.toJCRName(ticket.getNamespaceResolver())).getValues();
if (values != null) {
String[] labels = new String[values.length];
for (int i = 0; i < values.length; i++) {
labels[i] = values[i].getString();
}
return labels;
}
}
return new String[0];
}
/**
* @see Version#hasVersionLabel()
*/
public boolean hasVersionLabel(String label) throws RepositoryException {
if
(hasProperty(PROPNAME_VERSION_LABELS.toJCRName(ticket.getNamespaceResolver()))) {
Value[] values =
getProperty(PROPNAME_VERSION_LABELS.toJCRName(ticket.getNamespaceResolver())).getValues();
if (values != null) {
for (int i = 0; i < values.length; i++) {
if (values[i].getString().equals(label)) {
return true;
}
}
}
}
return false;
}
/**
* @see Version#addVersionLabel(java.lang.String)
*/
public void addVersionLabel(String label) throws RepositoryException {
// check version first
if (!getHistory().addVersionLabel(this, label)) {
return;
}
Value[] oldValues = null;
Value[] newValues = null;
if
(hasProperty(PROPNAME_VERSION_LABELS.toJCRName(ticket.getNamespaceResolver()))) {
oldValues =
getProperty(PROPNAME_VERSION_LABELS.toJCRName(ticket.getNamespaceResolver())).getValues();
}
if (oldValues != null) {
newValues = new Value[oldValues.length + 1];
for (int i = 0; i < oldValues.length; i++) {
newValues[i] = oldValues[i];
}
newValues[oldValues.length] = new StringValue(label);
} else {
newValues = new Value[]{new StringValue(label)};
}
setProperty(PROPNAME_VERSION_LABELS.toJCRName(ticket.getNamespaceResolver()),
newValues);
save();
}
/**
* @see Version#removeVersionLabel(java.lang.String)
*/
public void removeVersionLabel(String label) throws RepositoryException {
// check history first
getHistory().removeVersionLabel(label);
Value[] oldValues =
getProperty(PROPNAME_VERSION_LABELS.toJCRName(ticket.getNamespaceResolver())).getValues();
Value[] newValues = new Value[oldValues.length - 1];
int j = 0;
for (int i = 0; i < oldValues.length; i++) {
if (!oldValues[i].getString().equals(label)) {
if (j < newValues.length) {
newValues[j] = oldValues[i];
}
j++;
}
}
if (j == 0) {
setProperty(PROPNAME_VERSION_LABELS.toJCRName(ticket.getNamespaceResolver()),
(Value[]) null);
save();
} else {
setProperty(PROPNAME_VERSION_LABELS.toJCRName(ticket.getNamespaceResolver()),
newValues);
save();
}
}
/**
* @see Version#getSuccessors()
*/
public Version[] getSuccessors() throws RepositoryException {
if (hasProperty(PROPNAME_SUCCESSORS.toJCRName(ticket.getNamespaceResolver())))
{
Value[] values =
getProperty(PROPNAME_SUCCESSORS.toJCRName(ticket.getNamespaceResolver())).getValues();
if (values != null) {
Version[] preds = new Version[values.length];
for (int i = 0; i < values.length; i++) {
preds[i] = (Version) ticket.getNodeByUUID(values[i].getString());
}
return preds;
}
}
return new Version[0];
}
/**
* @see Version#getPredecessors()
*/
public Version[] getPredecessors() throws RepositoryException {
if
(hasProperty(PROPNAME_PREDESESSORS.toJCRName(ticket.getNamespaceResolver()))) {
Value[] values =
getProperty(PROPNAME_PREDESESSORS.toJCRName(ticket.getNamespaceResolver())).getValues();
if (values != null) {
Version[] succs = new Version[values.length];
for (int i = 0; i < values.length; i++) {
succs[i] = (Version) ticket.getNodeByUUID(values[i].getString());
}
return succs;
}
}
return new Version[0];
}
/**
* Returns the version history of this version and not the extended node.
*
* @return the version history of this version graph
* @throws RepositoryException
*/
private VersionHistoryImpl getHistory() throws RepositoryException {
return (VersionHistoryImpl) getParent();
}
/**
* Initializes the frozen state of a version. i.e. copies the uuid,
* primary types etc.
*
* @param node
*/
void initFrozenState(NodeImpl node)
throws RepositoryException {
internalSetProperty(VersionImpl.PROPNAME_FROZEN_UUID,
InternalValue.create(node.getProperty(VersionImpl.PROPNAME_UUID).getString()));
internalSetProperty(VersionImpl.PROPNAME_FROZEN_PRIMARY_TYPE,
InternalValue.create(node.getProperty(VersionImpl.PROPNAME_PRIMARYTYPE).getString()));
if (node.hasProperty(VersionImpl.PROPNAME_MIXINTYPES)) {
internalSetProperty(VersionImpl.PROPNAME_FROZEN_MIXIN_TYPES,
InternalValue.create(node.getProperty(VersionImpl.PROPNAME_MIXINTYPES).getString()));
}
}
}
1.1
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/version/VersionIteratorImpl.java
Index: VersionIteratorImpl.java
===================================================================
/*
* $Id: VersionIteratorImpl.java,v 1.1 2004/07/16 16:34:36 stefan Exp $
*
* Copyright 2002-2004 Day Management AG, Switzerland.
*
* Licensed under the Day RI License, Version 2.0 (the "License"),
* as a reference implementation of the following specification:
*
* Content Repository API for Java Technology, revision 0.13
* <http://www.jcp.org/en/jsr/detail?id=170>
*
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License files at
*
* http://www.day.com/content/en/licenses/day-ri-license-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.slide.jcr.core.version;
import javax.jcr.RepositoryException;
import javax.jcr.version.Version;
import javax.jcr.version.VersionIterator;
import java.util.NoSuchElementException;
import java.util.Stack;
/**
* This Class implements a VersionIterator that iterates over a version
* graph following the successor nodes.
*
* @author Tobias Strasser
* @version $Revision: 1.1 $, $Date: 2004/07/16 16:34:36 $
*/
public class VersionIteratorImpl implements VersionIterator {
/**
* the current position
*/
private int pos = 0;
/**
* the traversal stack
*/
private Stack successors = new Stack();
/**
* Creates a new VersionIterator that iterates over the version tree,
* starting below the root node.
*
* @param rootVersion
*/
public VersionIteratorImpl(Version rootVersion) throws RepositoryException {
push(rootVersion.getSuccessors());
}
/**
* @see VersionIterator#nextVersion()
*/
public Version nextVersion() {
if (successors.isEmpty()) {
throw new NoSuchElementException();
}
Version ret = (Version) successors.peek();
pos++;
try {
push(ret.getSuccessors());
} catch (RepositoryException e) {
// ignore
}
return ret;
}
/**
* @see VersionIterator#skip(int)
*/
public void skip(int skipNum) {
while (skipNum > 0) {
skipNum--;
nextVersion();
}
}
/**
* @see VersionIterator#getSize()
*/
public long getSize() {
return -1;
}
/**
* @see VersionIterator#getPos()
*/
public long getPos() {
return pos;
}
/**
* @throws UnsupportedOperationException since this operation is not supported
* @see VersionIterator#remove()
*/
public void remove() throws UnsupportedOperationException {
throw new UnsupportedOperationException();
}
/**
* @see VersionIterator#hasNext()
*/
public boolean hasNext() {
return !successors.isEmpty();
}
/**
* @see VersionIterator#next()
*/
public Object next() {
return nextVersion();
}
/**
* Pushes the versions on the stack
*
* @param versions
*/
private void push(Version[] versions) {
for (int i = 0; i < versions.length; i++) {
successors.push(versions[i]);
}
}
}
1.1
jakarta-slide/proposals/jcrri/src/org/apache/slide/jcr/core/version/VersionManager.java
Index: VersionManager.java
===================================================================
/*
* $Id: VersionManager.java,v 1.1 2004/07/16 16:34:36 stefan Exp $
*
* Copyright 2002-2004 Day Management AG, Switzerland.
*
* Licensed under the Day RI License, Version 2.0 (the "License"),
* as a reference implementation of the following specification:
*
* Content Repository API for Java Technology, revision 0.13
* <http://www.jcp.org/en/jsr/detail?id=170>
*
* You may not use this file except in compliance with the License.
* You may obtain a copy of the License files at
*
* http://www.day.com/content/en/licenses/day-ri-license-2.0
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.slide.jcr.core.version;
import org.apache.slide.jcr.core.*;
import org.apache.slide.jcr.core.nodetype.NodeTypeRegistry;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.version.Version;
import javax.jcr.version.VersionHistory;
/**
* This Class implements...
*
* @author Tobias Strasser
* @version $Revision: 1.1 $, $Date: 2004/07/16 16:34:36 $
*/
public class VersionManager {
// root path for version storage
public static final QName VERSION_HISTORY_ROOT_NAME =
new QName(NamespaceRegistryImpl.NS_JCR_URI, "versionStorage");
// the system ticket for the versioning
private final TicketImpl ticket;
/**
* the root node of the version histories
*/
private final Node historyRoot;
/**
* Creates a new VersionManager.
*
* @param ticket
* @throws RepositoryException
*/
public VersionManager(TicketImpl ticket) throws RepositoryException {
this.ticket = ticket;
// check for versionhistory root
Node systemRoot = ((RepositoryImpl)
ticket.getRepository()).getSystemRootNode(ticket);
if
(!systemRoot.hasNode(VERSION_HISTORY_ROOT_NAME.toJCRName(ticket.getNamespaceResolver())))
{
// if not exist, create
systemRoot.addNode(VERSION_HISTORY_ROOT_NAME.toJCRName(ticket.getNamespaceResolver()),
NodeTypeRegistry.NT_UNSTRUCTURED.toJCRName(ticket.getNamespaceResolver()));
systemRoot.save();
}
historyRoot =
systemRoot.getNode(VERSION_HISTORY_ROOT_NAME.toJCRName(ticket.getNamespaceResolver()));
}
/**
* Creates a new Version History and returns the UUID of it.
*
* @param node the node for which the version history is to be initialized
* @return the UUID of the new version history node
* @throws RepositoryException
*/
public VersionHistory createVersionHistory(NodeImpl node)
throws RepositoryException {
// check if history already exists
String relPath = node.getUUID();
if (historyRoot.hasNode(relPath)) {
//throw new RepositoryException("Unable to initialize version history.
Already exists");
historyRoot.remove(relPath);
}
// create new history node
VersionHistoryImpl vh = VersionHistoryImpl.create((NodeImpl)
historyRoot.addNode(relPath,
NodeTypeRegistry.NT_VERSION_HISTORY.toJCRName(ticket.getNamespaceResolver())));
// and initialize the root version
((VersionImpl) vh.getRootVersion()).initFrozenState(node);
// save new history
historyRoot.save();
// must aquire version history wich ticket in node
return VersionHistoryImpl.create((NodeImpl)
node.getTicket().getNodeByUUID(vh.getUUID()));
}
/**
* Returns the base version of the given node. assuming mix:versionable
*
* @param node
* @return
* @throws RepositoryException
*/
public Version getBaseVersion(NodeImpl node) throws RepositoryException {
return (Version) node.getProperty(VersionImpl.PROPNAME_BASE_VERSION).getItem();
}
/**
* Returns the version history for the given node. assuming mix:versionable
* and version history set in property
*
* @param node
* @return
* @throws RepositoryException
*/
public VersionHistory getVersionHistory(NodeImpl node) throws
RepositoryException {
return VersionHistoryImpl.create((NodeImpl)
node.getTicket().getNodeByUUID(node.getProperty(VersionImpl.PROPNAME_VERSION_HISTORY).getString()));
}
}
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]