- Incorporate JCR project into Repository project

- Single configuration entry point for JCR and non-JCR clients (i.e. application-context.xml)
- Addition of build-war, incremental-war build targets (no deploy)
- Remove build of JCR TCK war file by default

git-svn-id: https://svn.alfresco.com/repos/alfresco-enterprise/alfresco/HEAD/root@2777 c4b6b30b-aa2e-2d43-bbcb-ca4b014f7261
This commit is contained in:
David Caruana
2006-05-05 16:33:22 +00:00
parent c29f0fd4f1
commit 19e3138e1c
80 changed files with 14665 additions and 3 deletions

View File

@@ -0,0 +1,58 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.api;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.util.ParameterCheck;
/**
* Helper to retrieve an Alfresco Node Reference from a JCR Node
*
* @author David Caruana
*/
public class JCRNodeRef
{
/**
* Gets the Node Reference for the specified Node
*
* @param node JCR Node
* @return Alfresco Node Reference
* @throws RepositoryException
*/
public static NodeRef getNodeRef(Node node)
throws RepositoryException
{
ParameterCheck.mandatory("Node", node);
Property protocol = node.getProperty(NamespaceService.SYSTEM_MODEL_PREFIX + ":" + ContentModel.PROP_STORE_PROTOCOL.getLocalName());
Property identifier = node.getProperty(NamespaceService.SYSTEM_MODEL_PREFIX + ":" + ContentModel.PROP_STORE_IDENTIFIER.getLocalName());
Property uuid = node.getProperty(NamespaceService.SYSTEM_MODEL_PREFIX + ":" + ContentModel.PROP_NODE_UUID.getLocalName());
return new NodeRef(new StoreRef(protocol.getString(), identifier.getString()), uuid.getString());
}
}

View File

@@ -0,0 +1,139 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.dictionary;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import javax.jcr.RepositoryException;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
/**
* Responsible for mapping Alfresco Classes to JCR Types / Mixins and vice versa.
*
* @author David Caruana
*/
public class ClassMap
{
/** Map of Alfresco Class to JCR Class */
private static Map<QName, QName> JCRToAlfresco = new HashMap<QName, QName>();
static
{
JCRToAlfresco.put(NodeTypeImpl.MIX_REFERENCEABLE, ContentModel.ASPECT_REFERENCEABLE);
JCRToAlfresco.put(NodeTypeImpl.MIX_LOCKABLE, ContentModel.ASPECT_LOCKABLE);
JCRToAlfresco.put(NodeTypeImpl.MIX_VERSIONABLE, ContentModel.ASPECT_VERSIONABLE);
}
/** Map of JCR Class to Alfresco Class */
private static Map<QName, QName> AlfrescoToJCR = new HashMap<QName, QName>();
static
{
AlfrescoToJCR.put(ContentModel.ASPECT_REFERENCEABLE, NodeTypeImpl.MIX_REFERENCEABLE);
AlfrescoToJCR.put(ContentModel.ASPECT_LOCKABLE, NodeTypeImpl.MIX_LOCKABLE);
AlfrescoToJCR.put(ContentModel.ASPECT_VERSIONABLE, NodeTypeImpl.MIX_VERSIONABLE);
}
/** Map of JCR to Alfresco "Add Aspect" Behaviours */
private static Map<QName, AddMixin> addMixin = new HashMap<QName, AddMixin>();
static
{
addMixin.put(ContentModel.ASPECT_VERSIONABLE, new VersionableMixin());
}
/** Map of JCR to Alfresco "Remove Aspect" Behaviours */
private static Map<QName, RemoveMixin> removeMixin = new HashMap<QName, RemoveMixin>();
static
{
removeMixin.put(ContentModel.ASPECT_VERSIONABLE, new VersionableMixin());
}
/**
* Convert an Alfresco Class to a JCR Type
*
* @param jcrType JCR Type
* @return Alfresco Class
* @throws RepositoryException
*/
public static QName convertTypeToClass(QName jcrType)
{
return JCRToAlfresco.get(jcrType);
}
/**
* Convert an Alfresco Class to a JCR Type
*
* @param alfrescoClass Alfresco Class
* @return JCR Type
* @throws RepositoryException
*/
public static QName convertClassToType(QName alfrescoClass)
{
return JCRToAlfresco.get(alfrescoClass);
}
/**
* Get 'Add Mixin' JCR behaviour
*
* @param alfrescoClass
* @return AddMixin behaviour
*/
public static AddMixin getAddMixin(QName alfrescoClass)
{
return addMixin.get(alfrescoClass);
}
/**
* Get 'Remove Mixin' JCR behaviour
*
* @param alfrescoClass
* @return RemoveMixin behaviour
*/
public static RemoveMixin getRemoveMixin(QName alfrescoClass)
{
return removeMixin.get(alfrescoClass);
}
/**
* Add Mixin Behaviour
*
* Encapsulates mapping of JCR behaviour to Alfresco
*/
public interface AddMixin
{
public Map<QName, Serializable> preAddMixin(SessionImpl session, NodeRef nodeRef);
public void postAddMixin(SessionImpl session, NodeRef nodeRef);
}
/**
* Remove Mixin Behaviour
*
* Encapsulates mapping of JCR behaviour to Alfresco
*/
public interface RemoveMixin
{
public void preRemoveMixin(SessionImpl session, NodeRef nodeRef);
public void postRemoveMixin(SessionImpl session, NodeRef nodeRef);
}
}

View File

@@ -0,0 +1,108 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.dictionary;
import java.util.HashMap;
import java.util.Map;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.namespace.QName;
/**
* Responsible for mapping Alfresco Data Types to JCR Property Types and vice versa.
*
* @author David Caruana
*/
public class DataTypeMap
{
/** Map of Alfresco Data Type to JCR Property Type */
private static Map<QName, Integer> dataTypeToPropertyType = new HashMap<QName, Integer>();
static
{
dataTypeToPropertyType.put(DataTypeDefinition.TEXT, PropertyType.STRING);
dataTypeToPropertyType.put(DataTypeDefinition.CONTENT, PropertyType.BINARY);
dataTypeToPropertyType.put(DataTypeDefinition.INT, PropertyType.LONG);
dataTypeToPropertyType.put(DataTypeDefinition.LONG, PropertyType.LONG);
dataTypeToPropertyType.put(DataTypeDefinition.FLOAT, PropertyType.DOUBLE);
dataTypeToPropertyType.put(DataTypeDefinition.DOUBLE, PropertyType.DOUBLE);
dataTypeToPropertyType.put(DataTypeDefinition.DATE, PropertyType.DATE);
dataTypeToPropertyType.put(DataTypeDefinition.DATETIME, PropertyType.DATE);
dataTypeToPropertyType.put(DataTypeDefinition.BOOLEAN, PropertyType.BOOLEAN);
dataTypeToPropertyType.put(DataTypeDefinition.QNAME, PropertyType.NAME);
dataTypeToPropertyType.put(DataTypeDefinition.CATEGORY, PropertyType.STRING); // TODO: Check this mapping
dataTypeToPropertyType.put(DataTypeDefinition.NODE_REF, PropertyType.REFERENCE);
dataTypeToPropertyType.put(DataTypeDefinition.PATH, PropertyType.PATH);
dataTypeToPropertyType.put(DataTypeDefinition.ANY, PropertyType.UNDEFINED);
}
/** Map of JCR Property Type to Alfresco Data Type */
private static Map<Integer, QName> propertyTypeToDataType = new HashMap<Integer, QName>();
static
{
propertyTypeToDataType.put(PropertyType.STRING, DataTypeDefinition.TEXT);
propertyTypeToDataType.put(PropertyType.BINARY, DataTypeDefinition.CONTENT);
propertyTypeToDataType.put(PropertyType.LONG, DataTypeDefinition.LONG);
propertyTypeToDataType.put(PropertyType.DOUBLE, DataTypeDefinition.DOUBLE);
propertyTypeToDataType.put(PropertyType.DATE, DataTypeDefinition.DATETIME);
propertyTypeToDataType.put(PropertyType.BOOLEAN, DataTypeDefinition.BOOLEAN);
propertyTypeToDataType.put(PropertyType.NAME, DataTypeDefinition.QNAME);
propertyTypeToDataType.put(PropertyType.REFERENCE, DataTypeDefinition.NODE_REF);
propertyTypeToDataType.put(PropertyType.PATH, DataTypeDefinition.PATH);
propertyTypeToDataType.put(PropertyType.UNDEFINED, DataTypeDefinition.ANY);
}
/**
* Convert an Alfresco Data Type to a JCR Property Type
*
* @param datatype alfresco data type
* @return JCR property type
* @throws RepositoryException
*/
public static int convertDataTypeToPropertyType(QName datatype)
{
Integer propertyType = dataTypeToPropertyType.get(datatype);
if (propertyType == null)
{
throw new AlfrescoRuntimeException("Cannot map Alfresco data type " + datatype + " to JCR property type.");
}
return propertyType;
}
/**
* Convert a JCR Property Type to an Alfresco Data Type
*
* @param propertyType JCR property type
* @return alfresco data type
* @throws RepositoryException
*/
public static QName convertPropertyTypeToDataType(int propertyType)
{
QName type = propertyTypeToDataType.get(propertyType);
if (type == null)
{
throw new AlfrescoRuntimeException("Cannot map JCR property type " + propertyType + " to Alfresco data type.");
}
return type;
}
}

View File

@@ -0,0 +1,40 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.dictionary;
/**
* JCR Namespace definitions
*
* @author David Caruana
*/
public class JCRNamespace
{
public static String XML_PREFIX = "xml";
public static String JCR_URI = "http://www.jcp.org/jcr/1.0";
public static String JCR_PREFIX = "jcr";
public static String NT_URI = "http://www.jcp.org/jcr/nt/1.0";
public static String NT_PREFIX = "nt";
public static String MIX_URI = "http://www.jcp.org/jcr/mix/1.0";
public static String MIX_PREFIX = "mix";
public static String SV_URI = "http://www.jcp.org/jcr/sv/1.0";
public static String SV_PREFIX = "sv";
}

View File

@@ -0,0 +1,151 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.dictionary;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.service.namespace.NamespaceException;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.NamespaceService;
/**
* JCR Namespace Resolver
*
* @author David Caruana
*/
public class JCRNamespacePrefixResolver implements NamespaceService
{
// delegate
private NamespacePrefixResolver delegate;
// prefix -> uri
private Map<String, String> prefixes = new HashMap<String, String>();
// uri -> prefix
private Map<String, String> uris = new HashMap<String, String>();
/**
* Construct
*
* @param delegate namespace delegate
*/
public JCRNamespacePrefixResolver(NamespacePrefixResolver delegate)
{
this.delegate = delegate;
}
/* (non-Javadoc)
* @see org.alfresco.service.namespace.NamespacePrefixResolver#getPrefixes(java.lang.String)
*/
public Collection<String> getPrefixes(String namespaceURI) throws NamespaceException
{
String prefix = uris.get(namespaceURI);
if (prefix == null)
{
return delegate.getPrefixes(namespaceURI);
}
List<String> prefixes = new ArrayList<String>();
prefixes.add(prefix);
return prefixes;
}
/* (non-Javadoc)
* @see org.alfresco.service.namespace.NamespacePrefixResolver#getPrefixes()
*/
public Collection<String> getPrefixes()
{
List<String> prefixes = new ArrayList<String>();
Collection<String> uris = getURIs();
for (String uri : uris)
{
Collection<String> uriPrefixes = getPrefixes(uri);
prefixes.addAll(uriPrefixes);
}
return prefixes;
}
/* (non-Javadoc)
* @see org.alfresco.service.namespace.NamespaceService#registerNamespace(java.lang.String, java.lang.String)
*/
public void registerNamespace(String prefix, String uri)
{
//
// Check re-mapping according to JCR specification
//
// Cannot map any prefix that starts with xml
if (prefix.toLowerCase().startsWith(JCRNamespace.XML_PREFIX))
{
throw new NamespaceException("Cannot map prefix " + prefix + " as it is reserved");
}
// Cannot remap a prefix that is already assigned to a uri
String existingUri = delegate.getNamespaceURI(prefix);
if (existingUri != null)
{
throw new NamespaceException("Cannot map prefix " + prefix + " as it is already assigned to uri " + existingUri);
}
// Cannot map a prefix to a non-existent uri
Collection<String> existingURIs = delegate.getURIs();
if (existingURIs.contains(uri) == false)
{
throw new NamespaceException("Cannot map prefix " + prefix + " to uri " + uri + " which does not exist");
}
prefixes.put(prefix, uri);
uris.put(uri, prefix);
}
/* (non-Javadoc)
* @see org.alfresco.service.namespace.NamespaceService#unregisterNamespace(java.lang.String)
*/
public void unregisterNamespace(String prefix)
{
String uri = prefixes.get(prefix);
if (uri != null)
{
uris.remove(uri);
}
prefixes.remove(prefix);
}
public String getNamespaceURI(String prefix) throws NamespaceException
{
String uri = prefixes.get(prefix);
if (uri == null)
{
return delegate.getNamespaceURI(prefix);
}
return uri;
}
/* (non-Javadoc)
* @see org.alfresco.service.namespace.NamespacePrefixResolver#getURIs()
*/
public Collection<String> getURIs()
{
return delegate.getURIs();
}
}

View File

@@ -0,0 +1,146 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.dictionary;
import java.util.Collection;
import javax.jcr.AccessDeniedException;
import javax.jcr.NamespaceException;
import javax.jcr.NamespaceRegistry;
import javax.jcr.RepositoryException;
import javax.jcr.UnsupportedRepositoryOperationException;
import org.alfresco.service.namespace.NamespaceService;
/**
* Alfresco implementation of a JCR Namespace registry
*
* @author David Caruana
*/
public class NamespaceRegistryImpl implements NamespaceRegistry
{
private boolean allowRegistration;
private NamespaceService namespaceService;
/**
* Construct
*
* @param namespaceService namespace service
*/
public NamespaceRegistryImpl(boolean allowRegistraton, NamespaceService namespaceService)
{
this.allowRegistration = allowRegistraton;
this.namespaceService = namespaceService;
}
/**
* Get the namespace prefix resolver
*
* @return the namespace prefix resolver
*/
public NamespaceService getNamespaceService()
{
return this.namespaceService;
}
/* (non-Javadoc)
* @see javax.jcr.NamespaceRegistry#registerNamespace(java.lang.String, java.lang.String)
*/
public void registerNamespace(String prefix, String uri) throws NamespaceException, UnsupportedRepositoryOperationException, AccessDeniedException, RepositoryException
{
try
{
if (!allowRegistration)
{
throw new UnsupportedRepositoryOperationException();
}
namespaceService.registerNamespace(prefix, uri);
}
catch(org.alfresco.service.namespace.NamespaceException e)
{
throw new NamespaceException(e);
}
}
/* (non-Javadoc)
* @see javax.jcr.NamespaceRegistry#unregisterNamespace(java.lang.String)
*/
public void unregisterNamespace(String prefix) throws NamespaceException, UnsupportedRepositoryOperationException, AccessDeniedException, RepositoryException
{
try
{
if (!allowRegistration)
{
throw new UnsupportedRepositoryOperationException();
}
namespaceService.unregisterNamespace(prefix);
}
catch(org.alfresco.service.namespace.NamespaceException e)
{
throw new NamespaceException(e);
}
}
/* (non-Javadoc)
* @see javax.jcr.NamespaceRegistry#getPrefixes()
*/
public String[] getPrefixes() throws RepositoryException
{
Collection<String> prefixes = namespaceService.getPrefixes();
return prefixes.toArray(new String[prefixes.size()]);
}
/* (non-Javadoc)
* @see javax.jcr.NamespaceRegistry#getURIs()
*/
public String[] getURIs() throws RepositoryException
{
Collection<String> uris = namespaceService.getURIs();
return uris.toArray(new String[uris.size()]);
}
/* (non-Javadoc)
* @see javax.jcr.NamespaceRegistry#getURI(java.lang.String)
*/
public String getURI(String prefix) throws NamespaceException, RepositoryException
{
String uri = namespaceService.getNamespaceURI(prefix);
if (uri == null)
{
throw new NamespaceException("Prefix " + prefix + " is unknown.");
}
return uri;
}
/* (non-Javadoc)
* @see javax.jcr.NamespaceRegistry#getPrefix(java.lang.String)
*/
public String getPrefix(String uri) throws NamespaceException, RepositoryException
{
Collection<String> prefixes = namespaceService.getPrefixes(uri);
if (prefixes.size() == 0)
{
throw new NamespaceException("URI " + uri + " is unknown.");
}
// Return first prefix registered for uri
return prefixes.iterator().next();
}
}

View File

@@ -0,0 +1,126 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.dictionary;
import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.NodeType;
import javax.jcr.version.OnParentVersionAction;
import org.alfresco.service.cmr.dictionary.ChildAssociationDefinition;
import org.alfresco.service.cmr.dictionary.ClassDefinition;
/**
* Alfresco implementation of a JCR Node Definition
*
* @author David Caruana
*
*/
public class NodeDefinitionImpl implements NodeDefinition
{
private NodeTypeManagerImpl typeManager;
private ChildAssociationDefinition assocDef;
/**
* Construct
*
* @param typeManager
* @param assocDef
*/
public NodeDefinitionImpl(NodeTypeManagerImpl typeManager, ChildAssociationDefinition assocDef)
{
this.typeManager = typeManager;
this.assocDef = assocDef;
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeDefinition#getRequiredPrimaryTypes()
*/
public NodeType[] getRequiredPrimaryTypes()
{
// Note: target class is mandatory in Alfresco
ClassDefinition target = assocDef.getTargetClass();
return new NodeType[] { typeManager.getNodeTypeImpl(target.getName()) };
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeDefinition#getDefaultPrimaryType()
*/
public NodeType getDefaultPrimaryType()
{
return null;
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeDefinition#allowsSameNameSiblings()
*/
public boolean allowsSameNameSiblings()
{
return assocDef.getDuplicateChildNamesAllowed();
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.ItemDefinition#getDeclaringNodeType()
*/
public NodeType getDeclaringNodeType()
{
return typeManager.getNodeTypeImpl(assocDef.getSourceClass().getName());
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.ItemDefinition#getName()
*/
public String getName()
{
return assocDef.getName().toPrefixString(typeManager.getNamespaceService());
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.ItemDefinition#isAutoCreated()
*/
public boolean isAutoCreated()
{
return isMandatory();
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.ItemDefinition#isMandatory()
*/
public boolean isMandatory()
{
return assocDef.isTargetMandatory();
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.ItemDefinition#getOnParentVersion()
*/
public int getOnParentVersion()
{
// TODO: Check this correct
return OnParentVersionAction.INITIALIZE;
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.ItemDefinition#isProtected()
*/
public boolean isProtected()
{
return assocDef.isProtected();
}
}

View File

@@ -0,0 +1,426 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.dictionary;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.PropertyDefinition;
import org.alfresco.jcr.item.ValueImpl;
import org.alfresco.jcr.item.property.JCRMixinTypesProperty;
import org.alfresco.jcr.item.property.JCRPrimaryTypeProperty;
import org.alfresco.service.cmr.dictionary.ChildAssociationDefinition;
import org.alfresco.service.cmr.dictionary.ClassDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.namespace.QName;
/**
* Alfresco implementation of a Node Type Definition
*
* @author David Caruana
*/
public class NodeTypeImpl implements NodeType
{
// The required nt:base type specified by JCR
public static QName NT_BASE = QName.createQName(JCRNamespace.NT_URI, "base");
// The optional mix:referenceable specified by JCR
public static QName MIX_REFERENCEABLE = QName.createQName(JCRNamespace.MIX_URI, "referenceable");
// The optional mix:lockable specified by JCR
public static QName MIX_LOCKABLE = QName.createQName(JCRNamespace.MIX_URI, "lockable");
// The optional mix:versionable specified by JCR
public static QName MIX_VERSIONABLE = QName.createQName(JCRNamespace.MIX_URI, "versionable");
private NodeTypeManagerImpl typeManager;
private ClassDefinition classDefinition;
/**
* Construct
*
* @param classDefinition Alfresco class definition
*/
public NodeTypeImpl(NodeTypeManagerImpl typeManager, ClassDefinition classDefinition)
{
this.typeManager = typeManager;
this.classDefinition = classDefinition;
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeType#getName()
*/
public String getName()
{
return classDefinition.getName().toPrefixString(typeManager.getNamespaceService());
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeType#isMixin()
*/
public boolean isMixin()
{
return classDefinition.isAspect();
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeType#hasOrderableChildNodes()
*/
public boolean hasOrderableChildNodes()
{
// Note: For now, we don't expose this through JCR
return false;
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeType#getPrimaryItemName()
*/
public String getPrimaryItemName()
{
// NOTE: Alfresco does not support the notion of PrimaryItem (not yet anyway)
return null;
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeType#getSupertypes()
*/
public NodeType[] getSupertypes()
{
List<NodeType> nodeTypes = new ArrayList<NodeType>();
NodeType[] declaredSupertypes = getDeclaredSupertypes();
while (declaredSupertypes.length > 0)
{
// Alfresco supports single inheritence only
NodeType supertype = declaredSupertypes[0];
nodeTypes.add(supertype);
declaredSupertypes = supertype.getDeclaredSupertypes();
}
return nodeTypes.toArray(new NodeType[nodeTypes.size()]);
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeType#getDeclaredSupertypes()
*/
public NodeType[] getDeclaredSupertypes()
{
// return no supertype when type is nt:base
if (classDefinition.getName().equals(NT_BASE))
{
return new NodeType[] {};
}
// return root type when no parent (nt:base if a type hierarchy)
QName parent = classDefinition.getParentName();
if (parent == null)
{
if (classDefinition.isAspect())
{
return new NodeType[] {};
}
else
{
return new NodeType[] { typeManager.getNodeTypeImpl(NT_BASE) };
}
}
// return the supertype
return new NodeType[] { typeManager.getNodeTypeImpl(parent) };
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeType#isNodeType(java.lang.String)
*/
public boolean isNodeType(String nodeTypeName)
{
QName name = QName.createQName(nodeTypeName, typeManager.getNamespaceService());
// is it one of standard types
if (name.equals(NodeTypeImpl.NT_BASE))
{
return true;
}
// is it part of this class hierarchy
return typeManager.getSession().getRepositoryImpl().getServiceRegistry().getDictionaryService().isSubClass(name, classDefinition.getName());
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeType#getPropertyDefinitions()
*/
public PropertyDefinition[] getPropertyDefinitions()
{
Map<QName, org.alfresco.service.cmr.dictionary.PropertyDefinition> propDefs = classDefinition.getProperties();
PropertyDefinition[] defs = new PropertyDefinition[propDefs.size() + (classDefinition.isAspect() ? 0 : 2)];
int i = 0;
for (org.alfresco.service.cmr.dictionary.PropertyDefinition propDef : propDefs.values())
{
defs[i++] = new PropertyDefinitionImpl(typeManager, propDef);
}
if (!classDefinition.isAspect())
{
// add nt:base properties
defs[i++] = typeManager.getPropertyDefinitionImpl(JCRPrimaryTypeProperty.PROPERTY_NAME);
defs[i++] = typeManager.getPropertyDefinitionImpl(JCRMixinTypesProperty.PROPERTY_NAME);
}
return defs;
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeType#getDeclaredPropertyDefinitions()
*/
public PropertyDefinition[] getDeclaredPropertyDefinitions()
{
Map<QName, org.alfresco.service.cmr.dictionary.PropertyDefinition> propDefs = classDefinition.getProperties();
List<PropertyDefinition> defs = new ArrayList<PropertyDefinition>();
for (org.alfresco.service.cmr.dictionary.PropertyDefinition propDef : propDefs.values())
{
if (propDef.getContainerClass().equals(classDefinition))
{
defs.add(new PropertyDefinitionImpl(typeManager, propDef));
}
}
if (classDefinition.equals(NT_BASE))
{
// add nt:base properties
defs.add(typeManager.getPropertyDefinitionImpl(JCRPrimaryTypeProperty.PROPERTY_NAME));
defs.add(typeManager.getPropertyDefinitionImpl(JCRMixinTypesProperty.PROPERTY_NAME));
}
return defs.toArray(new PropertyDefinition[defs.size()]);
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeType#getChildNodeDefinitions()
*/
public NodeDefinition[] getChildNodeDefinitions()
{
Map<QName, ChildAssociationDefinition> assocDefs = classDefinition.getChildAssociations();
NodeDefinition[] defs = new NodeDefinition[assocDefs.size()];
int i = 0;
for (ChildAssociationDefinition assocDef : assocDefs.values())
{
defs[i++] = new NodeDefinitionImpl(typeManager, assocDef);
}
return defs;
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeType#getDeclaredChildNodeDefinitions()
*/
public NodeDefinition[] getDeclaredChildNodeDefinitions()
{
Map<QName, ChildAssociationDefinition> assocDefs = classDefinition.getChildAssociations();
List<NodeDefinition> defs = new ArrayList<NodeDefinition>();
for (ChildAssociationDefinition assocDef : assocDefs.values())
{
if (assocDef.getSourceClass().equals(classDefinition))
{
defs.add(new NodeDefinitionImpl(typeManager, assocDef));
}
}
return defs.toArray(new NodeDefinition[defs.size()]);
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeType#canSetProperty(java.lang.String, javax.jcr.Value)
*/
public boolean canSetProperty(String propertyName, Value value)
{
try
{
// is an attempt to remove property being made
if (value == null)
{
return canRemoveItem(propertyName);
}
// retrieve property definition
QName propertyQName = QName.createQName(propertyName, typeManager.getNamespaceService());
Map<QName, org.alfresco.service.cmr.dictionary.PropertyDefinition> propDefs = classDefinition.getProperties();
org.alfresco.service.cmr.dictionary.PropertyDefinition propDef = propDefs.get(propertyQName);
if (propDef == null)
{
// Alfresco doesn't have residual properties yet
return false;
}
// is property read-write
if (propDef.isProtected() || propDef.isMultiValued())
{
return false;
}
// get required type to convert to
int requiredType = DataTypeMap.convertDataTypeToPropertyType(propDef.getDataType().getName());
if (requiredType == PropertyType.UNDEFINED)
{
requiredType = value.getType();
}
// convert value to required type
// Note: Invalid conversion will throw exception
ValueImpl.getValue(typeManager.getSession().getTypeConverter(), requiredType, value);
// Note: conversion succeeded
return true;
}
catch(RepositoryException e)
{
// Note: Not much can be done really
}
return false;
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeType#canSetProperty(java.lang.String, javax.jcr.Value[])
*/
public boolean canSetProperty(String propertyName, Value[] values)
{
try
{
// is an attempt to remove property being made
if (values == null)
{
return canRemoveItem(propertyName);
}
// retrieve property definition
QName propertyQName = QName.createQName(propertyName, typeManager.getNamespaceService());
Map<QName, org.alfresco.service.cmr.dictionary.PropertyDefinition> propDefs = classDefinition.getProperties();
org.alfresco.service.cmr.dictionary.PropertyDefinition propDef = propDefs.get(propertyQName);
if (propDef == null)
{
// Alfresco doesn't have residual properties yet
return false;
}
// is property read write
if (propDef.isProtected() || !propDef.isMultiValued())
{
return false;
}
// determine type of values to check
int valueType = PropertyType.UNDEFINED;
for (Value value : values)
{
if (value != null)
{
if (valueType != PropertyType.UNDEFINED && value.getType() != valueType)
{
// do not allow collection mixed type values
return false;
}
valueType = value.getType();
}
}
// get required type to convert to
int requiredType = DataTypeMap.convertDataTypeToPropertyType(propDef.getDataType().getName());
if (requiredType == PropertyType.UNDEFINED)
{
requiredType = valueType;
}
// convert values to required format
// Note: Invalid conversion will throw exception
for (Value value : values)
{
if (value != null)
{
ValueImpl.getValue(typeManager.getSession().getTypeConverter(), requiredType, value);
}
}
// Note: conversion succeeded
return true;
}
catch(RepositoryException e)
{
// Note: Not much can be done really
}
return false;
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeType#canAddChildNode(java.lang.String)
*/
public boolean canAddChildNode(String childNodeName)
{
// NOTE: Alfresco does not have default primary type notion
return false;
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeType#canAddChildNode(java.lang.String, java.lang.String)
*/
public boolean canAddChildNode(String childNodeName, String nodeTypeName)
{
boolean canAdd = false;
Map<QName, ChildAssociationDefinition> assocDefs = classDefinition.getChildAssociations();
QName childNodeQName = QName.createQName(childNodeName, typeManager.getNamespaceService());
ChildAssociationDefinition assocDef = assocDefs.get(childNodeQName);
if (assocDef != null)
{
QName nodeTypeQName = QName.createQName(nodeTypeName, typeManager.getNamespaceService());
DictionaryService dictionaryService = typeManager.getSession().getRepositoryImpl().getServiceRegistry().getDictionaryService();
canAdd = dictionaryService.isSubClass(nodeTypeQName, assocDef.getTargetClass().getName());
}
return canAdd;
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeType#canRemoveItem(java.lang.String)
*/
public boolean canRemoveItem(String itemName)
{
boolean isProtected = false;
boolean isMandatory = false;
// TODO: Property and Association names can clash? What to do?
QName itemQName = QName.createQName(itemName, typeManager.getNamespaceService());
Map<QName, org.alfresco.service.cmr.dictionary.PropertyDefinition> propDefs = classDefinition.getProperties();
org.alfresco.service.cmr.dictionary.PropertyDefinition propDef = propDefs.get(itemQName);
if (propDef != null)
{
isProtected = propDef.isProtected();
isMandatory = propDef.isMandatory();
}
Map<QName, ChildAssociationDefinition> assocDefs = classDefinition.getChildAssociations();
ChildAssociationDefinition assocDef = assocDefs.get(itemQName);
if (assocDef != null)
{
isProtected |= assocDef.isProtected();
isMandatory |= assocDef.isTargetMandatory();
}
return !isProtected && !isMandatory;
}
}

View File

@@ -0,0 +1,163 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.dictionary;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.NodeTypeIterator;
import javax.jcr.nodetype.NodeTypeManager;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.service.cmr.dictionary.ClassDefinition;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.namespace.QName;
/**
* Alfresco implementation of JCR Node Type Manager
*
* @author David Caruana
*/
public class NodeTypeManagerImpl implements NodeTypeManager
{
private SessionImpl session;
private NamespaceService namespaceService;
/**
* Construct
*
* @param dictionaryService dictionary service
* @param namespaceService namespace service (global repository registry)
*/
public NodeTypeManagerImpl(SessionImpl session, NamespaceService namespaceService)
{
this.session = session;
this.namespaceService = namespaceService;
}
/**
* Get Dictionary Service
*
* @return the dictionary service
*/
public SessionImpl getSession()
{
return session;
}
/**
* Get Namespace Service
*
* @return the namespace service
*/
public NamespaceService getNamespaceService()
{
return namespaceService;
}
/**
* Get Node Type Implementation for given Class Name
*
* @param nodeTypeName alfresco class name
* @return the node type
*/
public NodeTypeImpl getNodeTypeImpl(QName nodeTypeName)
{
// TODO: Might be worth caching here... wait and see
NodeTypeImpl nodeType = null;
ClassDefinition definition = session.getRepositoryImpl().getServiceRegistry().getDictionaryService().getClass(nodeTypeName);
if (definition != null)
{
nodeType = new NodeTypeImpl(this, definition);
}
return nodeType;
}
/**
* Get Property Definition Implementation for given Property Name
*
* @param propertyName alfresco property name
* @return the property
*/
public PropertyDefinitionImpl getPropertyDefinitionImpl(QName propertyName)
{
// TODO: Might be worth caching here... wait and see
PropertyDefinitionImpl propDef = null;
PropertyDefinition definition = session.getRepositoryImpl().getServiceRegistry().getDictionaryService().getProperty(propertyName);
if (definition != null)
{
propDef = new PropertyDefinitionImpl(this, definition);
}
return propDef;
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeTypeManager#getNodeType(java.lang.String)
*/
public NodeType getNodeType(String nodeTypeName) throws NoSuchNodeTypeException, RepositoryException
{
QName name = QName.createQName(nodeTypeName, namespaceService);
NodeTypeImpl nodeTypeImpl = getNodeTypeImpl(name);
if (nodeTypeImpl == null)
{
throw new NoSuchNodeTypeException("Node type " + nodeTypeName + " does not exist");
}
return nodeTypeImpl;
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeTypeManager#getAllNodeTypes()
*/
public NodeTypeIterator getAllNodeTypes() throws RepositoryException
{
Collection<QName> typeNames = session.getRepositoryImpl().getServiceRegistry().getDictionaryService().getAllTypes();
Collection<QName> aspectNames = session.getRepositoryImpl().getServiceRegistry().getDictionaryService().getAllAspects();
List<QName> typesList = new ArrayList<QName>(typeNames.size() + aspectNames.size());
typesList.addAll(typeNames);
typesList.addAll(aspectNames);
return new NodeTypeNameIterator(this, typesList);
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeTypeManager#getPrimaryNodeTypes()
*/
public NodeTypeIterator getPrimaryNodeTypes() throws RepositoryException
{
Collection<QName> typeNames = session.getRepositoryImpl().getServiceRegistry().getDictionaryService().getAllTypes();
List<QName> typesList = new ArrayList<QName>(typeNames.size());
typesList.addAll(typeNames);
return new NodeTypeNameIterator(this, typesList);
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeTypeManager#getMixinNodeTypes()
*/
public NodeTypeIterator getMixinNodeTypes() throws RepositoryException
{
Collection<QName> typeNames = session.getRepositoryImpl().getServiceRegistry().getDictionaryService().getAllAspects();
List<QName> typesList = new ArrayList<QName>(typeNames.size());
typesList.addAll(typeNames);
return new NodeTypeNameIterator(this, typesList);
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.dictionary;
import java.util.List;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.NodeTypeIterator;
import org.alfresco.jcr.util.AbstractRangeIterator;
import org.alfresco.service.namespace.QName;
/**
* Alfresco implementation of a Node Type Iterator
*
* @author David Caruana
*/
public class NodeTypeNameIterator extends AbstractRangeIterator
implements NodeTypeIterator
{
private NodeTypeManagerImpl typeManager;
private List<QName> nodeTypeNames;
/**
* Construct
*
* @param context session context
* @param nodeTypes node type list
*/
public NodeTypeNameIterator(NodeTypeManagerImpl typeManager, List<QName> nodeTypeNames)
{
this.typeManager = typeManager;
this.nodeTypeNames = nodeTypeNames;
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.NodeTypeIterator#nextNodeType()
*/
public NodeType nextNodeType()
{
long position = skip();
QName name = nodeTypeNames.get((int)position);
return typeManager.getNodeTypeImpl(name);
}
/* (non-Javadoc)
* @see javax.jcr.RangeIterator#getSize()
*/
public long getSize()
{
return nodeTypeNames.size();
}
/* (non-Javadoc)
* @see java.util.Iterator#next()
*/
public Object next()
{
return nextNodeType();
}
}

View File

@@ -0,0 +1,155 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.dictionary;
import javax.jcr.Value;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.PropertyDefinition;
import javax.jcr.version.OnParentVersionAction;
import org.alfresco.jcr.item.ValueImpl;
import org.alfresco.jcr.item.property.JCRMixinTypesProperty;
import org.alfresco.jcr.item.property.JCRPrimaryTypeProperty;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.dictionary.ClassDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
/**
* Alfresco implementation of a JCR Property Definition
*
* @author David Caruana
*/
public class PropertyDefinitionImpl implements PropertyDefinition
{
/** Session */
private NodeTypeManagerImpl typeManager;
/** Alfresco Property Definition */
private org.alfresco.service.cmr.dictionary.PropertyDefinition propDef;
/**
* Construct
*
* @param propDef Alfresco Property Definition
*/
public PropertyDefinitionImpl(NodeTypeManagerImpl typeManager, org.alfresco.service.cmr.dictionary.PropertyDefinition propDef)
{
this.typeManager = typeManager;
this.propDef = propDef;
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.PropertyDefinition#getRequiredType()
*/
public int getRequiredType()
{
// TODO: Switch on data type
if (propDef.getName().equals(ContentModel.PROP_CONTENT))
{
return DataTypeMap.convertDataTypeToPropertyType(DataTypeDefinition.CONTENT);
}
return DataTypeMap.convertDataTypeToPropertyType(propDef.getDataType().getName());
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.PropertyDefinition#getValueConstraints()
*/
public String[] getValueConstraints()
{
return new String[] {};
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.PropertyDefinition#getDefaultValues()
*/
public Value[] getDefaultValues()
{
String defaultValue = propDef.getDefaultValue();
if (defaultValue == null)
{
return null;
}
return new Value[] { new ValueImpl(typeManager.getSession(), getRequiredType(), defaultValue) };
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.PropertyDefinition#isMultiple()
*/
public boolean isMultiple()
{
return propDef.isMultiValued();
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.ItemDefinition#getDeclaringNodeType()
*/
public NodeType getDeclaringNodeType()
{
ClassDefinition declaringClass = propDef.getContainerClass();
return typeManager.getNodeTypeImpl(declaringClass.getName());
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.ItemDefinition#getName()
*/
public String getName()
{
return propDef.getName().toPrefixString(typeManager.getNamespaceService());
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.ItemDefinition#isAutoCreated()
*/
public boolean isAutoCreated()
{
return isMandatory();
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.ItemDefinition#isMandatory()
*/
public boolean isMandatory()
{
return propDef.isMandatory();
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.ItemDefinition#getOnParentVersion()
*/
public int getOnParentVersion()
{
// TODO: There's no equivalent in Alfresco, so hard code for now
if (propDef.getName().equals(JCRPrimaryTypeProperty.PROPERTY_NAME) ||
propDef.getName().equals(JCRMixinTypesProperty.PROPERTY_NAME))
{
return OnParentVersionAction.COMPUTE;
}
// TODO: Check this
return OnParentVersionAction.INITIALIZE;
}
/* (non-Javadoc)
* @see javax.jcr.nodetype.ItemDefinition#isProtected()
*/
public boolean isProtected()
{
return propDef.isProtected();
}
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.dictionary;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
/**
* Encapsulate Versionable Mixin behaviour mapping to Alfresco
*
* @author davidc
*/
public class VersionableMixin implements ClassMap.AddMixin, ClassMap.RemoveMixin
{
/*
* (non-Javadoc)
* @see org.alfresco.jcr.dictionary.ClassMap.AddMixin#preAddMixin(org.alfresco.jcr.session.SessionImpl, org.alfresco.service.cmr.repository.NodeRef)
*/
public Map<QName, Serializable> preAddMixin(SessionImpl session, NodeRef nodeRef)
{
// switch off auto-versioning
Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
properties.put(ContentModel.PROP_INITIAL_VERSION, false);
properties.put(ContentModel.PROP_AUTO_VERSION, false);
return properties;
}
/*
* (non-Javadoc)
* @see org.alfresco.jcr.dictionary.ClassMap.AddMixin#postAddMixin(org.alfresco.jcr.session.SessionImpl, org.alfresco.service.cmr.repository.NodeRef)
*/
public void postAddMixin(SessionImpl session, NodeRef nodeRef)
{
}
/*
* (non-Javadoc)
* @see org.alfresco.jcr.dictionary.ClassMap.RemoveMixin#preRemoveMixin(org.alfresco.jcr.session.SessionImpl, org.alfresco.service.cmr.repository.NodeRef)
*/
public void preRemoveMixin(SessionImpl session, NodeRef nodeRef)
{
}
/*
* (non-Javadoc)
* @see org.alfresco.jcr.dictionary.ClassMap.RemoveMixin#postRemoveMixin(org.alfresco.jcr.session.SessionImpl, org.alfresco.service.cmr.repository.NodeRef)
*/
public void postRemoveMixin(SessionImpl session, NodeRef nodeRef)
{
}
}

View File

@@ -0,0 +1,83 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.example;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.Repository;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import org.alfresco.jcr.api.JCRNodeRef;
import org.alfresco.model.ContentModel;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Example that demonstrate use of JCR and Alfresco API calls.
*
* @author David Caruana
*/
public class MixedExample
{
public static void main(String[] args)
throws Exception
{
// Setup Spring and Transaction Service
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:alfresco/application-context.xml");
ServiceRegistry registry = (ServiceRegistry)context.getBean(ServiceRegistry.SERVICE_REGISTRY);
NodeService nodeService = (NodeService)registry.getNodeService();
// Retrieve Repository
Repository repository = (Repository)context.getBean("JCR.Repository");
// Login to workspace
// Note: Default workspace is the one used by Alfresco Web Client which contains all the Spaces
// and their documents
Session session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
try
{
// Retrieve Company Home
Node root = session.getRootNode();
Node companyHome = root.getNode("app:company_home");
// Read Company Home Name
Property name = companyHome.getProperty("cm:name");
System.out.println("Name = " + name.getString());
// Update Node via Alfresco Node Service API
NodeRef companyHomeRef = JCRNodeRef.getNodeRef(companyHome);
nodeService.setProperty(companyHomeRef, ContentModel.PROP_NAME, "Updated Company Home Name");
// Re-read via JCR
System.out.println("Updated name = " + name.getString());
}
finally
{
session.logout();
System.exit(0);
}
}
}

View File

@@ -0,0 +1,87 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.example;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.Repository;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Simple Example that demonstrate login and retrieval of top-level Spaces
* under Company Home.
*
* @author David Caruana
*/
public class SimpleExample
{
public static void main(String[] args)
throws Exception
{
// Setup Spring and Transaction Service
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:alfresco/application-context.xml");
// Retrieve Repository
Repository repository = (Repository)context.getBean("JCR.Repository");
// Login to workspace
// Note: Default workspace is the one used by Alfresco Web Client which contains all the Spaces
// and their documents
Session session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
try
{
// Retrieve Company Home
Node root = session.getRootNode();
Node companyHome = root.getNode("app:company_home");
// Iterator through children of Company Home
NodeIterator iterator = companyHome.getNodes();
while(iterator.hasNext())
{
Node child = iterator.nextNode();
System.out.println(child.getName());
PropertyIterator propIterator = child.getProperties();
while(propIterator.hasNext())
{
Property prop = propIterator.nextProperty();
if (!prop.getDefinition().isMultiple())
{
System.out.println(" " + prop.getName() + " = " + prop.getString());
}
}
}
}
finally
{
session.logout();
System.exit(0);
}
}
}

View File

@@ -0,0 +1,400 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.example;
import java.io.File;
import java.io.FileOutputStream;
import java.util.Calendar;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.Property;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.Value;
import javax.jcr.Workspace;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.jcr.version.Version;
import javax.jcr.version.VersionHistory;
import javax.jcr.version.VersionIterator;
import org.alfresco.jcr.api.JCRNodeRef;
import org.alfresco.model.ContentModel;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.security.PermissionService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.core.io.ClassPathResource;
/**
* Example that demonstrates read and write of a simple WIKI model
*
* Please refer to http://www.alfresco.org/mediawiki/index.php/Introducing_the_Alfresco_Java_Content_Repository_API
* for a complete description of this example.
*
* @author David Caruana
*/
public class WIKIExample
{
public static void main(String[] args)
throws Exception
{
//
// Repository Initialisation
//
// access the Alfresco JCR Repository (here it's via programmatic approach, but it could also be injected)
System.out.println("Initialising Repository...");
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:org/alfresco/jcr/example/wiki-context.xml");
Repository repository = (Repository)context.getBean("JCR.Repository");
// display information about the repository
System.out.println("Repository Description...");
String[] keys = repository.getDescriptorKeys();
for (String key : keys)
{
String value = repository.getDescriptor(key);
System.out.println(" " + key + " = " + value);
}
//
// Create a WIKI structure
//
// Note: Here we're using the Alfresco Content Model and custom WIKI model to create
// WIKI pages and Content that are accessible via the Alfresco Web Client
//
// login to workspace (here we rely on the default workspace defined by JCR.Repository bean)
Session session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
try
{
System.out.println("Creating WIKI...");
// first, access the company home
Node rootNode = session.getRootNode();
System.out.println("Root node: path=" + rootNode.getPath() + ", type=" + rootNode.getPrimaryNodeType().getName());
Node companyHome = rootNode.getNode("app:company_home");
System.out.println("Company home node: path=" + companyHome.getPath() + ", type=" + companyHome.getPrimaryNodeType().getName());
// remove the WIKI structure if it already exists
try
{
Node encyclopedia = companyHome.getNode("wiki:encyclopedia");
encyclopedia.remove();
System.out.println("Existing WIKI found and removed");
}
catch(PathNotFoundException e)
{
// doesn't exist, no need to remove
}
// create the root WIKI folder
Node encyclopedia = companyHome.addNode("wiki:encyclopedia", "cm:folder");
encyclopedia.setProperty("cm:name", "WIKI Encyclopedia");
encyclopedia.setProperty("cm:description", "");
// create first wiki page
Node page1 = encyclopedia.addNode("wiki:entry1", "wiki:page");
page1.setProperty("cm:name", "Rose");
page1.setProperty("cm:description", "");
page1.setProperty("cm:title", "The rose");
page1.setProperty("cm:content", "A rose is a flowering shrub.");
page1.setProperty("wiki:category", new String[] {"flower", "plant", "rose"});
// create second wiki page
Node page2 = encyclopedia.addNode("wiki:entry2", "wiki:page");
page2.setProperty("cm:name", "Shakespeare");
page2.setProperty("cm:description", "");
page2.setProperty("cm:title", "William Shakespeare");
page2.setProperty("cm:content", "A famous poet who likes roses.");
page2.setProperty("wiki:restrict", true);
page2.setProperty("wiki:category", new String[] {"poet"});
// create an image (note: we're using an input stream to allow setting of binary content)
Node contentNode = encyclopedia.addNode("wiki:image", "cm:content");
contentNode.setProperty("cm:name", "Dog");
contentNode.setProperty("cm:description", "");
contentNode.setProperty("cm:title", "My dog at New Year party");
ClassPathResource resource = new ClassPathResource("org/alfresco/jcr/example/wikiImage.gif");
contentNode.setProperty("cm:content", resource.getInputStream());
session.save();
System.out.println("WIKI created");
}
finally
{
session.logout();
}
//
// Access the WIKI structure
//
// login to workspace (here we rely on the default workspace defined by JCR.Repository bean)
session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
try
{
System.out.println("Accessing WIKI...");
// access a wiki node directly from root node (by path and by UUID)
Node rootNode = session.getRootNode();
Node encyclopedia = rootNode.getNode("app:company_home/wiki:encyclopedia");
Node direct = session.getNodeByUUID(encyclopedia.getUUID());
System.out.println("Found WIKI root correctly: " + encyclopedia.equals(direct));
// access a wiki property directly from root node
Node entry1 = rootNode.getNode("app:company_home/wiki:encyclopedia/wiki:entry1");
String title = entry1.getProperty("cm:title").getString();
System.out.println("Found WIKI page 1 title: " + title);
Calendar modified = entry1.getProperty("cm:modified").getDate();
System.out.println("Found WIKI page 1 last modified date: " + modified.getTime());
// browse all wiki entries
System.out.println("WIKI browser:");
NodeIterator entries = encyclopedia.getNodes();
while (entries.hasNext())
{
Node entry = entries.nextNode();
outputContentNode(entry);
}
// perform a search
System.out.println("Search results:");
Workspace workspace = session.getWorkspace();
QueryManager queryManager = workspace.getQueryManager();
Query query = queryManager.createQuery("//app:company_home/wiki:encyclopedia/*[@cm:title = 'The rose']", Query.XPATH);
//Query query = queryManager.createQuery("//app:company_home/wiki:encyclopedia/*[jcr:contains(., 'rose')]", Query.XPATH);
QueryResult result = query.execute();
NodeIterator it = result.getNodes();
while (it.hasNext())
{
Node n = it.nextNode();
outputContentNode(n);
}
// export content (system view format)
File systemView = new File("systemview.xml");
FileOutputStream systemViewOut = new FileOutputStream(systemView);
session.exportSystemView("/app:company_home/wiki:encyclopedia", systemViewOut, false, false);
// export content (document view format)
File docView = new File("docview.xml");
FileOutputStream docViewOut = new FileOutputStream(docView);
session.exportDocumentView("/app:company_home/wiki:encyclopedia", docViewOut, false, false);
System.out.println("WIKI exported");
}
finally
{
session.logout();
}
//
// Advanced Usage
//
// 1) Check-out / Check-in and version history retrieval
session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
try
{
//
// Version WIKI Page 1
//
// first, access the page
Node rootNode = session.getRootNode();
Node entry1 = rootNode.getNode("app:company_home/wiki:encyclopedia/wiki:entry1");
// enable versioning capability
entry1.addMixin("mix:versionable");
// update the properties and content
entry1.setProperty("cm:title", "The Rise");
entry1.setProperty("cm:content", "A rose is a flowering shrub of the genus Rosa.");
Value[] categories = entry1.getProperty("wiki:category").getValues();
Value[] newCategories = new Value[categories.length + 1];
System.arraycopy(categories, 0, newCategories, 0, categories.length);
newCategories[categories.length] = session.getValueFactory().createValue("poet");
entry1.setProperty("wiki:category", newCategories);
// and checkin the changes
entry1.checkin();
// checkout, fix wiki title and checkin again
entry1.checkout();
entry1.setProperty("cm:title", "The Rose");
entry1.checkin();
session.save();
System.out.println("Versioned WIKI Page 1");
}
finally
{
session.logout();
}
// 2) Permission checks
session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
try
{
//
// Browse WIKI Page 1 Version History
//
// first, access the page
Node rootNode = session.getRootNode();
Node entry1 = rootNode.getNode("app:company_home/wiki:encyclopedia/wiki:entry1");
// retrieve the history for thte page
VersionHistory versionHistory = entry1.getVersionHistory();
VersionIterator versionIterator = versionHistory.getAllVersions();
// for each version, output the node as it was versioned
while (versionIterator.hasNext())
{
Version version = versionIterator.nextVersion();
NodeIterator nodeIterator = version.getNodes();
while (nodeIterator.hasNext())
{
Node versionedNode = nodeIterator.nextNode();
System.out.println(" Version: " + version.getName());
System.out.println(" Created: " + version.getCreated().getTime());
outputContentNode(versionedNode);
}
}
//
// Permission Checks
//
System.out.println("Testing Permissions:");
// check for JCR 'read' permission
session.checkPermission("app:company_home/wiki:encyclopedia/wiki:entry1", "read");
System.out.println("Session has 'read' permission on app:company_home/wiki:encyclopedia/wiki:entry1");
// check for Alfresco 'Take Ownership' permission
session.checkPermission("app:company_home/wiki:encyclopedia/wiki:entry1", PermissionService.TAKE_OWNERSHIP);
System.out.println("Session has 'take ownership' permission on app:company_home/wiki:encyclopedia/wiki:entry1");
}
finally
{
session.logout();
}
//
// Mixing JCR and Alfresco API calls
//
// Provide mimetype for WIKI content properties
//
session = repository.login(new SimpleCredentials("admin", "admin".toCharArray()));
try
{
// Retrieve the Alfresco Repository Service Registry
ServiceRegistry registry = (ServiceRegistry)context.getBean(ServiceRegistry.SERVICE_REGISTRY);
// set the mime type on both WIKI pages and Image
Node rootNode = session.getRootNode();
// note: we have to checkout entry1 first - it's versioned
Node entry1 = rootNode.getNode("app:company_home/wiki:encyclopedia/wiki:entry1");
entry1.checkout();
setMimetype(registry, entry1, "cm:content", MimetypeMap.MIMETYPE_TEXT_PLAIN);
entry1.checkin();
Node entry2 = rootNode.getNode("app:company_home/wiki:encyclopedia/wiki:entry2");
setMimetype(registry, entry2, "cm:content", MimetypeMap.MIMETYPE_TEXT_PLAIN);
Node image = rootNode.getNode("app:company_home/wiki:encyclopedia/wiki:image");
setMimetype(registry, image, "cm:content", MimetypeMap.MIMETYPE_IMAGE_GIF);
// save the changes
session.save();
System.out.println("Updated WIKI mimetypes via Alfresco calls");
}
finally
{
session.logout();
}
// exit
System.out.println("Completed successfully.");
System.exit(0);
}
private static void outputContentNode(Node node)
throws RepositoryException
{
// output common content properties
System.out.println(" Node " + node.getUUID());
System.out.println(" title: " + node.getProperty("cm:title").getString());
// output properties specific to WIKI page
if (node.getPrimaryNodeType().getName().equals("wiki:page"))
{
System.out.println(" content: " + node.getProperty("cm:content").getString());
System.out.println(" restrict: " + node.getProperty("wiki:restrict").getString());
// output multi-value property
Property categoryProperty = node.getProperty("wiki:category");
Value[] categories = categoryProperty.getValues();
for (Value category : categories)
{
System.out.println(" category: " + category.getString());
}
}
}
private static void setMimetype(ServiceRegistry registry, Node node, String propertyName, String mimeType)
throws RepositoryException
{
// convert the JCR Node to an Alfresco Node Reference
NodeRef nodeRef = JCRNodeRef.getNodeRef(node);
// retrieve the Content Property (represented as a ContentData object in Alfresco)
NodeService nodeService = registry.getNodeService();
ContentData content = (ContentData)nodeService.getProperty(nodeRef, ContentModel.PROP_CONTENT);
// update the Mimetype
content = ContentData.setMimetype(content, mimeType);
nodeService.setProperty(nodeRef, ContentModel.PROP_CONTENT, content);
}
}

View File

@@ -0,0 +1,16 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<import resource="classpath:alfresco/application-context.xml" />
<bean id="testDictionaryBootstrap" parent="dictionaryModelBootstrap" depends-on="JCR.DictionaryBootstrap">
<property name="models">
<list>
<value>org/alfresco/jcr/example/wikiModel.xml</value>
</list>
</property>
</bean>
</beans>

Binary file not shown.

After

Width:  |  Height:  |  Size: 753 KiB

View File

@@ -0,0 +1,34 @@
<model name="wiki:wikimodel" xmlns="http://www.alfresco.org/model/dictionary/1.0">
<imports>
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d" />
<import uri="http://www.alfresco.org/model/content/1.0" prefix="cm" />
</imports>
<namespaces>
<namespace uri="http://www.alfresco.org/model/jcr/example/wiki/1.0" prefix="wiki" />
</namespaces>
<types>
<type name="wiki:page">
<title>WIKI Page</title>
<parent>cm:content</parent>
<properties>
<property name="wiki:restrict">
<type>d:boolean</type>
<default>false</default>
</property>
<property name="wiki:category">
<type>d:text</type>
<multiple>true</multiple>
</property>
</properties>
<mandatory-aspects>
<aspect>cm:titled</aspect>
</mandatory-aspects>
</type>
</types>
</model>

View File

@@ -0,0 +1,491 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.exporter;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;
import org.alfresco.jcr.dictionary.JCRNamespace;
import org.alfresco.jcr.item.NodeImpl;
import org.alfresco.jcr.item.PropertyImpl;
import org.alfresco.jcr.item.property.JCRMixinTypesProperty;
import org.alfresco.jcr.item.property.JCRPrimaryTypeProperty;
import org.alfresco.jcr.item.property.JCRUUIDProperty;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.cmr.view.Exporter;
import org.alfresco.service.cmr.view.ExporterContext;
import org.alfresco.service.cmr.view.ExporterException;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Base64;
import org.alfresco.util.ISO9075;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
/**
* Alfresco Implementation of JCR Document XML Exporter
*
* @author David Caruana
*/
public class JCRDocumentXMLExporter implements Exporter
{
private SessionImpl session;
private ContentHandler contentHandler;
private List<QName> currentProperties = new ArrayList<QName>();
private List<Object> currentValues = new ArrayList<Object>();
/**
* Construct
*
* @param namespaceService namespace service
* @param nodeService node service
* @param contentHandler content handler
*/
public JCRDocumentXMLExporter(SessionImpl session, ContentHandler contentHandler)
{
this.session = session;
this.contentHandler = contentHandler;
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#start()
*/
public void start(ExporterContext exportNodeRef)
{
try
{
contentHandler.startDocument();
}
catch (SAXException e)
{
throw new ExporterException("Failed to process export start event", e);
}
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startNamespace(java.lang.String, java.lang.String)
*/
public void startNamespace(String prefix, String uri)
{
try
{
contentHandler.startPrefixMapping(prefix, uri);
}
catch (SAXException e)
{
throw new ExporterException("Failed to process start namespace event - prefix " + prefix + " uri " + uri, e);
}
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endNamespace(java.lang.String)
*/
public void endNamespace(String prefix)
{
try
{
contentHandler.endPrefixMapping(prefix);
}
catch (SAXException e)
{
throw new ExporterException("Failed to process end namespace event - prefix " + prefix, e);
}
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startNode(org.alfresco.service.cmr.repository.NodeRef)
*/
public void startNode(NodeRef nodeRef)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endNode(org.alfresco.service.cmr.repository.NodeRef)
*/
public void endNode(NodeRef nodeRef)
{
try
{
QName nodeName = getNodeName(nodeRef);
contentHandler.endElement(nodeName.getNamespaceURI(), nodeName.getLocalName(), toPrefixString(nodeName));
}
catch (SAXException e)
{
throw new ExporterException("Failed to process end node event - node ref " + nodeRef.toString(), e);
}
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startAspects(org.alfresco.service.cmr.repository.NodeRef)
*/
public void startAspects(NodeRef nodeRef)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endAspects(org.alfresco.service.cmr.repository.NodeRef)
*/
public void endAspects(NodeRef nodeRef)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startAspect(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/
public void startAspect(NodeRef nodeRef, QName aspect)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endAspect(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/
public void endAspect(NodeRef nodeRef, QName aspect)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startACL(org.alfresco.service.cmr.repository.NodeRef)
*/
public void startACL(NodeRef nodeRef)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#permission(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.security.AccessPermission)
*/
public void permission(NodeRef nodeRef, AccessPermission permission)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endACL(org.alfresco.service.cmr.repository.NodeRef)
*/
public void endACL(NodeRef nodeRef)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startProperties(org.alfresco.service.cmr.repository.NodeRef)
*/
public void startProperties(NodeRef nodeRef)
{
currentProperties.clear();
currentValues.clear();
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endProperties(org.alfresco.service.cmr.repository.NodeRef)
*/
public void endProperties(NodeRef nodeRef)
{
try
{
// create node attributes
AttributesImpl attrs = new AttributesImpl();
// primary type
NodeImpl nodeImpl = new NodeImpl(session, nodeRef);
PropertyImpl primaryType = new JCRPrimaryTypeProperty(nodeImpl);
attrs.addAttribute(JCRPrimaryTypeProperty.PROPERTY_NAME.getNamespaceURI(), JCRPrimaryTypeProperty.PROPERTY_NAME.getLocalName(),
toPrefixString(JCRPrimaryTypeProperty.PROPERTY_NAME), null, getValue(primaryType.getValue().getString()));
// mixin type
PropertyImpl mixinTypes = new JCRMixinTypesProperty(nodeImpl);
Collection<String> mixins = new ArrayList<String>();
for (Value value : mixinTypes.getValues())
{
mixins.add(value.getString());
}
attrs.addAttribute(JCRMixinTypesProperty.PROPERTY_NAME.getNamespaceURI(), JCRMixinTypesProperty.PROPERTY_NAME.getLocalName(),
toPrefixString(JCRMixinTypesProperty.PROPERTY_NAME), null, getCollectionValue(mixins));
// uuid (for mix:referencable)
attrs.addAttribute(JCRUUIDProperty.PROPERTY_NAME.getNamespaceURI(), JCRUUIDProperty.PROPERTY_NAME.getLocalName(),
toPrefixString(JCRUUIDProperty.PROPERTY_NAME), null, getValue(nodeRef.getId()));
// node properties
for (int i = 0; i < currentProperties.size(); i++)
{
Object value = currentValues.get(i);
String strValue = (value instanceof Collection) ? getCollectionValue((Collection)value) : getValue(value);
QName propName = currentProperties.get(i);
propName = encodeQName(propName);
attrs.addAttribute(propName.getNamespaceURI(), propName.getLocalName(), toPrefixString(propName), null, strValue);
}
// emit node element
QName nodeName = getNodeName(nodeRef);
contentHandler.startElement(nodeName.getNamespaceURI(), nodeName.getLocalName(), toPrefixString(nodeName), attrs);
}
catch (ValueFormatException e)
{
throw new ExporterException("Failed to process properties event - nodeRef " + nodeRef);
}
catch (RepositoryException e)
{
throw new ExporterException("Failed to process properties event - nodeRef " + nodeRef);
}
catch (SAXException e)
{
throw new ExporterException("Failed to process properties event - nodeRef " + nodeRef);
}
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startProperty(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/
public void startProperty(NodeRef nodeRef, QName property)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endProperty(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/
public void endProperty(NodeRef nodeRef, QName property)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startValueCollection(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/
public void startValueCollection(NodeRef nodeRef, QName property)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endValueCollection(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/
public void endValueCollection(NodeRef nodeRef, QName property)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#value(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, java.io.Serializable)
*/
public void value(NodeRef nodeRef, QName property, Object value, int index)
{
currentProperties.add(property);
currentValues.add(value);
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#content(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, java.io.InputStream)
*/
public void content(NodeRef nodeRef, QName property, InputStream content, ContentData contentData, int index)
{
try
{
StringBuffer strValue = new StringBuffer(9 * 1024);
if (content != null)
{
// emit base64 encoded content
InputStream base64content = new Base64.InputStream(content, Base64.ENCODE | Base64.DONT_BREAK_LINES);
byte[] buffer = new byte[9 * 1024];
int read;
while ((read = base64content.read(buffer, 0, buffer.length)) > 0)
{
String characters = new String(buffer, 0, read);
strValue.append(characters);
}
}
currentProperties.add(property);
currentValues.add(strValue.toString());
}
catch (IOException e)
{
throw new ExporterException("Failed to process content event - nodeRef " + nodeRef + "; property " + toPrefixString(property));
}
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startAssoc(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/
public void startAssoc(NodeRef nodeRef, QName assoc)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endAssoc(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/
public void endAssoc(NodeRef nodeRef, QName assoc)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startAssocs(org.alfresco.service.cmr.repository.NodeRef)
*/
public void startAssocs(NodeRef nodeRef)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endAssocs(org.alfresco.service.cmr.repository.NodeRef)
*/
public void endAssocs(NodeRef nodeRef)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startReference(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/
public void startReference(NodeRef nodeRef, QName childName)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endReference(org.alfresco.service.cmr.repository.NodeRef)
*/
public void endReference(NodeRef nodeRef)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#warning(java.lang.String)
*/
public void warning(String warning)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#end()
*/
public void end()
{
try
{
contentHandler.endDocument();
}
catch (SAXException e)
{
throw new ExporterException("Failed to process end export event", e);
}
}
/**
* Get the prefix for the specified URI
* @param uri the URI
* @return the prefix (or null, if one is not registered)
*/
private String toPrefixString(QName qname)
{
return qname.toPrefixString(session.getNamespaceResolver());
}
/**
* Get name of Node
*
* @param nodeRef node reference
* @return node name
*/
private QName getNodeName(NodeRef nodeRef)
{
// establish name of node
QName childQName = null;
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
NodeRef rootNode = nodeService.getRootNode(nodeRef.getStoreRef());
if (rootNode.equals(nodeRef))
{
childQName = QName.createQName(JCRNamespace.JCR_URI, "root");
}
else
{
Path path = nodeService.getPath(nodeRef);
String childName = path.last().getElementString();
childQName = QName.createQName(childName);
childQName = encodeQName(childQName);
}
return childQName;
}
/**
* Get single-valued property
*
* @param value
* @return
*/
private String getValue(Object value)
throws RepositoryException
{
String strValue = session.getTypeConverter().convert(String.class, value);
return encodeBlanks(strValue);
}
/**
* Get multi-valued property
*
* @param values
* @return
*/
private String getCollectionValue(Collection values)
{
Collection<String> strValues = session.getTypeConverter().getConverter().convert(String.class, values);
StringBuffer buffer = new StringBuffer();
int i = 0;
for (String strValue : strValues)
{
buffer.append(encodeBlanks(strValue));
i++;
if (i < strValues.size())
{
buffer.append(" ");
}
}
return buffer.toString();
}
/**
* Encode Name for Document View Output
*
* @param name name to encode
* @return encoded name
*/
private QName encodeQName(QName name)
{
return QName.createQName(name.getNamespaceURI(), ISO9075.encode(name.getLocalName()));
}
/**
* Encode blanks in value
*
* @param value
* @return
*/
private String encodeBlanks(String value)
{
return value.replaceAll(" ", "_x0020_");
}
}

View File

@@ -0,0 +1,464 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.exporter;
import java.io.IOException;
import java.io.InputStream;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import org.alfresco.jcr.dictionary.JCRNamespace;
import org.alfresco.jcr.dictionary.PropertyDefinitionImpl;
import org.alfresco.jcr.item.NodeImpl;
import org.alfresco.jcr.item.PropertyImpl;
import org.alfresco.jcr.item.property.JCRMixinTypesProperty;
import org.alfresco.jcr.item.property.JCRPrimaryTypeProperty;
import org.alfresco.jcr.item.property.JCRUUIDProperty;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.security.AccessPermission;
import org.alfresco.service.cmr.view.Exporter;
import org.alfresco.service.cmr.view.ExporterContext;
import org.alfresco.service.cmr.view.ExporterException;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Base64;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
/**
* Alfresco Implementation of JCR System XML Exporter
*
* @author David Caruana
*/
public class JCRSystemXMLExporter implements Exporter
{
public final static String NODE_LOCALNAME = "node";
public final static String NAME_LOCALNAME = "name";
public final static String PROPERTY_LOCALNAME = "property";
public final static String TYPE_LOCALNAME = "type";
public final static String VALUE_LOCALNAME = "value";
public final static QName NODE_QNAME = QName.createQName(JCRNamespace.SV_URI, NODE_LOCALNAME);
public final static QName NAME_QNAME = QName.createQName(JCRNamespace.SV_URI, NAME_LOCALNAME);
public final static QName PROPERTY_QNAME = QName.createQName(JCRNamespace.SV_URI, PROPERTY_LOCALNAME);
public final static QName TYPE_QNAME = QName.createQName(JCRNamespace.SV_URI, TYPE_LOCALNAME);
public final static QName VALUE_QNAME = QName.createQName(JCRNamespace.SV_URI, VALUE_LOCALNAME);
private SessionImpl session;
private ContentHandler contentHandler;
private final static AttributesImpl EMPTY_ATTRIBUTES = new AttributesImpl();
/**
* Construct
*
* @param namespaceService namespace service
* @param nodeService node service
* @param contentHandler content handler
*/
public JCRSystemXMLExporter(SessionImpl session, ContentHandler contentHandler)
{
this.session = session;
this.contentHandler = contentHandler;
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#start()
*/
public void start(ExporterContext exportNodeRef)
{
try
{
contentHandler.startDocument();
}
catch (SAXException e)
{
throw new ExporterException("Failed to process export start event", e);
}
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startNamespace(java.lang.String, java.lang.String)
*/
public void startNamespace(String prefix, String uri)
{
try
{
contentHandler.startPrefixMapping(prefix, uri);
}
catch (SAXException e)
{
throw new ExporterException("Failed to process start namespace event - prefix " + prefix + " uri " + uri, e);
}
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endNamespace(java.lang.String)
*/
public void endNamespace(String prefix)
{
try
{
contentHandler.endPrefixMapping(prefix);
}
catch (SAXException e)
{
throw new ExporterException("Failed to process end namespace event - prefix " + prefix, e);
}
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startNode(org.alfresco.service.cmr.repository.NodeRef)
*/
public void startNode(NodeRef nodeRef)
{
try
{
// establish name of node
String childName;
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
NodeRef rootNode = nodeService.getRootNode(nodeRef.getStoreRef());
if (rootNode.equals(nodeRef))
{
childName = "jcr:root";
}
else
{
Path path = nodeService.getPath(nodeRef);
childName = path.last().getElementString();
}
QName childQName = QName.createQName(childName);
// create jcr node attributes
AttributesImpl attrs = new AttributesImpl();
attrs.addAttribute(NAME_QNAME.getNamespaceURI(), NAME_LOCALNAME, toPrefixString(NAME_QNAME), null, toPrefixString(childQName));
// emit node element
contentHandler.startElement(NODE_QNAME.getNamespaceURI(), NODE_LOCALNAME, toPrefixString(NODE_QNAME), attrs);
//
// emit jcr specifics
//
NodeImpl nodeImpl = new NodeImpl(session, nodeRef);
// primary type
PropertyImpl primaryType = new JCRPrimaryTypeProperty(nodeImpl);
startProperty(nodeRef, JCRPrimaryTypeProperty.PROPERTY_NAME);
value(nodeRef, JCRPrimaryTypeProperty.PROPERTY_NAME, primaryType.getValue().getString(), -1);
endProperty(nodeRef, JCRPrimaryTypeProperty.PROPERTY_NAME);
// mixin type
PropertyImpl mixinTypes = new JCRMixinTypesProperty(nodeImpl);
startProperty(nodeRef, JCRMixinTypesProperty.PROPERTY_NAME);
Value[] mixinValues = mixinTypes.getValues();
for (int i = 0; i < mixinValues.length; i++)
{
value(nodeRef, JCRMixinTypesProperty.PROPERTY_NAME, mixinValues[i], i);
}
endProperty(nodeRef, JCRMixinTypesProperty.PROPERTY_NAME);
// uuid (for mix:referencable)
startProperty(nodeRef, JCRUUIDProperty.PROPERTY_NAME);
value(nodeRef, JCRUUIDProperty.PROPERTY_NAME, nodeRef.getId(), -1);
endProperty(nodeRef, JCRUUIDProperty.PROPERTY_NAME);
}
catch (SAXException e)
{
throw new ExporterException("Failed to process start node event - node ref " + nodeRef.toString(), e);
}
catch (RepositoryException e)
{
throw new ExporterException("Failed to process start node event - node ref " + nodeRef.toString(), e);
}
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endNode(org.alfresco.service.cmr.repository.NodeRef)
*/
public void endNode(NodeRef nodeRef)
{
try
{
contentHandler.endElement(NODE_QNAME.getNamespaceURI(), NODE_LOCALNAME, toPrefixString(NODE_QNAME));
}
catch (SAXException e)
{
throw new ExporterException("Failed to process end node event - node ref " + nodeRef.toString(), e);
}
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startAspects(org.alfresco.service.cmr.repository.NodeRef)
*/
public void startAspects(NodeRef nodeRef)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endAspects(org.alfresco.service.cmr.repository.NodeRef)
*/
public void endAspects(NodeRef nodeRef)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startAspect(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/
public void startAspect(NodeRef nodeRef, QName aspect)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endAspect(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/
public void endAspect(NodeRef nodeRef, QName aspect)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startACL(org.alfresco.service.cmr.repository.NodeRef)
*/
public void startACL(NodeRef nodeRef)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#permission(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.cmr.security.AccessPermission)
*/
public void permission(NodeRef nodeRef, AccessPermission permission)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endACL(org.alfresco.service.cmr.repository.NodeRef)
*/
public void endACL(NodeRef nodeRef)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startProperties(org.alfresco.service.cmr.repository.NodeRef)
*/
public void startProperties(NodeRef nodeRef)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endProperties(org.alfresco.service.cmr.repository.NodeRef)
*/
public void endProperties(NodeRef nodeRef)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startProperty(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/
public void startProperty(NodeRef nodeRef, QName property)
{
try
{
// create jcr node attributes
DictionaryService dictionaryService = session.getRepositoryImpl().getServiceRegistry().getDictionaryService();
PropertyDefinition propDef = dictionaryService.getProperty(property);
PropertyDefinitionImpl propDefImpl = new PropertyDefinitionImpl(session.getTypeManager(), propDef);
String datatype = PropertyType.nameFromValue(propDefImpl.getRequiredType());
AttributesImpl attrs = new AttributesImpl();
attrs.addAttribute(NAME_QNAME.getNamespaceURI(), NAME_LOCALNAME, toPrefixString(NAME_QNAME), null, toPrefixString(property));
attrs.addAttribute(TYPE_QNAME.getNamespaceURI(), TYPE_LOCALNAME, toPrefixString(TYPE_QNAME), null, datatype);
// emit property element
contentHandler.startElement(PROPERTY_QNAME.getNamespaceURI(), PROPERTY_LOCALNAME, toPrefixString(PROPERTY_QNAME), attrs);
}
catch (SAXException e)
{
throw new ExporterException("Failed to process start property event - nodeRef " + nodeRef + "; property " + toPrefixString(property), e);
}
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endProperty(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/
public void endProperty(NodeRef nodeRef, QName property)
{
try
{
// emit property element
contentHandler.endElement(PROPERTY_QNAME.getNamespaceURI(), PROPERTY_LOCALNAME, toPrefixString(PROPERTY_QNAME));
}
catch (SAXException e)
{
throw new ExporterException("Failed to process end property event - nodeRef " + nodeRef + "; property " + toPrefixString(property), e);
}
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startValueCollection(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/
public void startValueCollection(NodeRef nodeRef, QName property)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endValueCollection(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/
public void endValueCollection(NodeRef nodeRef, QName property)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#value(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, java.io.Serializable)
*/
public void value(NodeRef nodeRef, QName property, Object value, int index)
{
try
{
// emit value element
contentHandler.startElement(VALUE_QNAME.getNamespaceURI(), VALUE_LOCALNAME, toPrefixString(VALUE_QNAME), EMPTY_ATTRIBUTES);
String strValue = session.getTypeConverter().convert(String.class, value);
contentHandler.characters(strValue.toCharArray(), 0, strValue.length());
contentHandler.endElement(VALUE_QNAME.getNamespaceURI(), VALUE_LOCALNAME, toPrefixString(VALUE_QNAME));
}
catch (RepositoryException e)
{
throw new ExporterException("Failed to process value event - nodeRef " + nodeRef + "; property " + toPrefixString(property) + "; value " + value, e);
}
catch (SAXException e)
{
throw new ExporterException("Failed to process value event - nodeRef " + nodeRef + "; property " + toPrefixString(property) + "; value " + value, e);
}
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#content(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName, java.io.InputStream)
*/
public void content(NodeRef nodeRef, QName property, InputStream content, ContentData contentData, int index)
{
try
{
contentHandler.startElement(VALUE_QNAME.getNamespaceURI(), VALUE_LOCALNAME, toPrefixString(VALUE_QNAME), EMPTY_ATTRIBUTES);
if (content != null)
{
// emit base64 encoded content
InputStream base64content = new Base64.InputStream(content, Base64.ENCODE | Base64.DONT_BREAK_LINES);
byte[] buffer = new byte[9 * 1024];
int read;
while ((read = base64content.read(buffer, 0, buffer.length)) > 0)
{
String characters = new String(buffer, 0, read);
contentHandler.characters(characters.toCharArray(), 0, characters.length());
}
}
contentHandler.endElement(VALUE_QNAME.getNamespaceURI(), VALUE_LOCALNAME, toPrefixString(VALUE_QNAME));
}
catch (SAXException e)
{
throw new ExporterException("Failed to process content event - nodeRef " + nodeRef + "; property " + toPrefixString(property));
}
catch (IOException e)
{
throw new ExporterException("Failed to process content event - nodeRef " + nodeRef + "; property " + toPrefixString(property));
}
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startAssoc(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/
public void startAssoc(NodeRef nodeRef, QName assoc)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endAssoc(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/
public void endAssoc(NodeRef nodeRef, QName assoc)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startAssocs(org.alfresco.service.cmr.repository.NodeRef)
*/
public void startAssocs(NodeRef nodeRef)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endAssocs(org.alfresco.service.cmr.repository.NodeRef)
*/
public void endAssocs(NodeRef nodeRef)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#startReference(org.alfresco.service.cmr.repository.NodeRef, org.alfresco.service.namespace.QName)
*/
public void startReference(NodeRef nodeRef, QName childName)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#endReference(org.alfresco.service.cmr.repository.NodeRef)
*/
public void endReference(NodeRef nodeRef)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#warning(java.lang.String)
*/
public void warning(String warning)
{
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.view.Exporter#end()
*/
public void end()
{
try
{
contentHandler.endDocument();
}
catch (SAXException e)
{
throw new ExporterException("Failed to process end export event", e);
}
}
/**
* Get the prefix for the specified URI
* @param uri the URI
* @return the prefix (or null, if one is not registered)
*/
private String toPrefixString(QName qname)
{
return qname.toPrefixString(session.getNamespaceResolver());
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.importer;
import javax.jcr.ImportUUIDBehavior;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import org.alfresco.jcr.test.BaseJCRTest;
import org.springframework.core.io.ClassPathResource;
public class ImportTest extends BaseJCRTest
{
protected Session superuserSession;
@Override
protected void setUp() throws Exception
{
super.setUp();
SimpleCredentials superuser = new SimpleCredentials("superuser", "".toCharArray());
superuserSession = repository.login(superuser, getWorkspace());
}
@Override
protected void tearDown() throws Exception
{
super.tearDown();
superuserSession.logout();
}
public void testSysImport()
throws Exception
{
ClassPathResource sysview = new ClassPathResource("org/alfresco/jcr/test/sysview.xml");
superuserSession.importXML("/testroot", sysview.getInputStream(), ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
}
public void testDocImport()
throws Exception
{
ClassPathResource sysview = new ClassPathResource("org/alfresco/jcr/test/docview.xml");
superuserSession.importXML("/testroot", sysview.getInputStream(), ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW);
}
public void testThrowCollision()
throws Exception
{
ClassPathResource sysview = new ClassPathResource("org/alfresco/jcr/test/docview.xml");
superuserSession.importXML("/testroot", sysview.getInputStream(), ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING);
try
{
superuserSession.importXML("/testroot", sysview.getInputStream(), ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW);
fail("Failed to catch UUID collision");
}
catch(RepositoryException e)
{
}
}
}

View File

@@ -0,0 +1,396 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.importer;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.List;
import java.util.Stack;
import javax.jcr.InvalidSerializedDataException;
import org.alfresco.jcr.dictionary.JCRNamespace;
import org.alfresco.jcr.item.property.JCRMixinTypesProperty;
import org.alfresco.jcr.item.property.JCRPrimaryTypeProperty;
import org.alfresco.jcr.item.property.JCRUUIDProperty;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.repo.importer.ImportContentHandler;
import org.alfresco.repo.importer.Importer;
import org.alfresco.repo.importer.view.ElementContext;
import org.alfresco.repo.importer.view.NodeContext;
import org.alfresco.repo.importer.view.ParentContext;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.InvalidTypeException;
import org.alfresco.service.cmr.dictionary.PropertyDefinition;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.view.ImporterException;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Base64;
import org.alfresco.util.ISO9075;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
/**
* Alfresco implementation of a Doc View Import Content Handler
*
* @author David Caruana
*/
public class JCRDocXMLHandler implements ImportContentHandler
{
private Importer importer;
private SessionImpl session;
private DictionaryService dictionaryService;
private NamespacePrefixResolver importResolver;
private Stack<ElementContext> contextStack = new Stack<ElementContext>();
/**
* Construct
*
* @param session JCR Session
* @param importResolver Namespace Resolver for the Import
*/
public JCRDocXMLHandler(SessionImpl session, NamespacePrefixResolver importResolver)
{
this.session = session;
this.importResolver = importResolver;
this.dictionaryService = session.getRepositoryImpl().getServiceRegistry().getDictionaryService();
}
/*
* (non-Javadoc)
* @see org.alfresco.repo.importer.ImportContentHandler#setImporter(org.alfresco.repo.importer.Importer)
*/
public void setImporter(Importer importer)
{
this.importer = importer;
}
/*
* (non-Javadoc)
* @see org.alfresco.repo.importer.ImportContentHandler#importStream(java.lang.String)
*/
public InputStream importStream(String content)
{
File contentFile = new File(content);
try
{
FileInputStream contentStream = new FileInputStream(contentFile);
return new Base64.InputStream(contentStream, Base64.DECODE | Base64.DONT_BREAK_LINES);
}
catch (FileNotFoundException e)
{
throw new ImporterException("Failed to retrieve import input stream on temporary content file " + content);
}
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
*/
public void setDocumentLocator(Locator locator)
{
// NOOP
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#startDocument()
*/
public void startDocument() throws SAXException
{
// NOOP
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#endDocument()
*/
public void endDocument() throws SAXException
{
// NOOP
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String)
*/
public void startPrefixMapping(String prefix, String uri) throws SAXException
{
// NOOP
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
*/
public void endPrefixMapping(String prefix) throws SAXException
{
// NOOP
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
*/
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException
{
try
{
// construct qname for element
QName elementName = decodeQName(QName.createQName(qName, importResolver));
// setup parent context
ParentContext parentContext = null;
if (contextStack.empty())
{
// create root parent context
parentContext = new ParentContext(elementName, dictionaryService, importer);
}
else
{
// create parent context
NodeContext parentNode = (NodeContext)contextStack.peek();
parentContext = new ParentContext(elementName, parentNode);
}
// create node context
NodeContext node = new NodeContext(elementName, parentContext, null);
node.setChildName(elementName.toPrefixString(importResolver));
contextStack.push(node);
// process node properties
for (int i = 0; i < atts.getLength(); i++)
{
QName propName = decodeQName(QName.createQName(atts.getURI(i), atts.getLocalName(i)));
String value = atts.getValue(i);
//
// process "well-known" properties
//
if (propName.equals(JCRPrimaryTypeProperty.PROPERTY_NAME))
{
// primary type
QName primaryTypeQName = QName.createQName(value, importResolver);
TypeDefinition typeDef = dictionaryService.getType(primaryTypeQName);
if (typeDef == null)
{
throw new InvalidTypeException(primaryTypeQName);
}
node.setTypeDefinition(typeDef);
}
else if (propName.equals(JCRMixinTypesProperty.PROPERTY_NAME))
{
// aspects
String[] aspects = value.split(" ");
for (String aspect : aspects)
{
// ignore JCR specific aspects
QName aspectQName = QName.createQName(aspect, importResolver);
if (!(JCRNamespace.JCR_URI.equals(aspectQName.getNamespaceURI()) ||
JCRNamespace.MIX_URI.equals(aspectQName.getNamespaceURI())))
{
AspectDefinition aspectDef = dictionaryService.getAspect(aspectQName);
if (aspectDef == null)
{
throw new InvalidTypeException(aspectQName);
}
node.addAspect(aspectDef);
}
}
}
else if (JCRUUIDProperty.PROPERTY_NAME.equals(propName))
{
node.setUUID(value);
}
//
// Note: ignore JCR specific properties
//
else if (JCRNamespace.JCR_URI.equals(propName.getNamespaceURI()))
{
}
//
// process all other properties
//
else
{
// determine type of property
PropertyDefinition propDef = dictionaryService.getProperty(propName);
if (propDef == null)
{
throw new ImporterException("Property " + propName + " is not known to the repository data dictionary");
}
DataTypeDefinition dataTypeDef = propDef.getDataType();
// extract values from node xml attribute
String[] propValues = null;
PropertyContext propertyContext = new PropertyContext(elementName, node, propName, dataTypeDef.getName());
if (dataTypeDef.getName().equals(DataTypeDefinition.CONTENT))
{
// Note: we only support single valued content properties
propValues = new String[] { value };
}
else
{
// attempt to split multi-value properties
propValues = value.split(" ");
}
// extract values appropriately
for (String propValue : propValues)
{
propertyContext.startValue();
propertyContext.appendCharacters(propValue.toCharArray(), 0, propValue.length());
propertyContext.endValue();
}
// add each value to the node
if (propertyContext.isMultiValue())
{
node.addPropertyCollection(propName);
}
List<StringBuffer> nodeValues = propertyContext.getValues();
for (StringBuffer nodeValue : nodeValues)
{
// first, cast value to appropriate type (using JCR converters)
Serializable objVal = (Serializable)session.getTypeConverter().convert(dataTypeDef, nodeValue.toString());
String strValue = DefaultTypeConverter.INSTANCE.convert(String.class, objVal);
node.addProperty(propName, strValue);
}
}
}
// import node
NodeRef nodeRef = node.getImporter().importNode(node);
node.setNodeRef(nodeRef);
}
catch(Exception e)
{
throw new SAXException("Failed to process element " + qName, e);
}
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
*/
public void endElement(String uri, String localName, String qName) throws SAXException
{
try
{
// ensure context matches parse
ElementContext context = (ElementContext)contextStack.pop();
QName elementName = QName.createQName(qName, importResolver);
if (!context.getElementName().equals(elementName))
{
throw new InvalidSerializedDataException("Expected element " + context.getElementName() + " but was " + elementName);
}
// signal end of node
NodeContext nodeContext = (NodeContext)context;
nodeContext.getImporter().childrenImported(nodeContext.getNodeRef());
}
catch(Exception e)
{
throw new SAXException("Failed to process element " + qName, e);
}
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#characters(char[], int, int)
*/
public void characters(char[] ch, int start, int length) throws SAXException
{
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
*/
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
{
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String, java.lang.String)
*/
public void processingInstruction(String target, String data) throws SAXException
{
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
*/
public void skippedEntity(String name) throws SAXException
{
}
/*
* (non-Javadoc)
* @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
*/
public void warning(SAXParseException exception) throws SAXException
{
}
/*
* (non-Javadoc)
* @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
*/
public void error(SAXParseException exception) throws SAXException
{
}
/*
* (non-Javadoc)
* @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
*/
public void fatalError(SAXParseException exception) throws SAXException
{
}
/**
* Decode QName
*
* @param name name to decode
* @return the decoded name
*/
private QName decodeQName(QName name)
{
return QName.createQName(name.getNamespaceURI(), ISO9075.decode(name.getLocalName()));
}
}

View File

@@ -0,0 +1,359 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.importer;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.alfresco.jcr.dictionary.JCRNamespace;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.repo.importer.ImportContentHandler;
import org.alfresco.repo.importer.Importer;
import org.alfresco.service.cmr.view.ImporterException;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.NamespaceService;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.helpers.NamespaceSupport;
/**
* Import Handler that is sensitive to Document and System View XML schemas.
*
* @author David Caruana
*/
public class JCRImportHandler implements ImportContentHandler
{
private Importer importer;
private SessionImpl session;
private NamespaceContext namespaceContext;
private ImportContentHandler targetHandler = null;
/**
* Construct
*
* @param session
*/
public JCRImportHandler(SessionImpl session)
{
this.session = session;
this.namespaceContext = new NamespaceContext();
}
/*
* (non-Javadoc)
* @see org.alfresco.repo.importer.ImportContentHandler#setImporter(org.alfresco.repo.importer.Importer)
*/
public void setImporter(Importer importer)
{
this.importer = importer;
}
/*
* (non-Javadoc)
* @see org.alfresco.repo.importer.ImportContentHandler#importStream(java.lang.String)
*/
public InputStream importStream(String content)
{
return targetHandler.importStream(content);
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
*/
public void setDocumentLocator(Locator locator)
{
// NOOP
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#startDocument()
*/
public void startDocument() throws SAXException
{
namespaceContext.reset();
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#endDocument()
*/
public void endDocument() throws SAXException
{
targetHandler.endDocument();
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String)
*/
public void startPrefixMapping(String prefix, String uri) throws SAXException
{
// ensure uri has been registered
NamespacePrefixResolver resolver = session.getNamespaceResolver();
Collection<String> uris = resolver.getURIs();
if (!uris.contains(uri))
{
throw new ImporterException("Namespace URI " + uri + " has not been registered with the repository");
}
// register prefix within this namespace context
namespaceContext.registerPrefix(prefix, uri);
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
*/
public void endPrefixMapping(String prefix) throws SAXException
{
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
*/
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException
{
namespaceContext.pushContext();
// determine content handler based on first element of document
if (targetHandler == null)
{
if (JCRNamespace.SV_URI.equals(uri))
{
targetHandler = new JCRSystemXMLHandler(session, namespaceContext);
}
else
{
targetHandler = new JCRDocXMLHandler(session, namespaceContext);
}
targetHandler.setImporter(importer);
targetHandler.startDocument();
}
targetHandler.startElement(uri, localName, qName, atts);
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
*/
public void endElement(String uri, String localName, String qName) throws SAXException
{
targetHandler.endElement(uri, localName, qName);
namespaceContext.popContext();
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#characters(char[], int, int)
*/
public void characters(char[] ch, int start, int length) throws SAXException
{
targetHandler.characters(ch, start, length);
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
*/
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
{
targetHandler.characters(ch, start, length);
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String, java.lang.String)
*/
public void processingInstruction(String target, String data) throws SAXException
{
targetHandler.processingInstruction(target, data);
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
*/
public void skippedEntity(String name) throws SAXException
{
targetHandler.skippedEntity(name);
}
/*
* (non-Javadoc)
* @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
*/
public void warning(SAXParseException exception) throws SAXException
{
targetHandler.warning(exception);
}
/*
* (non-Javadoc)
* @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
*/
public void error(SAXParseException exception) throws SAXException
{
targetHandler.error(exception);
}
/*
* (non-Javadoc)
* @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
*/
public void fatalError(SAXParseException exception) throws SAXException
{
targetHandler.fatalError(exception);
}
/**
* Namespace Context
*
* Implementation supported by NamespaceSupport which itself does not
* handle empty uri registration.
*/
private static class NamespaceContext implements NamespacePrefixResolver
{
private final NamespaceSupport context;
private static final String REMAPPED_DEFAULT_URI = " ";
/**
* Construct
*/
private NamespaceContext()
{
context = new NamespaceSupport();
}
/**
* Clear namespace declarations
*/
private void reset()
{
context.reset();
}
/**
* Push a new Namespace Context
*/
private void pushContext()
{
context.pushContext();
}
/**
* Pop a Namespace Context
*/
private void popContext()
{
context.popContext();
}
/**
* Register a namespace prefix
*
* @param prefix
* @param uri
* @return true => legal prefix; false => illegal prefix
*/
private boolean registerPrefix(String prefix, String uri)
{
if (NamespaceService.DEFAULT_URI.equals(uri))
{
uri = REMAPPED_DEFAULT_URI;
}
return context.declarePrefix(prefix, uri);
}
/*
* (non-Javadoc)
* @see org.alfresco.service.namespace.NamespacePrefixResolver#getNamespaceURI(java.lang.String)
*/
public String getNamespaceURI(String prefix) throws org.alfresco.service.namespace.NamespaceException
{
String uri = context.getURI(prefix);
if (uri == null)
{
throw new org.alfresco.service.namespace.NamespaceException("Namespace prefix " + prefix + " not registered.");
}
if (REMAPPED_DEFAULT_URI.equals(uri))
{
return NamespaceService.DEFAULT_URI;
}
return uri;
}
/*
* (non-Javadoc)
* @see org.alfresco.service.namespace.NamespacePrefixResolver#getPrefixes(java.lang.String)
*/
public Collection<String> getPrefixes(String namespaceURI) throws org.alfresco.service.namespace.NamespaceException
{
if (NamespaceService.DEFAULT_URI.equals(namespaceURI))
{
namespaceURI = REMAPPED_DEFAULT_URI;
}
String prefix = context.getPrefix(namespaceURI);
if (prefix == null)
{
if (namespaceURI.equals(context.getURI(NamespaceService.DEFAULT_PREFIX)))
{
prefix = NamespaceService.DEFAULT_PREFIX;
}
else
{
throw new org.alfresco.service.namespace.NamespaceException("Namespace URI " + namespaceURI + " not registered.");
}
}
List<String> prefixes = new ArrayList<String>(1);
prefixes.add(prefix);
return prefixes;
}
/*
* (non-Javadoc)
* @see org.alfresco.service.namespace.NamespacePrefixResolver#getPrefixes()
*/
public Collection<String> getPrefixes()
{
// NOTE: not required in this context
return null;
}
/*
* (non-Javadoc)
* @see org.alfresco.service.namespace.NamespacePrefixResolver#getURIs()
*/
public Collection<String> getURIs()
{
// NOTE: not required in this context
return null;
}
}
}

View File

@@ -0,0 +1,552 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.importer;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.io.Serializable;
import java.util.List;
import java.util.Stack;
import javax.jcr.InvalidSerializedDataException;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import org.alfresco.jcr.dictionary.DataTypeMap;
import org.alfresco.jcr.dictionary.JCRNamespace;
import org.alfresco.jcr.exporter.JCRSystemXMLExporter;
import org.alfresco.jcr.item.property.JCRMixinTypesProperty;
import org.alfresco.jcr.item.property.JCRPrimaryTypeProperty;
import org.alfresco.jcr.item.property.JCRUUIDProperty;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.repo.importer.ImportContentHandler;
import org.alfresco.repo.importer.Importer;
import org.alfresco.repo.importer.view.ElementContext;
import org.alfresco.repo.importer.view.NodeContext;
import org.alfresco.repo.importer.view.ParentContext;
import org.alfresco.service.cmr.dictionary.AspectDefinition;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.InvalidTypeException;
import org.alfresco.service.cmr.dictionary.TypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.view.ImporterException;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.Base64;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
/**
* Alfresco implementation of a System View Import Content Handler
*
* @author David Caruana
*/
public class JCRSystemXMLHandler implements ImportContentHandler
{
private Importer importer;
private SessionImpl session;
private NamespacePrefixResolver importResolver;
private Stack<ElementContext> contextStack = new Stack<ElementContext>();
/**
* Construct
*
* @param session JCR Session
* @param importResolver Namespace Resolver for the Import
*/
public JCRSystemXMLHandler(SessionImpl session, NamespacePrefixResolver importResolver)
{
this.session = session;
this.importResolver = importResolver;
}
/*
* (non-Javadoc)
* @see org.alfresco.repo.importer.ImportContentHandler#setImporter(org.alfresco.repo.importer.Importer)
*/
public void setImporter(Importer importer)
{
this.importer = importer;
}
/*
* (non-Javadoc)
* @see org.alfresco.repo.importer.ImportContentHandler#importStream(java.lang.String)
*/
public InputStream importStream(String content)
{
File contentFile = new File(content);
try
{
FileInputStream contentStream = new FileInputStream(contentFile);
return new Base64.InputStream(contentStream, Base64.DECODE | Base64.DONT_BREAK_LINES);
}
catch (FileNotFoundException e)
{
throw new ImporterException("Failed to retrieve import input stream on temporary content file " + content);
}
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#setDocumentLocator(org.xml.sax.Locator)
*/
public void setDocumentLocator(Locator locator)
{
// NOOP
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#startDocument()
*/
public void startDocument() throws SAXException
{
// NOOP
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#endDocument()
*/
public void endDocument() throws SAXException
{
// NOOP
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#startPrefixMapping(java.lang.String, java.lang.String)
*/
public void startPrefixMapping(String prefix, String uri) throws SAXException
{
// NOOP
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#endPrefixMapping(java.lang.String)
*/
public void endPrefixMapping(String prefix) throws SAXException
{
// NOOP
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#startElement(java.lang.String, java.lang.String, java.lang.String, org.xml.sax.Attributes)
*/
public void startElement(String uri, String localName, String qName, Attributes atts) throws SAXException
{
try
{
// construct qname for element
QName elementName = QName.createQName(qName, importResolver);
if (JCRSystemXMLExporter.NODE_QNAME.equals(elementName))
{
processStartNode(elementName, atts);
}
else if (JCRSystemXMLExporter.PROPERTY_QNAME.equals(elementName))
{
processStartProperty(elementName, atts);
}
else if (JCRSystemXMLExporter.VALUE_QNAME.equals(elementName))
{
processStartValue(elementName, atts);
}
}
catch(Exception e)
{
throw new SAXException("Failed to process element " + qName, e);
}
}
/**
* Process start of Node Element
*
* @param elementName
* @param atts
* @throws InvalidSerializedDataException
*/
private void processStartNode(QName elementName, Attributes atts)
throws InvalidSerializedDataException
{
ParentContext parentContext = null;
if (contextStack.empty())
{
// create root parent context
parentContext = new ParentContext(elementName, session.getRepositoryImpl().getServiceRegistry().getDictionaryService(), importer);
}
else
{
NodeContext parentNode = (NodeContext)contextStack.peek();
// if we haven't yet imported the node before its children, do so now
if (parentNode.getNodeRef() == null)
{
NodeRef nodeRef = importer.importNode(parentNode);
parentNode.setNodeRef(nodeRef);
}
// create parent context
parentContext = new ParentContext(elementName, parentNode);
}
// create node context
// NOTE: we don't yet know its type (we have to wait for a property)
NodeContext nodeContext = new NodeContext(elementName, parentContext, null);
// establish node child name
String name = atts.getValue(JCRSystemXMLExporter.NAME_QNAME.toPrefixString(importResolver));
if (name == null)
{
throw new InvalidSerializedDataException("Mandatory sv:name attribute of element sv:node not present.");
}
nodeContext.setChildName(name);
// record new node
contextStack.push(nodeContext);
}
/**
* Process start of Property element
*
* @param elementName
* @param atts
* @throws InvalidSerializedDataException
*/
private void processStartProperty(QName elementName, Attributes atts)
throws InvalidSerializedDataException
{
// establish correct context
ElementContext context = contextStack.peek();
if (!(context instanceof NodeContext))
{
throw new InvalidSerializedDataException("Element " + elementName + " not expected.");
}
NodeContext parentNode = (NodeContext)context;
// establish property name
String name = atts.getValue(JCRSystemXMLExporter.NAME_QNAME.toPrefixString(importResolver));
if (name == null)
{
throw new InvalidSerializedDataException("Mandatory sv:name attribute of element sv:node not present.");
}
QName propertyName = QName.createQName(name, importResolver);
// establish property type and validate property type
QName dataType = null;
String type = atts.getValue(JCRSystemXMLExporter.TYPE_QNAME.toPrefixString(importResolver));
if (type == null)
{
throw new InvalidSerializedDataException("Mandatory sv:type attribute of element sv:node not present.");
}
try
{
dataType = DataTypeMap.convertPropertyTypeToDataType(PropertyType.valueFromName(type));
}
catch(IllegalArgumentException e)
{
throw new ImporterException("Type " + type + " is not known for property " + name);
}
// construct property context
PropertyContext propertyContext = new PropertyContext(elementName, parentNode, propertyName, dataType);
contextStack.push(propertyContext);
}
/**
* Process start of Value element
*
* @param elementName
* @param atts
* @throws InvalidSerializedDataException
*/
private void processStartValue(QName elementName, Attributes atts)
throws InvalidSerializedDataException
{
// establish correct context
ElementContext context = contextStack.peek();
if (!(context instanceof PropertyContext))
{
throw new InvalidSerializedDataException("Element " + elementName + " not expected.");
}
PropertyContext property = (PropertyContext)context;
property.startValue();
ValueContext value = new ValueContext(elementName, property);
contextStack.push(value);
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#endElement(java.lang.String, java.lang.String, java.lang.String)
*/
public void endElement(String uri, String localName, String qName) throws SAXException
{
try
{
// ensure context matches parse
ElementContext context = (ElementContext)contextStack.peek();
QName elementName = QName.createQName(qName, importResolver);
if (!context.getElementName().equals(elementName))
{
throw new InvalidSerializedDataException("Expected element " + context.getElementName() + " but was " + elementName);
}
if (JCRSystemXMLExporter.NODE_QNAME.equals(elementName))
{
processEndNode((NodeContext)context);
}
else if (JCRSystemXMLExporter.PROPERTY_QNAME.equals(elementName))
{
processEndProperty((PropertyContext)context);
}
else if (JCRSystemXMLExporter.VALUE_QNAME.equals(elementName))
{
processEndValue((ValueContext)context);
}
// cleanup
contextStack.pop();
}
catch(Exception e)
{
throw new SAXException("Failed to process element " + qName, e);
}
}
/**
* Process end of Node element
*
* @param node
*/
private void processEndNode(NodeContext node)
{
// import node, if not already imported (this will be the case when no child nodes exist)
NodeRef nodeRef = node.getNodeRef();
if (nodeRef == null)
{
nodeRef = node.getImporter().importNode(node);
node.setNodeRef(nodeRef);
}
// signal end of node
node.getImporter().childrenImported(nodeRef);
}
/**
* Process end of Property element
*
* @param context
* @throws InvalidSerializedDataException
* @throws RepositoryException
*/
private void processEndProperty(PropertyContext context)
throws InvalidSerializedDataException, RepositoryException
{
QName propertyName = context.getName();
// ensure a value has been provided
if (context.isNull())
{
throw new InvalidSerializedDataException("Property " + propertyName + " must have a value");
}
//
// process known properties
//
if (JCRPrimaryTypeProperty.PROPERTY_NAME.equals(propertyName))
{
// apply type definition
if (!context.isNull())
{
QName typeQName = QName.createQName(context.getValues().get(0).toString(), importResolver);
TypeDefinition typeDef = context.getDictionaryService().getType(typeQName);
if (typeDef == null)
{
throw new InvalidTypeException(typeQName);
}
// update node context
context.getNode().setTypeDefinition(typeDef);
}
}
else if (JCRMixinTypesProperty.PROPERTY_NAME.equals(propertyName))
{
// apply aspect definitions
List<StringBuffer> values = context.getValues();
for (StringBuffer value : values)
{
QName aspectQName = QName.createQName(value.toString(), importResolver);
// ignore JCR specific aspects
if (!(JCRNamespace.JCR_URI.equals(aspectQName.getNamespaceURI()) ||
JCRNamespace.MIX_URI.equals(aspectQName.getNamespaceURI())))
{
AspectDefinition aspectDef = context.getDictionaryService().getAspect(aspectQName);
if (aspectDef == null)
{
throw new InvalidTypeException(aspectQName);
}
context.getNode().addAspect(aspectDef);
}
}
}
else if (JCRUUIDProperty.PROPERTY_NAME.equals(propertyName))
{
StringBuffer value = context.getValues().get(0);
context.getNode().setUUID(value.toString());
}
//
// Note: ignore all other JCR specific properties
//
else if (JCRNamespace.JCR_URI.equals(propertyName.getNamespaceURI()))
{
}
//
// process all other properties
//
else
{
// apply the property values to the node
NodeContext node = context.getNode();
if (node.getTypeDefinition() == null)
{
throw new InvalidSerializedDataException("Node jcr:primaryType property has not been specified.");
}
// determine data type of value
QName dataType = context.getType();
DataTypeDefinition dataTypeDef = context.getDictionaryService().getDataType(dataType);
if (dataTypeDef == null)
{
throw new InvalidTypeException(dataType);
}
node.addDatatype(propertyName, dataTypeDef);
// determine if multi-value property
if (context.isMultiValue())
{
node.addPropertyCollection(propertyName);
}
// add each value to the node
List<StringBuffer> values = context.getValues();
for (StringBuffer value : values)
{
// first, cast value to appropriate type (using JCR converters)
Serializable objVal = (Serializable)session.getTypeConverter().convert(dataTypeDef, value.toString());
String strValue = DefaultTypeConverter.INSTANCE.convert(String.class, objVal);
node.addProperty(propertyName, strValue);
}
}
}
/**
* Process end of value element
*
* @param context
*/
private void processEndValue(ValueContext context)
{
PropertyContext property = context.getProperty();
property.endValue();
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#characters(char[], int, int)
*/
public void characters(char[] ch, int start, int length) throws SAXException
{
ElementContext context = (ElementContext)contextStack.peek();
if (context instanceof ValueContext)
{
PropertyContext property = ((ValueContext)context).getProperty();
property.appendCharacters(ch, start, length);
}
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#ignorableWhitespace(char[], int, int)
*/
public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException
{
ElementContext context = (ElementContext)contextStack.peek();
if (context instanceof ValueContext)
{
PropertyContext property = ((ValueContext)context).getProperty();
property.appendCharacters(ch, start, length);
}
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#processingInstruction(java.lang.String, java.lang.String)
*/
public void processingInstruction(String target, String data) throws SAXException
{
}
/*
* (non-Javadoc)
* @see org.xml.sax.ContentHandler#skippedEntity(java.lang.String)
*/
public void skippedEntity(String name) throws SAXException
{
}
/*
* (non-Javadoc)
* @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException)
*/
public void warning(SAXParseException exception) throws SAXException
{
}
/*
* (non-Javadoc)
* @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException)
*/
public void error(SAXParseException exception) throws SAXException
{
}
/*
* (non-Javadoc)
* @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException)
*/
public void fatalError(SAXParseException exception) throws SAXException
{
}
}

View File

@@ -0,0 +1,210 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.importer;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.repo.importer.view.ElementContext;
import org.alfresco.repo.importer.view.NodeContext;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.repository.ContentData;
import org.alfresco.service.cmr.view.ImporterException;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.ISO9075;
import org.alfresco.util.TempFileProvider;
/**
* Maintains state about currently imported Property
*
* @author David Caruana
*
*/
public class PropertyContext extends ElementContext
{
private NodeContext parentContext;
private QName propertyName;
private QName propertyType;
private List<StringBuffer> values = new ArrayList<StringBuffer>();
private Map<QName, FileWriter> contentWriters = new HashMap<QName, FileWriter>();
/**
* Construct
*
* @param elementName
* @param parentContext
* @param propertyName
* @param propertyType
*/
public PropertyContext(QName elementName, NodeContext parentContext, QName propertyName, QName propertyType)
{
super(elementName, parentContext.getDictionaryService(), parentContext.getImporter());
this.parentContext = parentContext;
this.propertyName = propertyName;
this.propertyType = propertyType;
}
/**
* Get node containing property
*
* @return node
*/
public NodeContext getNode()
{
return parentContext;
}
/**
* Get property name
*
* @return property name
*/
public QName getName()
{
return propertyName;
}
/**
* Get property type
*
* @return property type
*/
public QName getType()
{
return propertyType;
}
/**
* Is property multi-valued?
*
* @return true => multi-valued; false => single value
*/
public boolean isMultiValue()
{
return values.size() > 1;
}
/**
* Is null property value
*
* @return true => value has not been provided
*/
public boolean isNull()
{
return values.size() == 0;
}
/**
* Get property values
*
* @return values
*/
public List<StringBuffer> getValues()
{
return values;
}
/**
* Start a new property value
*/
public void startValue()
{
StringBuffer buffer = new StringBuffer(128);
if (propertyType.equals(DataTypeDefinition.CONTENT))
{
// create temporary file to hold content
File tempFile = TempFileProvider.createTempFile("import", ".tmp");
try
{
FileWriter tempWriter = new FileWriter(tempFile);
contentWriters.put(propertyName, tempWriter);
ContentData contentData = new ContentData(tempFile.getAbsolutePath(), MimetypeMap.MIMETYPE_BINARY, 0, tempWriter.getEncoding());
buffer.append(contentData.toString());
}
catch(IOException e)
{
throw new ImporterException("Failed to create temporary content holder for property " + propertyName, e);
}
}
values.add(buffer);
}
/**
* End a property value
*/
public void endValue()
{
if (propertyType.equals(DataTypeDefinition.CONTENT))
{
// close content writer
FileWriter tempWriter = contentWriters.get(propertyName);
try
{
tempWriter.close();
contentWriters.remove(propertyName);
}
catch(IOException e)
{
throw new ImporterException("Failed to create temporary content holder for property " + propertyName, e);
}
}
else
{
// decode value
StringBuffer buffer = values.get(values.size() -1);
values.set(values.size() -1, new StringBuffer(ISO9075.decode(buffer.toString())));
}
}
/**
* Append property value characters
*
* @param ch
* @param start
* @param length
*/
public void appendCharacters(char[] ch, int start, int length)
{
if (propertyType.equals(DataTypeDefinition.CONTENT))
{
FileWriter tempWriter = contentWriters.get(propertyName);
try
{
tempWriter.write(ch, start, length);
}
catch(IOException e)
{
throw new ImporterException("Failed to write temporary content for property " + propertyName, e);
}
}
else
{
StringBuffer buffer = values.get(values.size() -1);
buffer.append(ch, start, length);
}
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.importer;
import org.alfresco.repo.importer.view.ElementContext;
import org.alfresco.service.namespace.QName;
/**
* Maintains state about currently imported value
*
* @author David Caruana
*/
public class ValueContext extends ElementContext
{
private PropertyContext property;
/**
* Construct
*
* @param elementName
* @param property
*/
public ValueContext(QName elementName, PropertyContext property)
{
super(elementName, property.getDictionaryService(), property.getImporter());
this.property = property;
}
/**
* Get property
*
* @return property holding value
*/
public PropertyContext getProperty()
{
return property;
}
}

View File

@@ -0,0 +1,80 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.item;
import java.util.List;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.jcr.util.AbstractRangeIterator;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
/**
* Alfresco implementation of a Node Iterator
*
* @author David Caruana
*/
public class ChildAssocNodeIteratorImpl extends AbstractRangeIterator
implements NodeIterator
{
private SessionImpl sessionImpl;
private List<ChildAssociationRef> childAssocs;
/**
* Construct
*
* @param context session context
* @param nodes node list
*/
public ChildAssocNodeIteratorImpl(SessionImpl sessionImpl, List<ChildAssociationRef> childAssocs)
{
this.sessionImpl = sessionImpl;
this.childAssocs = childAssocs;
}
/* (non-Javadoc)
* @see javax.jcr.NodeIterator#nextNode()
*/
public Node nextNode()
{
long position = skip();
ChildAssociationRef childAssocRef = childAssocs.get((int)position);
NodeImpl nodeImpl = new NodeImpl(sessionImpl, childAssocRef.getChildRef());
return nodeImpl.getProxy();
}
/* (non-Javadoc)
* @see javax.jcr.RangeIterator#getSize()
*/
public long getSize()
{
return childAssocs.size();
}
/* (non-Javadoc)
* @see java.util.Iterator#next()
*/
public Object next()
{
return nextNode();
}
}

View File

@@ -0,0 +1,114 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.item;
import javax.jcr.AccessDeniedException;
import javax.jcr.InvalidItemStateException;
import javax.jcr.Item;
import javax.jcr.ItemExistsException;
import javax.jcr.ReferentialIntegrityException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.lock.LockException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.version.VersionException;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
/**
* Alfresco Implementation of an Item
*
* @author David Caruana
*/
public abstract class ItemImpl implements Item
{
protected SessionImpl session;
/**
* Construct
*
* @param session
*/
public ItemImpl(SessionImpl session)
{
this.session = session;
}
/**
* Get the Session implementation
*
* @return session implementation
*/
public SessionImpl getSessionImpl()
{
return session;
}
/**
* Get the Item Proxy
*
* @return the proxy
*/
public abstract Item getProxy();
/* (non-Javadoc)
* @see javax.jcr.Item#getSession()
*/
public Session getSession() throws RepositoryException
{
return session.getProxy();
}
/* (non-Javadoc)
* @see javax.jcr.Item#isNew()
*/
public boolean isNew()
{
return false;
}
/* (non-Javadoc)
* @see javax.jcr.Item#isModified()
*/
public boolean isModified()
{
return false;
}
/* (non-Javadoc)
* @see javax.jcr.Item#save()
*/
public void save() throws AccessDeniedException, ItemExistsException, ConstraintViolationException, InvalidItemStateException, ReferentialIntegrityException, VersionException, LockException, NoSuchNodeTypeException, RepositoryException
{
AlfrescoTransactionSupport.flush();
}
/* (non-Javadoc)
* @see javax.jcr.Item#refresh(boolean)
*/
public void refresh(boolean keepChanges) throws InvalidItemStateException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
}

View File

@@ -0,0 +1,145 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.item;
import java.util.List;
import javax.jcr.PathNotFoundException;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.search.SearchService;
/**
* Responsible for finding JCR Items (Nodes, Properties) from Alfresco equivalents
*
* @author David Caruana
*
*/
public class ItemResolver
{
/**
* Create an Item from a JCR Path
*
* @param context session context
* @param from starting node for path
* @param path the path
* @return the Item (Node or Property)
* @throws PathNotFoundException
*/
public static ItemImpl findItem(SessionImpl context, NodeRef from, String path)
throws PathNotFoundException
{
ItemImpl item = null;
NodeRef nodeRef = getNodeRef(context, from, path);
if (nodeRef != null)
{
item = new NodeImpl(context, nodeRef);
}
else
{
// TODO: create property
}
if (item == null)
{
throw new PathNotFoundException("Path " + path + " not found.");
}
return item;
}
/**
* Create an Node from a JCR Path
*
* @param context session context
* @param from starting node for path
* @param path the path
* @return the Item (Node or Property)
* @throws PathNotFoundException
*/
public static NodeImpl findNode(SessionImpl context, NodeRef from, String path)
throws PathNotFoundException
{
NodeRef nodeRef = getNodeRef(context, from, path);
if (nodeRef == null)
{
throw new PathNotFoundException("A node does not exist at path " + path + " relative to node " + from);
}
return new NodeImpl(context, nodeRef);
}
/**
* Determine if Item exists
*
* @param context session context
* @param from starting node for path
* @param path the path
* @return true => exists, false => no it doesn't
*/
public static boolean itemExists(SessionImpl context, NodeRef from, String path)
{
boolean exists = nodeExists(context, from, path);
if (!exists)
{
// TODO: Check for property
}
return exists;
}
/**
* Determine if Node exists
*
* @param context session context
* @param from starting node for path
* @param path the path
* @return true => exists, false => no it doesn't
*/
public static boolean nodeExists(SessionImpl context, NodeRef from, String path)
{
NodeRef nodeRef = getNodeRef(context, from, path);
return nodeRef != null;
}
/**
* Gets the Node Reference for the node at the specified path
*
* @param context session context
* @param from the starting node for the path
* @param path the path
* @return the node reference (or null if not found)
*/
public static NodeRef getNodeRef(SessionImpl context, NodeRef from, String path)
{
NodeRef nodeRef = null;
// TODO: Support JCR Path
// TODO: Catch malformed path and return false (per Specification)
SearchService search = context.getRepositoryImpl().getServiceRegistry().getSearchService();
List<NodeRef> nodeRefs = search.selectNodes(from, path, null, context.getNamespaceResolver(), false);
if (nodeRefs != null && nodeRefs.size() > 0)
{
nodeRef = nodeRefs.get(0);
}
return nodeRef;
}
}

View File

@@ -0,0 +1,192 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.item;
import java.util.StringTokenizer;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.QName;
/**
* JCR Path Helper
*
* @author David Caruana
*/
public class JCRPath
{
private Path path;
/**
* Constuct path from string representation of path
*
* @param strPath
*/
public JCRPath(NamespacePrefixResolver resolver, String strPath)
{
// TODO: replace this simple parse for full path syntax
boolean root = false;
int pos = 0;
path = new Path();
StringTokenizer tokenizer = new StringTokenizer(strPath, "/", true);
while (tokenizer.hasMoreTokens())
{
String token = tokenizer.nextToken();
if (pos == 0 && token.equals("/"))
{
root = true;
}
else if (!token.equals("/"))
{
if (root)
{
path.append(new RootSimpleElement(resolver, token));
root = false;
}
else
{
path.append(new SimpleElement(resolver, token));
}
}
pos++;
}
}
/**
* Get the Path
*
* @return the underling path
*/
public Path getPath()
{
return path;
}
@Override
public String toString()
{
return path.toString();
}
/**
* Simple Path Element used for building JCR Paths
*
* @author David Caruana
*/
public static class SimpleElement extends Path.Element
{
private static final long serialVersionUID = -6510331182652872996L;
private QName path;
/**
* @param resolver namespace prefix resolver
* @param path path element name
*/
public SimpleElement(QName path)
{
this.path = path;
}
/**
* @param path path element name
*/
public SimpleElement(NamespacePrefixResolver resolver, String path)
{
this.path = QName.createQName(path, resolver);
}
/**
* Get the QName representation of Path
*/
public QName getQName()
{
return path;
}
@Override
public String getElementString()
{
return path.toString();
}
@Override
public String getPrefixedString(NamespacePrefixResolver resolver)
{
return path.toPrefixString(resolver);
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object o)
{
if(o == this)
{
return true;
}
if(!(o instanceof SimpleElement))
{
return false;
}
SimpleElement other = (SimpleElement)o;
return this.path.equals(other.path);
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
public int hashCode()
{
return path.hashCode();
}
}
/**
* Root Path Element
*
* @author David Caruana
*/
public static class RootSimpleElement extends SimpleElement
{
private static final long serialVersionUID = -4827016063963328324L;
/**
* Construct
*
* @param path
*/
public RootSimpleElement(NamespacePrefixResolver resolver, String path)
{
super(resolver, path);
}
@Override
public String getElementString()
{
return "/" + super.getElementString();
}
@Override
public String getPrefixedString(NamespacePrefixResolver resolver)
{
return "/" + super.getPrefixedString(resolver);
}
}
}

View File

@@ -0,0 +1,93 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.item;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.QNamePattern;
/**
* Checks if the QName matches the passed JCR pattern.
*
* The pattern may be a full name or a partial name with one or more wildcard
* characters ("*"), or a disjunction (using the "|" character to represent
* logical OR) of these. For example,
*
* isMatch("jcr:* | myapp:report | my doc")
*
* Note that leading and trailing whitespace around a disjunct is ignored,
* but whitespace within a disjunct forms part of the pattern to be matched.
*
* The EBNF for namePattern is:
*
* namePattern ::= disjunct {'|' disjunct}
* disjunct ::= name [':' name]
* name ::= '*' | ['*'] fragment {'*' fragment} ['*']
* fragment ::= char {char}
* char ::= nonspace | ' '
* nonspace ::= (* Any Unicode character except: '/', ':', '[', ']', '*', ''', '"', '|' or any whitespace character *)
*/
public class JCRPatternMatch implements QNamePattern
{
private List<String> searches = new ArrayList<String>();
private NamespacePrefixResolver resolver;
/**
* Construct
* @param pattern JCR Pattern
* @param resolver Namespace Prefix Resolver
*/
public JCRPatternMatch(String pattern, NamespacePrefixResolver resolver)
{
// TODO: Check for valid pattern
// Convert to regular expression
String regexPattern = pattern.replaceAll("\\*", ".*");
// Split into independent search strings
StringTokenizer tokenizer = new StringTokenizer(regexPattern, "|", false);
while (tokenizer.hasMoreTokens())
{
String disjunct = tokenizer.nextToken().trim();
this.searches.add(disjunct);
}
this.resolver = resolver;
}
/* (non-Javadoc)
* @see org.alfresco.service.namespace.QNamePattern#isMatch(org.alfresco.service.namespace.QName)
*/
public boolean isMatch(QName qname)
{
String prefixedName = qname.toPrefixString(resolver);
for (String search : searches)
{
if (prefixedName.matches(search))
{
return true;
}
}
return false;
}
}

View File

@@ -0,0 +1,416 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.item;
import java.io.InputStream;
import java.util.Calendar;
import java.util.Date;
import javax.jcr.RepositoryException;
import javax.jcr.ValueFormatException;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.repository.datatype.TypeConversionException;
import org.alfresco.service.cmr.repository.datatype.TypeConverter;
import org.alfresco.service.namespace.NamespaceException;
import org.alfresco.service.namespace.QName;
/**
* Responsible for converting Alfresco values to JCR values.
*
* @author David Caruana
*
*/
public class JCRTypeConverter
{
private SessionTypeConverter jcrTypeConverter;
/**
* Construct
*
* @param session
*/
public JCRTypeConverter(SessionImpl session)
{
this.jcrTypeConverter = new SessionTypeConverter(session);
}
/**
* Get the underlying Converter
*
* @return type converter
*/
public TypeConverter getConverter()
{
return jcrTypeConverter;
}
/**
* Convert to JCR Reference Value
*
* @param session
* @param value
* @return
* @throws ValueFormatException
* @throws RepositoryException
*/
public NodeImpl referenceValue(Object value) throws ValueFormatException, RepositoryException
{
NodeRef nodeRef = (NodeRef)convert(NodeRef.class, value);
return new NodeImpl(jcrTypeConverter.getSession(), nodeRef);
}
/**
* Convert to JCR String Value
*
* @param value
* @return
* @throws ValueFormatException
* @throws RepositoryException
*/
public String stringValue(Object value) throws ValueFormatException, RepositoryException
{
return (String)convert(String.class, value);
}
/**
* Convert to JCR Stream Value
*
* @param value
* @return
* @throws IllegalStateException
* @throws RepositoryException
*/
public InputStream streamValue(Object value) throws IllegalStateException, RepositoryException
{
return (InputStream)convert(InputStream.class, value);
}
/**
* Convert to JCR Long Value
*
* @param value
* @return
* @throws ValueFormatException
* @throws IllegalStateException
* @throws RepositoryException
*/
public long longValue(Object value) throws ValueFormatException, IllegalStateException, RepositoryException
{
try
{
return jcrTypeConverter.longValue(value);
}
catch(Exception e)
{
translateException(e);
throw new RepositoryException(e);
}
}
/**
* Convert to JCR Double Value
*
* @param value
* @return
* @throws ValueFormatException
* @throws IllegalStateException
* @throws RepositoryException
*/
public double doubleValue(Object value) throws ValueFormatException, IllegalStateException, RepositoryException
{
try
{
return jcrTypeConverter.doubleValue(value);
}
catch(Exception e)
{
translateException(e);
throw new RepositoryException(e);
}
}
/**
* Convert to JCR Date Value
*
* @param value
* @return
* @throws ValueFormatException
* @throws IllegalStateException
* @throws RepositoryException
*/
public Calendar dateValue(Object value) throws ValueFormatException, IllegalStateException, RepositoryException
{
Date date = (Date)convert(Date.class, value);
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
return calendar;
}
/**
* Convert to JCR Boolean Value
*
* @param value
* @return
* @throws ValueFormatException
* @throws IllegalStateException
* @throws RepositoryException
*/
public boolean booleanValue(Object value) throws ValueFormatException, IllegalStateException, RepositoryException
{
try
{
return jcrTypeConverter.booleanValue(value);
}
catch(Exception e)
{
translateException(e);
throw new RepositoryException(e);
}
}
/**
* Convert to JCR Name Value
*
* @param value
* @return
* @throws ValueFormatException
* @throws IllegalStateException
* @throws RepositoryException
*/
public QName nameValue(Object value) throws ValueFormatException, IllegalStateException, RepositoryException
{
return convert(QName.class, value);
}
/**
* Convert to JCR Path Value
*
* @param value
* @return
* @throws ValueFormatException
* @throws IllegalStateException
* @throws RepositoryException
*/
public Path pathValue(Object value) throws ValueFormatException, IllegalStateException, RepositoryException
{
return convert(Path.class, value);
}
/**
* General conversion method using JCR converters
*
* @param propertyType datatype to convert to
* @param value the value to convert
* @return the converted value
* @throws RepositoryException
*/
public final Object convert(DataTypeDefinition propertyType, Object value)
throws RepositoryException
{
try
{
return jcrTypeConverter.convert(propertyType, value);
}
catch(Exception e)
{
translateException(e);
throw new RepositoryException(e);
}
}
/**
* General conversion method using JCR converters
*
* @param <T> class
* @param c class
* @param value value to convert
* @return converted value
* @throws RepositoryException
*/
public final <T> T convert(Class<T> c, Object value)
throws RepositoryException
{
try
{
return jcrTypeConverter.convert(c, value);
}
catch(Exception e)
{
translateException(e);
throw new RepositoryException(e);
}
}
/**
* Catch and translate value conversion errors
*
* @param e exception to translate
* @throws ValueFormatException value formatting exception
*/
private static void translateException(Exception e) throws ValueFormatException
{
if (e instanceof TypeConversionException ||
e instanceof NumberFormatException)
{
throw new ValueFormatException(e);
}
}
/**
* Data Type Converter that takes into account JCR session context
*
* @author David Caruana
*/
private static class SessionTypeConverter extends TypeConverter
{
private SessionImpl session;
/**
* Construct
*
* @param session session context
*/
public SessionTypeConverter(SessionImpl session)
{
this.session = session;
/**
* Converter to translating string to QName as prefix:localName
*/
addConverter(String.class, QName.class, new TypeConverter.Converter<String, QName>()
{
public QName convert(String source)
{
try
{
return QName.createQName(source, SessionTypeConverter.this.session.getNamespaceResolver());
}
catch(NamespaceException e)
{
throw new TypeConversionException("Cannot convert " + source + " to qualified name", e);
}
}
});
/**
* Converter to translating string to QName as prefix:localName
*/
addConverter(String.class, Path.class, new TypeConverter.Converter<String, Path>()
{
public Path convert(String source)
{
try
{
return new JCRPath(SessionTypeConverter.this.session.getNamespaceResolver(), source).getPath();
}
catch(NamespaceException e)
{
throw new TypeConversionException("Cannot convert " + source + " to qualified name", e);
}
}
});
/**
* Converter for translating QName to string as prefix:localName
*/
addConverter(QName.class, String.class, new TypeConverter.Converter<QName, String>()
{
public String convert(QName source)
{
try
{
return source.toPrefixString(SessionTypeConverter.this.session.getNamespaceResolver());
}
catch(NamespaceException e)
{
throw new TypeConversionException("Cannot convert " + source + " to qualified name", e);
}
}
});
/**
* Converter for translating Path to string as prefix:localName
*/
addConverter(Path.class, String.class, new TypeConverter.Converter<Path, String>()
{
public String convert(Path source)
{
try
{
return source.toPrefixString(SessionTypeConverter.this.session.getNamespaceResolver());
}
catch(NamespaceException e)
{
throw new TypeConversionException("Cannot convert " + source + " to qualified name", e);
}
}
});
/**
* Converter for translating Node Ref to JCR Id
*/
addConverter(NodeRef.class, String.class, new TypeConverter.Converter<NodeRef, String>()
{
public String convert(NodeRef source)
{
return source.getId();
}
});
}
/**
* Get the session
*
* @return session
*/
public SessionImpl getSession()
{
return session;
}
/* (non-Javadoc)
* @see org.alfresco.service.cmr.repository.datatype.TypeConverter#getConverter(java.lang.Class, java.lang.Class)
*/
@Override
@SuppressWarnings("unchecked")
public <F, T> Converter getConverter(Class<F> source, Class<T> dest)
{
Converter converter = super.getConverter(source, dest);
if (converter == null)
{
converter = DefaultTypeConverter.INSTANCE.getConverter(source, dest);
if (converter instanceof DynamicTwoStageConverter)
{
DynamicTwoStageConverter dynamic = (DynamicTwoStageConverter)converter;
converter = addDynamicTwoStageConverter(dynamic.getFrom(), dynamic.getIntermediate(), dynamic.getTo());
}
}
return converter;
}
}
}

View File

@@ -0,0 +1,137 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.item;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.lock.Lock;
import javax.jcr.lock.LockException;
import org.alfresco.jcr.util.JCRProxyFactory;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.lock.LockService;
import org.alfresco.service.cmr.lock.LockStatus;
import org.alfresco.service.cmr.repository.NodeService;
/**
* Alfresco implementation of a JCR Lock
*
* @author David Caruana
*/
public class LockImpl implements Lock
{
private NodeImpl node;
private Lock proxy = null;
/**
* Constructor
*
* @param node node holding lock
*/
public LockImpl(NodeImpl node)
{
this.node = node;
}
/**
* Create proxied JCR Lock
*
* @return lock
*/
public Lock getProxy()
{
if (proxy == null)
{
proxy = (Lock)JCRProxyFactory.create(this, Lock.class, node.session);
}
return proxy;
}
/*
* (non-Javadoc)
* @see javax.jcr.lock.Lock#getLockOwner()
*/
public String getLockOwner()
{
String lockOwner = null;
NodeService nodeService = node.session.getRepositoryImpl().getServiceRegistry().getNodeService();
if (nodeService.hasAspect(node.getNodeRef(), ContentModel.ASPECT_LOCKABLE))
{
lockOwner = (String)nodeService.getProperty(node.getNodeRef(), ContentModel.PROP_LOCK_OWNER);
}
return lockOwner;
}
/*
* (non-Javadoc)
* @see javax.jcr.lock.Lock#isDeep()
*/
public boolean isDeep()
{
return false;
}
/*
* (non-Javadoc)
* @see javax.jcr.lock.Lock#getNode()
*/
public Node getNode()
{
return node.getProxy();
}
/*
* (non-Javadoc)
* @see javax.jcr.lock.Lock#getLockToken()
*/
public String getLockToken()
{
LockService lockService = node.session.getRepositoryImpl().getServiceRegistry().getLockService();
LockStatus lockStatus = lockService.getLockStatus(node.getNodeRef());
return lockStatus.equals(LockStatus.LOCK_OWNER) ? node.getNodeRef().toString() : null;
}
/*
* (non-Javadoc)
* @see javax.jcr.lock.Lock#isLive()
*/
public boolean isLive() throws RepositoryException
{
return getLockToken() == null ? false : true;
}
/*
* (non-Javadoc)
* @see javax.jcr.lock.Lock#isSessionScoped()
*/
public boolean isSessionScoped()
{
return false;
}
/*
* (non-Javadoc)
* @see javax.jcr.lock.Lock#refresh()
*/
public void refresh() throws LockException, RepositoryException
{
// note: for now, this is a noop
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,81 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.item;
import java.util.List;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.query.QueryResult;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.jcr.util.AbstractRangeIterator;
import org.alfresco.jcr.util.JCRProxyFactory;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* Alfresco implementation of a Node Iterator
*
* @author David Caruana
*/
public class NodeRefNodeIteratorImpl extends AbstractRangeIterator
implements NodeIterator
{
private SessionImpl sessionImpl;
private List<NodeRef> nodeRefs;
/**
* Construct
*
* @param context session context
* @param nodes node list
*/
public NodeRefNodeIteratorImpl(SessionImpl sessionImpl, List<NodeRef> nodeRefs)
{
this.sessionImpl = sessionImpl;
this.nodeRefs = nodeRefs;
}
/* (non-Javadoc)
* @see javax.jcr.NodeIterator#nextNode()
*/
public Node nextNode()
{
long position = skip();
NodeRef nodeRef = nodeRefs.get((int)position);
NodeImpl nodeImpl = new NodeImpl(sessionImpl, nodeRef);
return nodeImpl.getProxy();
}
/* (non-Javadoc)
* @see javax.jcr.RangeIterator#getSize()
*/
public long getSize()
{
return nodeRefs.size();
}
/* (non-Javadoc)
* @see java.util.Iterator#next()
*/
public Object next()
{
return nextNode();
}
}

View File

@@ -0,0 +1,684 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.item;
import java.io.InputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.List;
import javax.jcr.AccessDeniedException;
import javax.jcr.Item;
import javax.jcr.ItemNotFoundException;
import javax.jcr.ItemVisitor;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;
import javax.jcr.lock.LockException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.PropertyDefinition;
import javax.jcr.version.VersionException;
import org.alfresco.jcr.api.JCRNodeRef;
import org.alfresco.jcr.dictionary.DataTypeMap;
import org.alfresco.jcr.dictionary.PropertyDefinitionImpl;
import org.alfresco.jcr.util.JCRProxyFactory;
import org.alfresco.repo.content.MimetypeMap;
import org.alfresco.service.cmr.dictionary.DataTypeDefinition;
import org.alfresco.service.cmr.dictionary.DictionaryService;
import org.alfresco.service.cmr.dictionary.InvalidTypeException;
import org.alfresco.service.cmr.repository.ContentReader;
import org.alfresco.service.cmr.repository.ContentService;
import org.alfresco.service.cmr.repository.ContentWriter;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.datatype.DefaultTypeConverter;
import org.alfresco.service.cmr.repository.datatype.TypeConversionException;
import org.alfresco.service.namespace.QName;
/**
* Alfresco implementation of a Property
*
* @author David Caruana
*/
public class PropertyImpl extends ItemImpl implements Property
{
private NodeImpl node;
private QName name;
private Property proxy = null;
/**
* Constructor
*
* @param session
*/
public PropertyImpl(NodeImpl node, QName name)
{
super(node.session);
this.node = node;
this.name = name;
}
/**
* Create proxied JCR Property
*
* @return property
*/
@Override
public Property getProxy()
{
if (proxy == null)
{
proxy = (Property)JCRProxyFactory.create(this, Property.class, session);
}
return proxy;
}
/* (non-Javadoc)
* @see javax.jcr.Item#remove()
*/
public void remove() throws VersionException, LockException, ConstraintViolationException, RepositoryException
{
setValue((Value)null);
}
/* (non-Javadoc)
* @see javax.jcr.Property#setValue(javax.jcr.Value)
*/
public void setValue(Value value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
setPropertyValue(value, -1);
}
/* (non-Javadoc)
* @see javax.jcr.Property#setValue(javax.jcr.Value[])
*/
public void setValue(Value[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
setPropertyValue(values, -1);
}
/* (non-Javadoc)
* @see javax.jcr.Property#setValue(java.lang.String)
*/
public void setValue(String value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
setPropertyValue(value, -1);
}
/* (non-Javadoc)
* @see javax.jcr.Property#setValue(java.lang.String[])
*/
public void setValue(String[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
setPropertyValue(values, -1);
}
/* (non-Javadoc)
* @see javax.jcr.Property#setValue(java.io.InputStream)
*/
public void setValue(InputStream value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
setPropertyValue(value, -1);
}
/* (non-Javadoc)
* @see javax.jcr.Property#setValue(long)
*/
public void setValue(long value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
setPropertyValue(value, -1);
}
/* (non-Javadoc)
* @see javax.jcr.Property#setValue(double)
*/
public void setValue(double value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
setPropertyValue(value, -1);
}
/* (non-Javadoc)
* @see javax.jcr.Property#setValue(java.util.Calendar)
*/
public void setValue(Calendar value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
setPropertyValue((value == null) ? null : value.getTime(), -1);
}
/* (non-Javadoc)
* @see javax.jcr.Property#setValue(boolean)
*/
public void setValue(boolean value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
setPropertyValue(value, -1);
}
/* (non-Javadoc)
* @see javax.jcr.Property#setValue(javax.jcr.Node)
*/
public void setValue(Node value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
setPropertyValue((value == null) ? null : JCRNodeRef.getNodeRef(value), -1);
}
/* (non-Javadoc)
* @see javax.jcr.Property#getValue()
*/
public Value getValue() throws ValueFormatException, RepositoryException
{
checkSingleValued();
ValueImpl valueImpl = new ValueImpl(session, getType(), getPropertyValue());
// TODO: Could consider returning proxied value implementation (but i don't think is necessary)
return valueImpl;
}
/* (non-Javadoc)
* @see javax.jcr.Property#getValues()
*/
public Value[] getValues() throws ValueFormatException, RepositoryException
{
// get values from node property
checkMultiValued();
Collection values = (Collection)getPropertyValue();
int type = getType();
// construct JCR wrappers
List<Value> jcrValues = new ArrayList<Value>(values.size());
for (Object value : values)
{
// Note: In JCR all null values are stripped
if (value != null)
{
// TODO: Could consider returning proxied value implementation (but i don't think is necessary)
jcrValues.add(new ValueImpl(session, type, value));
}
}
return jcrValues.toArray(new Value[jcrValues.size()]);
}
/* (non-Javadoc)
* @see javax.jcr.Property#getString()
*/
public String getString() throws ValueFormatException, RepositoryException
{
checkSingleValued();
return session.getTypeConverter().stringValue(getPropertyValue());
}
/* (non-Javadoc)
* @see javax.jcr.Property#getStream()
*/
public InputStream getStream() throws ValueFormatException, RepositoryException
{
checkSingleValued();
return session.getTypeConverter().streamValue(getPropertyValue());
}
/* (non-Javadoc)
* @see javax.jcr.Property#getLong()
*/
public long getLong() throws ValueFormatException, RepositoryException
{
checkSingleValued();
return session.getTypeConverter().longValue(getPropertyValue());
}
/* (non-Javadoc)
* @see javax.jcr.Property#getDouble()
*/
public double getDouble() throws ValueFormatException, RepositoryException
{
checkSingleValued();
return session.getTypeConverter().doubleValue(getPropertyValue());
}
/* (non-Javadoc)
* @see javax.jcr.Property#getDate()
*/
public Calendar getDate() throws ValueFormatException, RepositoryException
{
checkSingleValued();
return session.getTypeConverter().dateValue(getPropertyValue());
}
/* (non-Javadoc)
* @see javax.jcr.Property#getBoolean()
*/
public boolean getBoolean() throws ValueFormatException, RepositoryException
{
checkSingleValued();
return session.getTypeConverter().booleanValue(getPropertyValue());
}
/* (non-Javadoc)
* @see javax.jcr.Property#getNode()
*/
public Node getNode() throws ValueFormatException, RepositoryException
{
checkSingleValued();
return session.getTypeConverter().referenceValue(getPropertyValue()).getProxy();
}
/* (non-Javadoc)
* @see javax.jcr.Property#getLength()
*/
public long getLength() throws ValueFormatException, RepositoryException
{
checkSingleValued();
return getPropertyLength(getPropertyValue());
}
/* (non-Javadoc)
* @see javax.jcr.Property#getLengths()
*/
public long[] getLengths() throws ValueFormatException, RepositoryException
{
checkMultiValued();
Collection values = (Collection)getPropertyValue();
long[] lengths = new long[values.size()];
int i = 0;
for (Object value : values)
{
lengths[i++] = getPropertyLength(value);
}
return lengths;
}
/* (non-Javadoc)
* @see javax.jcr.Property#getDefinition()
*/
public PropertyDefinition getDefinition() throws RepositoryException
{
PropertyDefinitionImpl propDefImpl = new PropertyDefinitionImpl(session.getTypeManager(), getPropertyDefinition());
return propDefImpl;
}
/* (non-Javadoc)
* @see javax.jcr.Property#getType()
*/
public int getType() throws RepositoryException
{
// TODO: The type should be based on the property value (in the case of undefined required type)
return DataTypeMap.convertDataTypeToPropertyType(getPropertyDefinition().getDataType().getName());
}
/* (non-Javadoc)
* @see javax.jcr.Item#getName()
*/
public String getName() throws RepositoryException
{
return name.toPrefixString(session.getNamespaceResolver());
}
/* (non-Javadoc)
* @see javax.jcr.Item#isNode()
*/
public boolean isNode()
{
return false;
}
/* (non-Javadoc)
* @see javax.jcr.Item#getParent()
*/
public Node getParent() throws ItemNotFoundException, AccessDeniedException, RepositoryException
{
return node.getProxy();
}
/* (non-Javadoc)
* @see javax.jcr.Item#getPath()
*/
public String getPath() throws RepositoryException
{
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
Path path = nodeService.getPath(node.getNodeRef());
path.append(new JCRPath.SimpleElement(name));
return path.toPrefixString(session.getNamespaceResolver());
}
/* (non-Javadoc)
* @see javax.jcr.Item#getDepth()
*/
public int getDepth() throws RepositoryException
{
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
Path path = nodeService.getPath(node.getNodeRef());
// Note: Property is one depth lower than its node
return path.size();
}
/* (non-Javadoc)
* @see javax.jcr.Item#getAncestor(int)
*/
public Item getAncestor(int depth) throws ItemNotFoundException, AccessDeniedException, RepositoryException
{
int propertyDepth = getDepth();
if (depth < 0 || depth > propertyDepth)
{
throw new ItemNotFoundException("Ancestor at depth " + depth + " not found for property " + name);
}
if (depth == propertyDepth)
{
return this.getProxy();
}
else
{
return node.getAncestor(depth -1);
}
}
/* (non-Javadoc)
* @see javax.jcr.Item#isSame(javax.jcr.Item)
*/
public boolean isSame(Item otherItem) throws RepositoryException
{
return getProxy().equals(otherItem);
}
/* (non-Javadoc)
* @see javax.jcr.Item#accept(javax.jcr.ItemVisitor)
*/
public void accept(ItemVisitor visitor) throws RepositoryException
{
visitor.visit(getProxy());
}
/**
* Gets the Node Implementation that contains this property
*
* @return the node implementation
*/
protected NodeImpl getNodeImpl()
{
return node;
}
/**
* Gets the Property Name
*
* @return the property name
*/
protected QName getPropertyName()
{
return name;
}
/**
* Gets the property value
*
* @return the property value
*/
protected Object getPropertyValue()
throws RepositoryException
{
Object value = null;
if (getPropertyDefinition().getDataType().getName().equals(DataTypeDefinition.CONTENT))
{
// Retrieve content reader as value
ContentService contentService = node.session.getRepositoryImpl().getServiceRegistry().getContentService();
value = contentService.getReader(node.getNodeRef(), name);
if (value == null)
{
// TODO: Check - If value is now null, then effectively the property has been removed
throw new RepositoryException("Property " + name + " has been removed.");
}
}
else
{
// TODO: We may need to copy value here...
NodeService nodeService = node.session.getRepositoryImpl().getServiceRegistry().getNodeService();
value = nodeService.getProperty(node.getNodeRef(), name);
if (value == null)
{
// TODO: Check - If value is now null, then effectively the property has been removed
throw new RepositoryException("Property " + name + " has been removed.");
}
// Note: Internal check to ensure that value is single or multi-valued as expected
boolean multiValued = getPropertyDefinition().isMultiValued();
if (multiValued != (value instanceof Collection))
{
throw new RepositoryException("Alfresco value does not match multi-valued definition of " + multiValued);
}
}
return value;
}
/**
* Get Length of a Value
*
* @param value
* @return
* @throws ValueFormatException
* @throws RepositoryException
*/
private long getPropertyLength(Object value) throws ValueFormatException, RepositoryException
{
// Handle streams
if (value instanceof ContentReader)
{
return ((ContentReader)value).getSize();
}
if (value instanceof InputStream)
{
return -1;
}
// Handle all other data types by converting to string
String strValue = (String)DefaultTypeConverter.INSTANCE.convert(String.class, value);
return strValue.length();
}
/**
* Sets a property value
*
* @param value the value to set
* @param type type to explicitly convert to or -1 to convert to property type
* @throws RepositoryException
*/
protected void setPropertyValue(Object value, int type)
throws RepositoryException
{
checkSingleValued();
Object castValue = castValue(value, type);
writeValue(castValue);
}
/**
* Sets a property value
*
* @param values the values to set
* @param type type to explicitly convert to or -1 to convert to property type
* @throws RepositoryException
*/
protected void setPropertyValue(Object[] values, int type)
throws RepositoryException
{
checkMultiValued();
// create collection for multi-valued property
List<Object> castValues = null;
if (values != null)
{
castValues = new ArrayList<Object>(values.length);
for (Object value : values)
{
Object castValue = castValue(value, type);
castValues.add(castValue);
}
}
writeValue(castValues);
}
/**
* Cast value to appropriate type for this property
*
* @param value value to cast
* @param type -1 => cast to property type; otherwise cast to type explicitly provided
* @return the cast value
* @throws RepositoryException
*/
private Object castValue(Object value, int type)
throws RepositoryException
{
// extract raw value if JCR value provided
if (value instanceof Value)
{
value = ValueImpl.getValue((Value)value);
}
// cast value to appropriate type
DataTypeDefinition dataTypeDef = getPropertyDefinition().getDataType();
if (type != -1 && dataTypeDef.getName().equals(DataTypeDefinition.ANY))
{
// attempt cast to explicitly specified type, but only in case where property type can be ANY
QName dataTypeName = DataTypeMap.convertPropertyTypeToDataType(type);
DictionaryService dictionaryService = session.getRepositoryImpl().getServiceRegistry().getDictionaryService();
dataTypeDef = dictionaryService.getDataType(dataTypeName);
if (!dataTypeName.equals(DataTypeDefinition.CONTENT))
{
value = session.getTypeConverter().convert(dataTypeDef, value);
}
}
// special case where binary is converted to inputStream ready for writing via a ContentWriter
if (dataTypeDef.getName().equals(DataTypeDefinition.CONTENT))
{
value = session.getTypeConverter().streamValue(value);
}
return value;
}
/**
* Write the passed value to the property
*
* @param value value to write
* @throws ValueFormatException
*/
private void writeValue(Object value)
throws ValueFormatException
{
// set the property value
if (value instanceof InputStream)
{
// write content
try
{
ContentService contentService = session.getRepositoryImpl().getServiceRegistry().getContentService();
ContentWriter writer = contentService.getWriter(node.getNodeRef(), name, true);
writer.setMimetype(MimetypeMap.MIMETYPE_BINARY);
writer.putContent((InputStream)value);
}
catch(InvalidTypeException e)
{
throw new ValueFormatException(e);
}
}
else
{
// write property value
// Note: In the case of Content properties, this effectively "deletes" the content when the value is null
try
{
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
nodeService.setProperty(node.getNodeRef(), name, (Serializable)value);
}
catch(TypeConversionException e)
{
throw new ValueFormatException(e);
}
}
}
/**
* Checks that this property is single valued.
*
* @throws ValueFormatException if value is multi-valued
*/
private void checkSingleValued()
throws ValueFormatException
{
if (getPropertyDefinition().isMultiValued())
{
// Expected exception for JSR-170
throw new ValueFormatException("Property " + name + " is multi-valued.");
}
}
/**
* Checks that this property is single valued.
*
* @throws ValueFormatException if value is multi-valued
*/
private void checkMultiValued()
throws ValueFormatException
{
if (!getPropertyDefinition().isMultiValued())
{
// Expected exception for JSR-170
throw new ValueFormatException("Property " + name + " is single-valued.");
}
}
/**
* Gets the Property Data Type
*
* @return the (JCR) data type
*/
private org.alfresco.service.cmr.dictionary.PropertyDefinition getPropertyDefinition()
{
DictionaryService dictionary = session.getRepositoryImpl().getServiceRegistry().getDictionaryService();
return dictionary.getProperty(name);
}
@Override
public boolean equals(Object obj)
{
if (obj == this)
{
return true;
}
if (!(obj instanceof PropertyImpl))
{
return false;
}
PropertyImpl other = (PropertyImpl)obj;
return this.name.equals(other.name);
}
@Override
public int hashCode()
{
return name.hashCode();
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.item;
import java.util.List;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import org.alfresco.jcr.util.AbstractRangeIterator;
/**
* Alfresco implementation of a Property Iterator
*
* @author David Caruana
*/
public class PropertyListIterator extends AbstractRangeIterator
implements PropertyIterator
{
private List<PropertyImpl> properties;
/**
* Construct
*
* @param context session context
* @param properties property list
*/
public PropertyListIterator(List<PropertyImpl> properties)
{
this.properties = properties;
}
/* (non-Javadoc)
* @see javax.jcr.PropertyIterator#nextProperty()
*/
public Property nextProperty()
{
long position = skip();
PropertyImpl propertyImpl = properties.get((int)position);
return propertyImpl.getProxy();
}
/* (non-Javadoc)
* @see javax.jcr.RangeIterator#getSize()
*/
public long getSize()
{
return properties.size();
}
/* (non-Javadoc)
* @see java.util.Iterator#next()
*/
public Object next()
{
return nextProperty();
}
}

View File

@@ -0,0 +1,193 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.item;
import java.io.InputStream;
import java.util.Calendar;
import java.util.Date;
import javax.jcr.Node;
import javax.jcr.Property;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFactory;
import javax.jcr.ValueFormatException;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.jcr.util.JCRProxyFactory;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.QName;
/**
* Alfresco implementation of JCR Value Factory
*
* @author David Caruana
*
*/
public class ValueFactoryImpl implements ValueFactory
{
private SessionImpl session;
private ValueFactory proxy = null;
/**
* Construct
*
* @param session
*/
public ValueFactoryImpl(SessionImpl session)
{
this.session = session;
}
/**
* Get proxied JCR Value Factory
*
* @return
*/
public ValueFactory getProxy()
{
if (proxy == null)
{
proxy = (ValueFactory)JCRProxyFactory.create(this, ValueFactory.class, session);
}
return proxy;
}
/* (non-Javadoc)
* @see javax.jcr.ValueFactory#createValue(java.lang.String, int)
*/
public Value createValue(String value, int type) throws ValueFormatException
{
Value createdValue = null;
try
{
switch(type)
{
case PropertyType.STRING:
createdValue = createValue(session.getTypeConverter().stringValue(value));
break;
case PropertyType.LONG:
createdValue = createValue(session.getTypeConverter().longValue(value));
break;
case PropertyType.DOUBLE:
createdValue = createValue(session.getTypeConverter().doubleValue(value));
break;
case PropertyType.BOOLEAN:
createdValue = createValue(session.getTypeConverter().booleanValue(value));
break;
case PropertyType.DATE:
createdValue = new ValueImpl(session, PropertyType.DATE, session.getTypeConverter().convert(Date.class, value));
break;
case PropertyType.BINARY:
createdValue = createValue(session.getTypeConverter().streamValue(value));
break;
case PropertyType.REFERENCE:
createdValue = new ValueImpl(session, PropertyType.REFERENCE, session.getTypeConverter().referenceValue(value));
break;
case PropertyType.NAME:
QName name = session.getTypeConverter().convert(QName.class, value);
createdValue = new ValueImpl(session, PropertyType.NAME, name);
break;
case PropertyType.PATH:
Path path = session.getTypeConverter().convert(Path.class, value);
createdValue = new ValueImpl(session, PropertyType.PATH, path);
break;
default:
throw new ValueFormatException("Cannot create value of type " + type);
}
}
catch(RepositoryException e)
{
// Should this method also throw repository exception
throw new ValueFormatException("Failed to create value " + value + " of type " + type, e);
}
return createdValue;
}
/* (non-Javadoc)
* @see javax.jcr.ValueFactory#createValue(java.lang.String)
*/
public Value createValue(String value)
{
return new ValueImpl(session, PropertyType.STRING, value);
}
/* (non-Javadoc)
* @see javax.jcr.ValueFactory#createValue(long)
*/
public Value createValue(long value)
{
return new ValueImpl(session, PropertyType.LONG, value);
}
/* (non-Javadoc)
* @see javax.jcr.ValueFactory#createValue(double)
*/
public Value createValue(double value)
{
return new ValueImpl(session, PropertyType.DOUBLE, value);
}
/* (non-Javadoc)
* @see javax.jcr.ValueFactory#createValue(boolean)
*/
public Value createValue(boolean value)
{
return new ValueImpl(session, PropertyType.BOOLEAN, value);
}
/* (non-Javadoc)
* @see javax.jcr.ValueFactory#createValue(java.util.Calendar)
*/
public Value createValue(Calendar value)
{
return new ValueImpl(session, PropertyType.DATE, value.getTime());
}
/* (non-Javadoc)
* @see javax.jcr.ValueFactory#createValue(java.io.InputStream)
*/
public Value createValue(InputStream value)
{
return new ValueImpl(session, PropertyType.BINARY, value);
}
/* (non-Javadoc)
* @see javax.jcr.ValueFactory#createValue(javax.jcr.Node)
*/
public Value createValue(Node value) throws RepositoryException
{
if (value == null)
{
throw new RepositoryException("Node value must not be null");
}
// TODO: refer to ContentModel Constants
Property protocol = value.getProperty("sys:store-protocol");
Property identifier = value.getProperty("sys:store-identifier");
Property uuid = value.getProperty("sys:node-uuid");
// construct a node reference
NodeRef ref = new NodeRef(new StoreRef(protocol.getString(), identifier.getString()), uuid.getString());
return new ValueImpl(session, PropertyType.REFERENCE, ref);
}
}

View File

@@ -0,0 +1,321 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.item;
import java.io.InputStream;
import java.util.Calendar;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.jcr.util.JCRProxyFactory;
import org.alfresco.service.cmr.repository.ContentReader;
/**
* Alfresco implementation of JCR Value
*
* @author David Caruana
*/
public class ValueImpl implements Value
{
private enum ValueState {Stream, Value, None};
private ValueState state = ValueState.None;
private SessionImpl session;
private int datatype;
private Object value;
private InputStream stream = null;
private Value proxy;
/**
* Constuct
*
* @param value value to wrap
*/
public ValueImpl(SessionImpl session, int datatype, Object value)
{
this.session = session;
this.datatype = datatype;
this.value = value;
}
/**
* Create a proxied JCR Value
*
* @return the proxied value
*/
public Value getProxy()
{
if (proxy == null)
{
proxy = (Value)JCRProxyFactory.create(this, Value.class, session);
}
return proxy;
}
/* (non-Javadoc)
* @see javax.jcr.Value#getString()
*/
public String getString() throws ValueFormatException, IllegalStateException, RepositoryException
{
isValidState(ValueState.Value);
String typedValue = session.getTypeConverter().stringValue(getInternalValue());
value = typedValue;
enterState(ValueState.Value);
return typedValue;
}
/* (non-Javadoc)
* @see javax.jcr.Value#getStream()
*/
public InputStream getStream() throws IllegalStateException, RepositoryException
{
isValidState(ValueState.Stream);
if (stream == null)
{
stream = session.getTypeConverter().streamValue(value);
}
enterState(ValueState.Stream);
return stream;
}
/* (non-Javadoc)
* @see javax.jcr.Value#getLong()
*/
public long getLong() throws ValueFormatException, IllegalStateException, RepositoryException
{
isValidState(ValueState.Value);
long typedValue = session.getTypeConverter().longValue(getInternalValue());
value = typedValue;
enterState(ValueState.Value);
return typedValue;
}
/* (non-Javadoc)
* @see javax.jcr.Value#getDouble()
*/
public double getDouble() throws ValueFormatException, IllegalStateException, RepositoryException
{
isValidState(ValueState.Value);
double typedValue = session.getTypeConverter().doubleValue(getInternalValue());
value = typedValue;
enterState(ValueState.Value);
return typedValue;
}
/* (non-Javadoc)
* @see javax.jcr.Value#getDate()
*/
public Calendar getDate() throws ValueFormatException, IllegalStateException, RepositoryException
{
isValidState(ValueState.Value);
Calendar typedValue = session.getTypeConverter().dateValue(getInternalValue());
value = typedValue.getTime();
enterState(ValueState.Value);
return typedValue;
}
/* (non-Javadoc)
* @see javax.jcr.Value#getBoolean()
*/
public boolean getBoolean() throws ValueFormatException, IllegalStateException, RepositoryException
{
isValidState(ValueState.Value);
boolean typedValue = session.getTypeConverter().booleanValue(getInternalValue());
value = typedValue;
enterState(ValueState.Value);
return typedValue;
}
/* (non-Javadoc)
* @see javax.jcr.Value#getType()
*/
public int getType()
{
return datatype;
}
/**
* Get value
*
* @param value the value wrapper to extract from
* @return the value
*/
public static Object getValue(Value value) throws RepositoryException
{
Object objValue = null;
int valueType = value.getType();
switch(valueType)
{
case PropertyType.STRING:
case PropertyType.NAME:
case PropertyType.PATH:
objValue = value.getString();
break;
case PropertyType.LONG:
objValue = value.getLong();
break;
case PropertyType.DOUBLE:
objValue = value.getDouble();
break;
case PropertyType.BOOLEAN:
objValue = value.getBoolean();
break;
case PropertyType.DATE:
objValue = value.getDate();
break;
case PropertyType.BINARY:
objValue = value.getStream();
break;
default:
// Note: just take the internal value
objValue = ((ValueImpl)value).value;
break;
}
return objValue;
}
/**
* Get typed value
*
* @param value the value to extract from
* @return the wrapped object
*/
public static Object getValue(JCRTypeConverter typeConverter, int requiredType, Value value) throws RepositoryException
{
Object objValue = null;
switch(requiredType)
{
case PropertyType.STRING:
objValue = value.getString();
break;
case PropertyType.LONG:
objValue = value.getLong();
break;
case PropertyType.DOUBLE:
objValue = value.getDouble();
break;
case PropertyType.BOOLEAN:
objValue = value.getBoolean();
break;
case PropertyType.DATE:
objValue = value.getDate();
break;
case PropertyType.BINARY:
objValue = value.getStream();
break;
case PropertyType.NAME:
objValue = typeConverter.nameValue(ValueImpl.getValue(value));
break;
case PropertyType.PATH:
objValue = typeConverter.pathValue(ValueImpl.getValue(value));
break;
default:
throw new ValueFormatException("Unsupported Value Type " + requiredType);
}
return objValue;
}
/**
* Retrieve Value
*
* Note: When retrieving non stream values against a backed stream, the content reader
* has to be re-created.
*
* @return the value
*/
private Object getInternalValue()
{
if (value instanceof ContentReader && state == ValueState.Value)
{
value = ((ContentReader)value).getReader();
}
return value;
}
/**
* Check for valid state
*
* @param state the state to check
* @throws IllegalStateException state is not valid
*/
private void isValidState(ValueState state)
{
if (this.state != ValueState.None && this.state != state)
{
throw new IllegalStateException("This value has already been retrieved as a " + state + " and cannot be retrieved as a " + ValueState.Stream + ".");
}
}
/**
* Enter state
*
* @param state the state to enter
*/
private void enterState(ValueState state)
{
this.state = state;
}
@Override
public boolean equals(Object obj)
{
if (obj == this)
{
return true;
}
if (!(obj instanceof ValueImpl))
{
return false;
}
ValueImpl other = (ValueImpl)obj;
// check data type first
if (datatype != other.datatype)
{
return false;
}
// handle case where values are content streams
if (value instanceof ContentReader)
{
String thisUrl = ((ContentReader)value).getContentUrl();
String otherUrl = ((ContentReader)other).getContentUrl();
return thisUrl.equals(otherUrl);
}
// handle other value types
return value.equals(other.value);
}
@Override
public int hashCode()
{
return value.hashCode() * 32 + datatype;
}
}

View File

@@ -0,0 +1,52 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.item.property;
import javax.jcr.RepositoryException;
import org.alfresco.jcr.dictionary.JCRNamespace;
import org.alfresco.jcr.item.NodeImpl;
import org.alfresco.jcr.item.PropertyImpl;
import org.alfresco.service.namespace.QName;
/**
* Implementation for mix:lockable lockIsDeep property
*
* @author David Caruana
*/
public class JCRLockIsDeepProperty extends PropertyImpl
{
public static QName PROPERTY_NAME = QName.createQName(JCRNamespace.JCR_URI, "lockIsDeep");
/**
* Construct
*
* @param node
*/
public JCRLockIsDeepProperty(NodeImpl node)
{
super(node, PROPERTY_NAME);
}
@Override
protected Object getPropertyValue() throws RepositoryException
{
return false;
}
}

View File

@@ -0,0 +1,57 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.item.property;
import javax.jcr.RepositoryException;
import org.alfresco.jcr.dictionary.JCRNamespace;
import org.alfresco.jcr.item.NodeImpl;
import org.alfresco.jcr.item.PropertyImpl;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
/**
* Implementation for mix:lockable lockOwner property
*
* @author David Caruana
*/
public class JCRLockOwnerProperty extends PropertyImpl
{
public static QName PROPERTY_NAME = QName.createQName(JCRNamespace.JCR_URI, "lockOwner");
/**
* Construct
*
* @param node
*/
public JCRLockOwnerProperty(NodeImpl node)
{
super(node, PROPERTY_NAME);
}
@Override
protected Object getPropertyValue() throws RepositoryException
{
NodeImpl nodeImpl = getNodeImpl();
NodeService nodeService = nodeImpl.getSessionImpl().getRepositoryImpl().getServiceRegistry().getNodeService();
String lockOwner = (String)nodeService.getProperty(nodeImpl.getNodeRef(), ContentModel.PROP_LOCK_OWNER);
return lockOwner;
}
}

View File

@@ -0,0 +1,73 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.item.property;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import javax.jcr.RepositoryException;
import org.alfresco.jcr.dictionary.JCRNamespace;
import org.alfresco.jcr.dictionary.NodeTypeImpl;
import org.alfresco.jcr.item.NodeImpl;
import org.alfresco.jcr.item.PropertyImpl;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
/**
* Implementation for nt:base primaryType property
*
* @author David Caruana
*/
public class JCRMixinTypesProperty extends PropertyImpl
{
public static QName PROPERTY_NAME = QName.createQName(JCRNamespace.JCR_URI, "mixinTypes");
/**
* Construct
*
* @param node
*/
public JCRMixinTypesProperty(NodeImpl node)
{
super(node, PROPERTY_NAME);
}
@Override
protected Object getPropertyValue() throws RepositoryException
{
// get aspects from node
NodeImpl nodeImpl = getNodeImpl();
NodeService nodeService = nodeImpl.getSessionImpl().getRepositoryImpl().getServiceRegistry().getNodeService();
Set<QName> aspects = nodeService.getAspects(nodeImpl.getNodeRef());
// resolve against session namespace prefix resolver
List<String> aspectNames = new ArrayList<String>(aspects.size() + 1);
for (QName aspect : aspects)
{
aspectNames.add(aspect.toPrefixString(nodeImpl.getSessionImpl().getNamespaceResolver()));
}
// add JCR referenceable
aspectNames.add(NodeTypeImpl.MIX_REFERENCEABLE.toPrefixString(nodeImpl.getSessionImpl().getNamespaceResolver()));
return aspectNames;
}
}

View File

@@ -0,0 +1,56 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.item.property;
import javax.jcr.RepositoryException;
import org.alfresco.jcr.dictionary.JCRNamespace;
import org.alfresco.jcr.item.NodeImpl;
import org.alfresco.jcr.item.PropertyImpl;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
/**
* Implementation for nt:base primaryType property
*
* @author David Caruana
*/
public class JCRPrimaryTypeProperty extends PropertyImpl
{
public static QName PROPERTY_NAME = QName.createQName(JCRNamespace.JCR_URI, "primaryType");
/**
* Construct
*
* @param node
*/
public JCRPrimaryTypeProperty(NodeImpl node)
{
super(node, PROPERTY_NAME);
}
@Override
protected Object getPropertyValue() throws RepositoryException
{
NodeImpl nodeImpl = getNodeImpl();
NodeService nodeService = nodeImpl.getSessionImpl().getRepositoryImpl().getServiceRegistry().getNodeService();
QName type = nodeService.getType(nodeImpl.getNodeRef());
return type.toPrefixString(nodeImpl.getSessionImpl().getNamespaceResolver());
}
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.item.property;
import javax.jcr.RepositoryException;
import org.alfresco.jcr.dictionary.JCRNamespace;
import org.alfresco.jcr.item.NodeImpl;
import org.alfresco.jcr.item.PropertyImpl;
import org.alfresco.service.namespace.QName;
/**
* Implementation for mix:referenceable uuid property
* @author David Caruana
*
*/
public class JCRUUIDProperty extends PropertyImpl
{
public static QName PROPERTY_NAME = QName.createQName(JCRNamespace.JCR_URI, "uuid");
/**
* Construct
*
* @param node
*/
public JCRUUIDProperty(NodeImpl node)
{
super(node, PROPERTY_NAME);
}
@Override
protected Object getPropertyValue() throws RepositoryException
{
NodeImpl node = getNodeImpl();
return node.getNodeRef().getId();
}
}

View File

@@ -0,0 +1,204 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.item.property;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.jcr.PathNotFoundException;
import org.alfresco.jcr.item.NodeImpl;
import org.alfresco.jcr.item.PropertyImpl;
import org.alfresco.model.ContentModel;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
import org.alfresco.service.namespace.QNamePattern;
/**
* Responsible for resolving properties on Nodes
*
* @author David Caruana
*/
public class PropertyResolver
{
private static Map<QName, QName> virtualProperties = new HashMap<QName, QName>();
static
{
virtualProperties.put(JCRUUIDProperty.PROPERTY_NAME, null);
virtualProperties.put(JCRPrimaryTypeProperty.PROPERTY_NAME, null);
virtualProperties.put(JCRMixinTypesProperty.PROPERTY_NAME, null);
virtualProperties.put(JCRLockOwnerProperty.PROPERTY_NAME, ContentModel.ASPECT_LOCKABLE);
virtualProperties.put(JCRLockIsDeepProperty.PROPERTY_NAME, ContentModel.ASPECT_LOCKABLE);
// TODO: mix:versionable
}
/**
* Create Property List for all properties of this node
*
* @return list of properties (null properties are filtered)
*/
public static List<PropertyImpl> createProperties(NodeImpl node, QNamePattern pattern)
{
// Create list of properties from node itself
NodeService nodeService = node.getSessionImpl().getRepositoryImpl().getServiceRegistry().getNodeService();
Map<QName, Serializable> properties = nodeService.getProperties(node.getNodeRef());
List<PropertyImpl> propertyList = new ArrayList<PropertyImpl>(properties.size());
for (Map.Entry<QName, Serializable> entry : properties.entrySet())
{
QName propertyName = entry.getKey();
if (pattern == null || pattern.isMatch(propertyName))
{
Serializable value = entry.getValue();
if (value != null)
{
PropertyImpl property = new PropertyImpl(node, propertyName);
propertyList.add(property);
}
}
}
// Add JCR properties
for (Map.Entry<QName, QName> virtualProperty : virtualProperties.entrySet())
{
boolean addJCRProperty = false;
if (virtualProperty.getValue() == null)
{
addJCRProperty = true;
}
else
{
addJCRProperty = nodeService.hasAspect(node.getNodeRef(), virtualProperty.getValue());
}
if (addJCRProperty && (pattern == null || pattern.isMatch(virtualProperty.getKey())))
{
propertyList.add(createVirtualProperty(node, virtualProperty.getKey()));
}
}
return propertyList;
}
/**
* Create property for the given named property
*
* @param node
* @param propertyName
* @return
* @throws PathNotFoundException
*/
public static PropertyImpl createProperty(NodeImpl node, QName propertyName)
throws PathNotFoundException
{
// has a JCR property been requested that is not persisted in Alfresco repository?
if (hasVirtualProperty(node, propertyName))
{
return createVirtualProperty(node, propertyName);
}
// has a property been requested that actually exists?
NodeService nodeService = node.getSessionImpl().getRepositoryImpl().getServiceRegistry().getNodeService();
Serializable value = nodeService.getProperty(node.getNodeRef(), propertyName);
if (value == null)
{
throw new PathNotFoundException("Property path " + propertyName + " not found from node " + node.getNodeRef());
}
// construct property wrapper
PropertyImpl propertyImpl = new PropertyImpl(node, propertyName);
return propertyImpl;
}
private static PropertyImpl createVirtualProperty(NodeImpl node, QName propertyName)
{
if (propertyName.equals(JCRUUIDProperty.PROPERTY_NAME))
{
return new JCRUUIDProperty(node);
}
if (propertyName.equals(JCRPrimaryTypeProperty.PROPERTY_NAME))
{
return new JCRPrimaryTypeProperty(node);
}
if (propertyName.equals(JCRMixinTypesProperty.PROPERTY_NAME))
{
return new JCRMixinTypesProperty(node);
}
if (propertyName.equals(JCRLockOwnerProperty.PROPERTY_NAME))
{
return new JCRLockOwnerProperty(node);
}
if (propertyName.equals(JCRLockIsDeepProperty.PROPERTY_NAME))
{
return new JCRLockIsDeepProperty(node);
}
return null;
}
/**
* Check for existence of Property on specified Node
*
* @param node
* @param propertyName
* @return
*/
public static boolean hasProperty(NodeImpl node, QName propertyName)
{
if (hasVirtualProperty(node, propertyName))
{
return true;
}
NodeService nodeService = node.getSessionImpl().getRepositoryImpl().getServiceRegistry().getNodeService();
Serializable value = nodeService.getProperty(node.getNodeRef(), propertyName);
return value != null;
}
private static boolean hasVirtualProperty(NodeImpl node, QName propertyName)
{
// is this a virtual property
if (virtualProperties.containsKey(propertyName))
{
// is this a virtual property attached to a specific aspect
QName aspect = virtualProperties.get(propertyName);
if (aspect == null)
{
// it's supported on all types
return true;
}
// is the aspect attached to the node
NodeService nodeService = node.getSessionImpl().getRepositoryImpl().getServiceRegistry().getNodeService();
return nodeService.hasAspect(node.getNodeRef(), aspect);
}
// no, it's not even a virtual property
return false;
}
}

View File

@@ -0,0 +1,170 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.query;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.jcr.NodeIterator;
import javax.jcr.RepositoryException;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.PropertyDefinition;
import javax.jcr.query.Query;
import javax.jcr.query.QueryResult;
import javax.jcr.query.RowIterator;
import org.alfresco.jcr.item.NodeRefNodeIteratorImpl;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.jcr.util.JCRProxyFactory;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
/**
* Query Result based a NodeRef List
*
* @author David Caruana
*/
public class NodeRefListQueryResultImpl implements QueryResult
{
/** Session */
private SessionImpl session;
/** The node refs in the result set */
private List<NodeRef> nodeRefs;
/** Node Service */
private NodeService nodeService;
/** Column Names */
private Map<QName, PropertyDefinition> columns = null;
/** Proxy */
private QueryResult proxy = null;
/**
* Construct
*
* @param nodeRefs list of node references
*/
public NodeRefListQueryResultImpl(SessionImpl session, List<NodeRef> nodeRefs)
{
this.session = session;
this.nodeRefs = nodeRefs;
this.nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
}
/**
* Get proxied JCR Query Result
*
* @return proxy
*/
public QueryResult getProxy()
{
if (proxy == null)
{
proxy = (QueryResult)JCRProxyFactory.create(this, QueryResult.class, session);
}
return proxy;
}
/* (non-Javadoc)
* @see javax.jcr.query.QueryResult#getColumnNames()
*/
public String[] getColumnNames() throws RepositoryException
{
Map<QName, PropertyDefinition> columns = getColumnDefinitions();
String[] names = new String[columns.size()];
int i = 0;
for (QName columnName : columns.keySet())
{
names[i++] = columnName.toPrefixString(session.getNamespaceResolver());
}
return names;
}
/* (non-Javadoc)
* @see javax.jcr.query.QueryResult#getRows()
*/
public RowIterator getRows() throws RepositoryException
{
return new NodeRefRowIteratorImpl(session, getColumnDefinitions(), nodeRefs).getProxy();
}
/* (non-Javadoc)
* @see javax.jcr.query.QueryResult#getNodes()
*/
public NodeIterator getNodes() throws RepositoryException
{
return new NodeRefNodeIteratorImpl(session, nodeRefs);
}
/**
* Get list of column definitions
*
* @return list of column definitions
*/
private Map<QName, PropertyDefinition> getColumnDefinitions()
throws RepositoryException
{
if (columns == null)
{
columns = new HashMap<QName, PropertyDefinition>();
// build list of column names from result set
if (nodeRefs.size() > 0)
{
// Base column list on first node ref
// TODO: determine on a more formal basis
QName type = nodeService.getType(nodeRefs.get(0));
NodeType nodeType = session.getTypeManager().getNodeType(type.toPrefixString(session.getNamespaceResolver()));
PropertyDefinition[] propDefs = nodeType.getPropertyDefinitions();
for (PropertyDefinition propDef : propDefs)
{
if (!propDef.isMultiple())
{
columns.put(QName.createQName(propDef.getName(), session.getNamespaceResolver()), propDef);
}
}
Set<QName>aspects = nodeService.getAspects(nodeRefs.get(0));
for (QName aspect : aspects)
{
NodeType nodeAspect = session.getTypeManager().getNodeType(aspect.toPrefixString(session.getNamespaceResolver()));
propDefs = nodeAspect.getPropertyDefinitions();
for (PropertyDefinition propDef : propDefs)
{
if (!propDef.isMultiple())
{
columns.put(QName.createQName(propDef.getName(), session.getNamespaceResolver()), propDef);
}
}
}
}
// add JCR required columns
columns.put(QueryManagerImpl.JCRPATH_COLUMN, null);
columns.put(QueryManagerImpl.JCRSCORE_COLUMN, null);
}
return columns;
}
}

View File

@@ -0,0 +1,104 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.query;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import javax.jcr.nodetype.PropertyDefinition;
import javax.jcr.query.Query;
import javax.jcr.query.Row;
import javax.jcr.query.RowIterator;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.jcr.util.AbstractRangeIterator;
import org.alfresco.jcr.util.JCRProxyFactory;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.namespace.QName;
/**
* Row Iterator based on a list of Node References
*
* @author David Caruana
*/
public class NodeRefRowIteratorImpl extends AbstractRangeIterator implements RowIterator
{
private SessionImpl session;
private Map<QName, PropertyDefinition> columns;
private List<NodeRef> nodeRefs;
private RowIterator proxy = null;
/**
* Construct
*
* @param session
* @param columnNames
* @param nodeRefs
*/
public NodeRefRowIteratorImpl(SessionImpl session, Map<QName, PropertyDefinition> columns, List<NodeRef> nodeRefs)
{
this.session = session;
this.columns = columns;
this.nodeRefs = nodeRefs;
}
/**
* Get proxied JCR Query
*
* @return proxy
*/
public RowIterator getProxy()
{
if (proxy == null)
{
proxy = (RowIterator)JCRProxyFactory.create(this, RowIterator.class, session);
}
return proxy;
}
/* (non-Javadoc)
* @see javax.jcr.query.RowIterator#nextRow()
*/
public Row nextRow()
{
long position = skip();
NodeRef nodeRef = nodeRefs.get((int)position);
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
Map<QName, Serializable> properties = nodeService.getProperties(nodeRef);
return new PropertyMapRowImpl(session, columns, nodeRef, properties);
}
/* (non-Javadoc)
* @see javax.jcr.RangeIterator#getSize()
*/
public long getSize()
{
return nodeRefs.size();
}
/* (non-Javadoc)
* @see java.util.Iterator#next()
*/
public Object next()
{
return nextRow();
}
}

View File

@@ -0,0 +1,129 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.query;
import java.io.Serializable;
import java.util.Map;
import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
import javax.jcr.PropertyType;
import javax.jcr.RepositoryException;
import javax.jcr.Value;
import javax.jcr.nodetype.PropertyDefinition;
import javax.jcr.query.Row;
import org.alfresco.jcr.item.NodeImpl;
import org.alfresco.jcr.item.ValueImpl;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.namespace.QName;
/**
* Node Ref based Row
*
* @author David Caruana
*/
public class PropertyMapRowImpl implements Row
{
private SessionImpl session;
private Map<QName, PropertyDefinition> columns;
private NodeRef nodeRef;
private Map<QName, Serializable> properties;
/**
* Construct
*
* @param session
* @param columnNames
* @param properties
*/
public PropertyMapRowImpl(SessionImpl session, Map<QName, PropertyDefinition> columns, NodeRef nodeRef, Map<QName, Serializable> properties)
{
this.session = session;
this.columns = columns;
this.nodeRef = nodeRef;
this.properties = properties;
}
/* (non-Javadoc)
* @see javax.jcr.query.Row#getValues()
*/
public Value[] getValues() throws RepositoryException
{
Value[] values = new Value[columns.size() + 2];
int i = 0;
for (QName propertyName : columns.keySet())
{
values[i++] = createValue(propertyName);
}
return values;
}
/* (non-Javadoc)
* @see javax.jcr.query.Row#getValue(java.lang.String)
*/
public Value getValue(String propertyName) throws ItemNotFoundException, RepositoryException
{
QName propertyQName = QName.createQName(propertyName, session.getNamespaceResolver());
if (!columns.containsKey(propertyQName))
{
throw new ItemNotFoundException("Column " + propertyName + " does not exist");
}
return createValue(propertyQName);
}
/**
* Create a Value for specified property name
*
* @param propertyName
* @return
* @throws RepositoryException
*/
private Value createValue(QName propertyName)
throws RepositoryException
{
Value value = null;
if (propertyName.equals(QueryManagerImpl.JCRPATH_COLUMN))
{
// derive path from node ref
Node node = new NodeImpl(session, nodeRef).getProxy();
value = new ValueImpl(session, PropertyType.STRING, node.getPath());
}
else if (propertyName.equals(QueryManagerImpl.JCRSCORE_COLUMN))
{
// TODO:
// create dummy score
value = new ValueImpl(session, PropertyType.LONG, (long)0);
}
else
{
// create value from node properties
Object objValue = properties.get(propertyName);
if (objValue != null)
{
PropertyDefinition propDef = columns.get(propertyName);
value = new ValueImpl(session, propDef.getRequiredType(), objValue);
}
}
return value;
}
}

View File

@@ -0,0 +1,118 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.query;
import javax.jcr.ItemExistsException;
import javax.jcr.ItemNotFoundException;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.lock.LockException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.query.InvalidQueryException;
import javax.jcr.query.Query;
import javax.jcr.version.VersionException;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.jcr.util.JCRProxyFactory;
/**
* Alfresco implementation of JCR Query
*
* @author David Caruana
*/
public abstract class QueryImpl implements Query
{
/** Session */
private SessionImpl session;
/** Query Statement */
private String statement;
/** Proxy */
private Query proxy = null;
/**
* Construct
*
* @param statement query language
*/
public QueryImpl(SessionImpl session, String statement)
{
this.session = session;
this.statement = statement;
}
/**
* Get proxied JCR Query
*
* @return proxy
*/
public Query getProxy()
{
if (proxy == null)
{
proxy = (Query)JCRProxyFactory.create(this, Query.class, session);
}
return proxy;
}
/**
* Get Session
*
* @return session
*/
public SessionImpl getSession()
{
return session;
}
/**
* Is the statement valid?
*
* @throws InvalidQueryException
*/
public abstract void isValidStatement() throws InvalidQueryException;
/* (non-Javadoc)
* @see javax.jcr.query.Query#getStatement()
*/
public String getStatement()
{
return statement;
}
/* (non-Javadoc)
* @see javax.jcr.query.Query#getStoredQueryPath()
*/
public String getStoredQueryPath() throws ItemNotFoundException, RepositoryException
{
throw new ItemNotFoundException("This query has not been saved to the Repository");
}
/* (non-Javadoc)
* @see javax.jcr.query.Query#storeAsNode(java.lang.String)
*/
public Node storeAsNode(String absPath) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, UnsupportedRepositoryOperationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
}

View File

@@ -0,0 +1,124 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.query;
import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Map;
import javax.jcr.Node;
import javax.jcr.RepositoryException;
import javax.jcr.query.InvalidQueryException;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import org.alfresco.jcr.dictionary.JCRNamespace;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.service.namespace.QName;
/**
* Alfresco implementation of JCR Query Manager
*
* @author David Caruana
*/
public class QueryManagerImpl implements QueryManager
{
public static QName JCRPATH_COLUMN = QName.createQName(JCRNamespace.JCR_URI, "path");
public static QName JCRSCORE_COLUMN = QName.createQName(JCRNamespace.JCR_URI, "score");
/** supported query languages */
private static Map<String, Class<? extends QueryImpl>> supportedLanguages = new HashMap<String, Class<? extends QueryImpl>>();
static
{
supportedLanguages.put(Query.XPATH, XPathQueryImpl.class);
}
private SessionImpl session;
/**
* Construct
*
* @param session session
*/
public QueryManagerImpl(SessionImpl session)
{
this.session = session;
}
/* (non-Javadoc)
* @see javax.jcr.query.QueryManager#createQuery(java.lang.String, java.lang.String)
*/
public Query createQuery(String statement, String language) throws InvalidQueryException, RepositoryException
{
// is the language known?
if (!isSupportedLanguage(language))
{
throw new InvalidQueryException("Query language " + language + " is not supported");
}
// construct the query
Class<? extends QueryImpl> queryClass = supportedLanguages.get(language);
try
{
Constructor<? extends QueryImpl> constructor = queryClass.getConstructor(new Class[] { SessionImpl.class, String.class } );
QueryImpl queryImpl = constructor.newInstance(new Object[] { session, statement } );
queryImpl.isValidStatement();
return queryImpl.getProxy();
}
catch (InstantiationException e)
{
throw new RepositoryException("Failed to create query " + statement + " (language: " + language + ")");
}
catch (IllegalAccessException e)
{
throw new RepositoryException("Failed to create query " + statement + " (language: " + language + ")");
}
catch (Exception e)
{
throw new RepositoryException("Failed to create query " + statement + " (language: " + language + ")");
}
}
/* (non-Javadoc)
* @see javax.jcr.query.QueryManager#getQuery(javax.jcr.Node)
*/
public Query getQuery(Node node) throws InvalidQueryException, RepositoryException
{
throw new InvalidQueryException("Persistent queries are not supported by the Repository.");
}
/* (non-Javadoc)
* @see javax.jcr.query.QueryManager#getSupportedQueryLanguages()
*/
public String[] getSupportedQueryLanguages() throws RepositoryException
{
return supportedLanguages.keySet().toArray(new String[supportedLanguages.size()]);
}
/**
* Is supported language?
*
* @param language language to check
* @return true => supported
*/
private boolean isSupportedLanguage(String language)
{
return supportedLanguages.containsKey(language);
}
}

View File

@@ -0,0 +1,87 @@
package org.alfresco.jcr.query;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.Property;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import javax.jcr.Value;
import javax.jcr.query.Query;
import javax.jcr.query.QueryManager;
import javax.jcr.query.QueryResult;
import javax.jcr.query.Row;
import javax.jcr.query.RowIterator;
import org.alfresco.jcr.test.BaseJCRTest;
public class QueryManagerImplTest extends BaseJCRTest
{
protected Session superuserSession;
@Override
protected void setUp() throws Exception
{
super.setUp();
SimpleCredentials superuser = new SimpleCredentials("superuser", "".toCharArray());
superuserSession = repository.login(superuser, getWorkspace());
}
@Override
protected void tearDown() throws Exception
{
superuserSession.logout();
super.tearDown();
}
public void testQuery()
throws Exception
{
QueryManager queryMgr = superuserSession.getWorkspace().getQueryManager();
String[] languages = queryMgr.getSupportedQueryLanguages();
assertEquals(1, languages.length);
assertEquals(Query.XPATH, languages[0]);
Query query = queryMgr.createQuery("//*", Query.XPATH);
QueryResult result = query.execute();
String[] columnNames = result.getColumnNames();
// iterate via row iterator
int rowCnt = 0;
RowIterator rowIterator = result.getRows();
while(rowIterator.hasNext())
{
Row row = rowIterator.nextRow();
for (String columnName : columnNames)
{
Value value = row.getValue(columnName);
if (value != null)
{
String strValue = value.getString();
assertNotNull(strValue);
}
}
rowCnt++;
}
// iterate via node iterator
int nodeCnt = 0;
NodeIterator nodeIterator = result.getNodes();
while(nodeIterator.hasNext())
{
Node node = nodeIterator.nextNode();
Property property = node.getProperty("sys:node-uuid");
Value value = property.getValue();
String uuid = value.getString();
assertNotNull(uuid);
nodeCnt++;
}
// check same number of items returned from each iterator
assertEquals(rowCnt, nodeCnt);
}
}

View File

@@ -0,0 +1,76 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.query;
import java.util.List;
import javax.jcr.RepositoryException;
import javax.jcr.query.InvalidQueryException;
import javax.jcr.query.Query;
import javax.jcr.query.QueryResult;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.search.SearchService;
/**
* Alfresco implementation of XPath Query
*
* @author David Caruana
*/
public class XPathQueryImpl extends QueryImpl
{
/**
* Construct
*
* @param statement the xpath statement
*/
public XPathQueryImpl(SessionImpl session, String statement)
{
super(session, statement);
}
@Override
public void isValidStatement() throws InvalidQueryException
{
// TODO
}
/* (non-Javadoc)
* @see javax.jcr.query.Query#execute()
*/
public QueryResult execute() throws RepositoryException
{
SearchService search = getSession().getRepositoryImpl().getServiceRegistry().getSearchService();
NodeService nodes = getSession().getRepositoryImpl().getServiceRegistry().getNodeService();
NodeRef root = nodes.getRootNode(getSession().getWorkspaceStore());
List<NodeRef> nodeRefs = search.selectNodes(root, getStatement(), null, getSession().getNamespaceResolver(), false, SearchService.LANGUAGE_JCR_XPATH);
return new NodeRefListQueryResultImpl(getSession(), nodeRefs).getProxy();
}
/* (non-Javadoc)
* @see javax.jcr.query.Query#getLanguage()
*/
public String getLanguage()
{
return Query.XPATH;
}
}

View File

@@ -0,0 +1,29 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.repository;
/**
* Factory settings for entry-point Repository implementation
*
* @author David Caruana
*/
public class RepositoryFactory
{
public final static String APPLICATION_CONTEXT = "classpath:alfresco/jcr-context.xml";
public final static String REPOSITORY_BEAN = "JCR.Repository";
}

View File

@@ -0,0 +1,310 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.repository;
import java.util.HashMap;
import java.util.Map;
import javax.jcr.Credentials;
import javax.jcr.LoginException;
import javax.jcr.NoSuchWorkspaceException;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.jcr.dictionary.NamespaceRegistryImpl;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.repo.importer.ImporterComponent;
import org.alfresco.repo.security.authentication.AuthenticationException;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.security.AuthenticationService;
import org.alfresco.service.descriptor.Descriptor;
import org.alfresco.service.descriptor.DescriptorService;
/**
* Alfresco implementation of a JCR Repository
*
* @author David Caruana
*/
public class RepositoryImpl implements Repository
{
/** Empty Password, if not supplied */
private final static char[] EMPTY_PASSWORD = "".toCharArray();
/** Repository Descriptors */
private static final Map<String, String> descriptors = new HashMap<String, String>();
/** Thread Local Session */
// Note: For now, we're only allowing one active (i.e. logged in) Session per-thread
private static ThreadLocal<SessionImpl> sessions = new ThreadLocal<SessionImpl>();
// Service dependencies
private ServiceRegistry serviceRegistry;
private ImporterComponent importerComponent;
private String defaultWorkspace = null;
// Services
private NamespaceRegistryImpl namespaceRegistry = null;
//
// Dependency Injection
//
/**
* Set the service registry
*
* @param serviceRegistry
*/
public void setServiceRegistry(ServiceRegistry serviceRegistry)
{
this.serviceRegistry = serviceRegistry;
}
/**
* Set the Importer Component
*
* @param importerComponent
*/
public void setImporterComponent(ImporterComponent importerComponent)
{
this.importerComponent = importerComponent;
}
/**
* Sets the Default Workspace
*
* @param defaultWorkspace default workspace
*/
public void setDefaultWorkspace(String defaultWorkspace)
{
this.defaultWorkspace = defaultWorkspace;
}
/**
* Initialisation
*/
public void init()
{
if (serviceRegistry == null)
{
throw new IllegalStateException("Service Registry has not been specified.");
}
// initialise namespace registry
namespaceRegistry = new NamespaceRegistryImpl(false, serviceRegistry.getNamespaceService());
// initialise descriptors
DescriptorService descriptorService = serviceRegistry.getDescriptorService();
Descriptor descriptor = descriptorService.getServerDescriptor();
String repNameDesc = "Alfresco Content Repository";
String edition = descriptor.getEdition();
if (edition != null && edition.length() > 0)
{
repNameDesc += " (" + edition + ")";
}
String repVersion = descriptor.getVersion();
descriptors.put(Repository.REP_NAME_DESC, repNameDesc);
descriptors.put(Repository.REP_VENDOR_DESC, "Alfresco");
descriptors.put(Repository.REP_VENDOR_URL_DESC, "http://www.alfresco.org");
descriptors.put(Repository.REP_VERSION_DESC, repVersion);
descriptors.put(Repository.SPEC_NAME_DESC, "Content Repository API for Java(TM) Technology Specification");
descriptors.put(Repository.SPEC_VERSION_DESC, "1.0");
descriptors.put(Repository.LEVEL_1_SUPPORTED, "true");
descriptors.put(Repository.LEVEL_2_SUPPORTED, "true");
descriptors.put(Repository.OPTION_TRANSACTIONS_SUPPORTED, "true");
descriptors.put(Repository.QUERY_XPATH_DOC_ORDER, "true");
descriptors.put(Repository.QUERY_XPATH_POS_INDEX, "true");
}
/**
* Get the service registry
*
* @return the service registry
*/
public ServiceRegistry getServiceRegistry()
{
return serviceRegistry;
}
/**
* Get the importer component
*
* @return the importer component
*/
public ImporterComponent getImporterComponent()
{
return importerComponent;
}
/**
* Get the Namespace Registry
*/
public NamespaceRegistryImpl getNamespaceRegistry()
{
return namespaceRegistry;
}
/* (non-Javadoc)
* @see javax.jcr.Repository#getDescriptorKeys()
*/
public String[] getDescriptorKeys()
{
String[] keys = (String[]) descriptors.keySet().toArray(new String[descriptors.keySet().size()]);
return keys;
}
/* (non-Javadoc)
* @see javax.jcr.Repository#getDescriptor(java.lang.String)
*/
public String getDescriptor(String key)
{
return descriptors.get(key);
}
/* (non-Javadoc)
* @see javax.jcr.Repository#login(javax.jcr.Credentials, java.lang.String)
*/
public Session login(Credentials credentials, String workspaceName)
throws LoginException, NoSuchWorkspaceException, RepositoryException
{
// extract username and password
// TODO: determine support for general Credentials
String username = null;
char[] password = EMPTY_PASSWORD;
if (credentials != null && credentials instanceof SimpleCredentials)
{
username = ((SimpleCredentials)credentials).getUserID();
password = ((SimpleCredentials)credentials).getPassword();
}
try
{
// construct the session
SessionImpl sessionImpl = new SessionImpl(this);
registerSession(sessionImpl);
// authenticate user
AuthenticationService authenticationService = getServiceRegistry().getAuthenticationService();
try
{
authenticationService.authenticate(username, password);
}
catch(AuthenticationException e)
{
deregisterSession();
throw new LoginException("Alfresco Repository failed to authenticate credentials", e);
}
// initialise the session
String ticket = authenticationService.getCurrentTicket();
String sessionWorkspace = (workspaceName == null) ? defaultWorkspace : workspaceName;
sessionImpl.init(ticket, sessionWorkspace, getAttributes(credentials));
// session is now ready
Session session = sessionImpl.getProxy();
return session;
}
catch(AlfrescoRuntimeException e)
{
deregisterSession();
throw new RepositoryException(e);
}
}
/* (non-Javadoc)
* @see javax.jcr.Repository#login(javax.jcr.Credentials)
*/
public Session login(Credentials credentials)
throws LoginException, RepositoryException
{
return login(credentials, null);
}
/* (non-Javadoc)
* @see javax.jcr.Repository#login(java.lang.String)
*/
public Session login(String workspaceName)
throws LoginException, NoSuchWorkspaceException, RepositoryException
{
return login(null, workspaceName);
}
/* (non-Javadoc)
* @see javax.jcr.Repository#login()
*/
public Session login()
throws LoginException, RepositoryException
{
return login(null, null);
}
/**
* Get attributes from passed Credentials
*
* @param credentials the credentials to extract attribute from
* @return the attributes
*/
private Map<String, Object> getAttributes(Credentials credentials)
{
Map<String, Object> attributes = null;
if (credentials != null && credentials instanceof SimpleCredentials)
{
SimpleCredentials simpleCredentials = (SimpleCredentials)credentials;
String[] names = simpleCredentials.getAttributeNames();
attributes = new HashMap<String, Object>(names.length);
for (String name : names)
{
attributes.put(name, simpleCredentials.getAttribute(name));
}
}
return attributes;
}
/**
* Register active session
*
* @param session
*/
private void registerSession(SessionImpl session)
throws RepositoryException
{
// only allow one active session
if (sessions.get() != null)
{
throw new RepositoryException("Only one active session is allowed per thread.");
}
// record session in current thread
sessions.set(session);
}
/**
* De-register current active session
*/
public void deregisterSession()
{
// remove session from current thread
sessions.set(null);
}
}

View File

@@ -0,0 +1,127 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.repository;
import javax.jcr.LoginException;
import javax.jcr.NoSuchWorkspaceException;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import org.alfresco.jcr.test.BaseJCRTest;
/**
* Test JCR Repository Implementation
*
* @author David Caruana
*/
public class RepositoryImplTest extends BaseJCRTest
{
public void testDescriptors()
{
String[] keys = repository.getDescriptorKeys();
assertEquals(11, keys.length);
for (String key : keys)
{
String value = repository.getDescriptor(key);
assertNotNull(value);
}
assertNotNull(repository.getDescriptor(Repository.REP_NAME_DESC));
System.out.println(repository.getDescriptor(Repository.REP_NAME_DESC));
assertNotNull(repository.getDescriptor(Repository.REP_VENDOR_DESC));
assertNotNull(repository.getDescriptor(Repository.REP_VENDOR_URL_DESC));
assertNotNull(repository.getDescriptor(Repository.REP_VERSION_DESC));
System.out.println(repository.getDescriptor(Repository.REP_VERSION_DESC));
assertNotNull(repository.getDescriptor(Repository.SPEC_NAME_DESC));
assertNotNull(repository.getDescriptor(Repository.SPEC_VERSION_DESC));
assertEquals("true", repository.getDescriptor(Repository.LEVEL_1_SUPPORTED));
assertEquals("true", repository.getDescriptor(Repository.LEVEL_2_SUPPORTED));
assertEquals("true", repository.getDescriptor(Repository.OPTION_TRANSACTIONS_SUPPORTED));
assertEquals("true", repository.getDescriptor(Repository.QUERY_XPATH_DOC_ORDER));
assertEquals("true", repository.getDescriptor(Repository.QUERY_XPATH_POS_INDEX));
}
public void testBadUsernameLogin() throws Exception
{
SimpleCredentials badUser = new SimpleCredentials("baduser", "".toCharArray());
try
{
repository.login(badUser);
fail("Failed to catch bad username - username should not exist.");
}
catch (LoginException e)
{
}
}
public void testBadPwdLogin() throws Exception
{
SimpleCredentials badPwd = new SimpleCredentials("superuser", "badpwd".toCharArray());
try
{
repository.login(badPwd);
fail("Failed to catch bad password - password is invalid.");
}
catch (LoginException e)
{
}
}
public void testNoCredentialsLogin() throws Exception
{
try
{
repository.login();
fail("Failed to catch no credentials.");
}
catch (LoginException e)
{
}
}
public void testLogin()
throws RepositoryException
{
SimpleCredentials good = new SimpleCredentials("superuser", "".toCharArray());
try
{
Session session = repository.login(good, getWorkspace());
assertNotNull(session);
session.logout();
}
catch (LoginException e)
{
fail("Failed to login.");
}
try
{
Session session = repository.login(good, null);
session.logout();
}
catch (NoSuchWorkspaceException e)
{
fail("Failed to detect default workspace");
}
}
}

View File

@@ -0,0 +1,982 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.session;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.security.AccessControlException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.jcr.AccessDeniedException;
import javax.jcr.Credentials;
import javax.jcr.ImportUUIDBehavior;
import javax.jcr.InvalidItemStateException;
import javax.jcr.InvalidSerializedDataException;
import javax.jcr.Item;
import javax.jcr.ItemExistsException;
import javax.jcr.ItemNotFoundException;
import javax.jcr.LoginException;
import javax.jcr.NamespaceException;
import javax.jcr.NoSuchWorkspaceException;
import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.ValueFactory;
import javax.jcr.Workspace;
import javax.jcr.lock.LockException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.version.VersionException;
import javax.transaction.HeuristicMixedException;
import javax.transaction.HeuristicRollbackException;
import javax.transaction.NotSupportedException;
import javax.transaction.RollbackException;
import javax.transaction.SystemException;
import javax.transaction.UserTransaction;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.jcr.dictionary.JCRNamespacePrefixResolver;
import org.alfresco.jcr.dictionary.NamespaceRegistryImpl;
import org.alfresco.jcr.dictionary.NodeTypeManagerImpl;
import org.alfresco.jcr.exporter.JCRDocumentXMLExporter;
import org.alfresco.jcr.exporter.JCRSystemXMLExporter;
import org.alfresco.jcr.importer.JCRImportHandler;
import org.alfresco.jcr.item.ItemImpl;
import org.alfresco.jcr.item.ItemResolver;
import org.alfresco.jcr.item.JCRPath;
import org.alfresco.jcr.item.JCRTypeConverter;
import org.alfresco.jcr.item.NodeImpl;
import org.alfresco.jcr.item.ValueFactoryImpl;
import org.alfresco.jcr.repository.RepositoryImpl;
import org.alfresco.jcr.util.JCRProxyFactory;
import org.alfresco.repo.importer.ImporterComponent;
import org.alfresco.repo.transaction.AlfrescoTransactionSupport;
import org.alfresco.service.cmr.lock.LockService;
import org.alfresco.service.cmr.lock.LockType;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.AccessStatus;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.view.ExporterCrawlerParameters;
import org.alfresco.service.cmr.view.ExporterService;
import org.alfresco.service.cmr.view.ImporterBinding;
import org.alfresco.service.cmr.view.ImporterException;
import org.alfresco.service.cmr.view.Location;
import org.alfresco.service.namespace.NamespacePrefixResolver;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.ParameterCheck;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;
import org.xml.sax.ContentHandler;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
/**
* Alfresco Implementation of a JCR Session
*
* @author David Caruana
*/
public class SessionImpl implements Session
{
/** Parent Repository */
private RepositoryImpl repository;
/** Transaction Id */
private String trxId;
/** Session Attributes */
private Map<String, Object> attributes;
/** Workspace Store Reference */
private StoreRef workspaceStore;
/** Workspace */
private WorkspaceImpl workspace = null;
/** Type Converter */
private JCRTypeConverter typeConverter = null;
/** Session based Namespace Resolver */
private NamespaceRegistryImpl namespaceResolver;
/** Type Manager */
private NodeTypeManagerImpl typeManager = null;
/** Value Factory */
private ValueFactoryImpl valueFactory = null;
/** Session Proxy */
private Session proxy = null;
/** Session Isolation Strategy */
private SessionIsolation sessionIsolation = null;
/** Authenticated ticket */
private String ticket = null;
/**
* Construct
*
* @param repository parent repository
* @throws NoSuchWorkspaceException
*/
public SessionImpl(RepositoryImpl repository)
{
// intialise session
this.repository = repository;
this.typeConverter = new JCRTypeConverter(this);
this.namespaceResolver = new NamespaceRegistryImpl(true, new JCRNamespacePrefixResolver(repository.getServiceRegistry().getNamespaceService()));
this.typeManager = new NodeTypeManagerImpl(this, namespaceResolver.getNamespaceService());
this.valueFactory = new ValueFactoryImpl(this);
}
/**
* Initialise Session
*
* @param ticket authentication ticket
* @param workspaceName workspace name
* @param attributes session attributes
* @throws RepositoryException
*/
public void init(String ticket, String workspaceName, Map<String, Object> attributes)
throws RepositoryException
{
// create appropriate strategy for handling session isolation
// TODO: Support full session isolation as described in the JCR specification
String trxId = AlfrescoTransactionSupport.getTransactionId();
sessionIsolation = (trxId == null) ? new InnerTransaction() : new OuterTransaction();
sessionIsolation.begin();
// initialise the session
this.ticket = ticket;
this.attributes = (attributes == null) ? new HashMap<String, Object>() : attributes;
this.workspaceStore = getWorkspaceStore(workspaceName);
}
/**
* Create proxied Session
*
* @return JCR Session
*/
public Session getProxy()
{
if (proxy == null)
{
proxy = (Session)JCRProxyFactory.create(this, Session.class, this);
}
return proxy;
}
/**
* Get the Repository Impl
*
* @return repository impl
*/
public RepositoryImpl getRepositoryImpl()
{
return repository;
}
/**
* Get the session Ticket
*
* @return ticket
*/
public String getTicket()
{
return ticket;
}
/**
* Get the associated transaction Id
*
* @return transaction id
*/
public String getTransactionId()
{
return trxId;
}
/**
* Get the Type Converter
*
* @return the type converter
*/
public JCRTypeConverter getTypeConverter()
{
return typeConverter;
}
/**
* Get the Type Manager
*
* @return the type manager
*/
public NodeTypeManagerImpl getTypeManager()
{
return typeManager;
}
/**
* Get the Namespace Resolver
*
* @return the session based Namespace Resolver
*/
public NamespacePrefixResolver getNamespaceResolver()
{
return namespaceResolver.getNamespaceService();
}
/**
* Get the Workspace Store
*
* @return the workspace store reference
*/
public StoreRef getWorkspaceStore()
{
return workspaceStore;
}
//
// JCR Session
//
/* (non-Javadoc)
* @see javax.jcr.Session#getRepository()
*/
public Repository getRepository()
{
return repository;
}
/* (non-Javadoc)
* @see javax.jcr.Session#getUserID()
*/
public String getUserID()
{
return getRepositoryImpl().getServiceRegistry().getAuthenticationService().getCurrentUserName();
}
/* (non-Javadoc)
* @see javax.jcr.Session#getAttribute(java.lang.String)
*/
public Object getAttribute(String name)
{
return attributes.get(name);
}
/* (non-Javadoc)
* @see javax.jcr.Session#getAttributeNames()
*/
public String[] getAttributeNames()
{
String[] names = (String[]) attributes.keySet().toArray(new String[attributes.keySet().size()]);
return names;
}
/* (non-Javadoc)
* @see javax.jcr.Session#getWorkspace()
*/
public Workspace getWorkspace()
{
if (workspace == null)
{
workspace = new WorkspaceImpl(this);
}
return workspace.getProxy();
}
/* (non-Javadoc)
* @see javax.jcr.Session#impersonate(javax.jcr.Credentials)
*/
public Session impersonate(Credentials credentials) throws LoginException, RepositoryException
{
// TODO: Implement when impersonation permission added to Alfresco Repository
throw new LoginException("Insufficient permission to impersonate");
}
/* (non-Javadoc)
* @see javax.jcr.Session#getRootNode()
*/
public Node getRootNode() throws RepositoryException
{
NodeRef nodeRef = getRepositoryImpl().getServiceRegistry().getNodeService().getRootNode(workspaceStore);
NodeImpl nodeImpl = new NodeImpl(this, nodeRef);
return nodeImpl.getProxy();
}
/* (non-Javadoc)
* @see javax.jcr.Session#getNodeByUUID(java.lang.String)
*/
public Node getNodeByUUID(String uuid) throws ItemNotFoundException, RepositoryException
{
NodeRef nodeRef = new NodeRef(workspaceStore, uuid);
boolean exists = getRepositoryImpl().getServiceRegistry().getNodeService().exists(nodeRef);
if (exists == false)
{
throw new ItemNotFoundException();
}
NodeImpl nodeImpl = new NodeImpl(this, nodeRef);
return nodeImpl.getProxy();
}
/* (non-Javadoc)
* @see javax.jcr.Session#getItem(java.lang.String)
*/
public Item getItem(String absPath) throws PathNotFoundException, RepositoryException
{
NodeRef nodeRef = getRepositoryImpl().getServiceRegistry().getNodeService().getRootNode(workspaceStore);
ItemImpl itemImpl = ItemResolver.findItem(this, nodeRef, absPath);
return itemImpl.getProxy();
}
/* (non-Javadoc)
* @see javax.jcr.Session#itemExists(java.lang.String)
*/
public boolean itemExists(String absPath) throws RepositoryException
{
ParameterCheck.mandatoryString("absPath", absPath);
NodeRef nodeRef = getRepositoryImpl().getServiceRegistry().getNodeService().getRootNode(workspaceStore);
return ItemResolver.itemExists(this, nodeRef, absPath);
}
/* (non-Javadoc)
* @see javax.jcr.Session#move(java.lang.String, java.lang.String)
*/
public void move(String srcAbsPath, String destAbsPath) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, RepositoryException
{
ParameterCheck.mandatoryString("srcAbsPath", srcAbsPath);
ParameterCheck.mandatoryString("destAbsPath", destAbsPath);
// Find source node
NodeService nodeService = getRepositoryImpl().getServiceRegistry().getNodeService();
NodeRef rootRef = nodeService.getRootNode(workspaceStore);
NodeRef sourceRef = ItemResolver.getNodeRef(this, rootRef, srcAbsPath);
if (sourceRef == null)
{
throw new PathNotFoundException("Source path " + srcAbsPath + " cannot be found.");
}
// Find dest node
NodeRef destRef = null;
QName destName = null;
Path destPath = new JCRPath(getNamespaceResolver(), destAbsPath).getPath();
if (destPath.size() == 1)
{
destRef = rootRef;
destName = ((JCRPath.SimpleElement)destPath.get(0)).getQName();
}
else
{
Path destParentPath = destPath.subPath(destPath.size() -2);
destRef = ItemResolver.getNodeRef(this, rootRef, destParentPath.toPrefixString(getNamespaceResolver()));
if (destRef == null)
{
throw new PathNotFoundException("Destination path " + destParentPath + " cannot be found.");
}
destName = ((JCRPath.SimpleElement)destPath.get(destPath.size() -1)).getQName();
}
// Validate name
// TODO: Replace with proper name validation
if (destName.getLocalName().indexOf('[') != -1 || destName.getLocalName().indexOf(']') != -1)
{
throw new RepositoryException("Node name '" + destName + "' is invalid");
}
// Determine child association type for destination
ChildAssociationRef childAssocRef = nodeService.getPrimaryParent(sourceRef);
// Move node
nodeService.moveNode(sourceRef, destRef, childAssocRef.getTypeQName(), destName);
}
/* (non-Javadoc)
* @see javax.jcr.Session#save()
*/
public void save() throws AccessDeniedException, ItemExistsException, ConstraintViolationException, InvalidItemStateException, VersionException, LockException, NoSuchNodeTypeException, RepositoryException
{
sessionIsolation.commit();
// Note: start a new transaction for subsequent session changes
sessionIsolation.begin();
}
/* (non-Javadoc)
* @see javax.jcr.Session#refresh(boolean)
*/
public void refresh(boolean keepChanges) throws RepositoryException
{
if (keepChanges)
{
throw new UnsupportedRepositoryOperationException("Keep changes is not supported.");
}
sessionIsolation.rollback();
// Note: start a new transaction for subsequent session changes
sessionIsolation.begin();
}
/* (non-Javadoc)
* @see javax.jcr.Session#hasPendingChanges()
*/
public boolean hasPendingChanges() throws RepositoryException
{
return AlfrescoTransactionSupport.isDirty();
}
/* (non-Javadoc)
* @see javax.jcr.Session#getValueFactory()
*/
public ValueFactory getValueFactory() throws UnsupportedRepositoryOperationException, RepositoryException
{
return valueFactory.getProxy();
}
/* (non-Javadoc)
* @see javax.jcr.Session#checkPermission(java.lang.String, java.lang.String)
*/
public void checkPermission(String absPath, String actions) throws AccessControlException, RepositoryException
{
// locate noderef for path
NodeService nodeService = getRepositoryImpl().getServiceRegistry().getNodeService();
NodeRef rootRef = nodeService.getRootNode(getWorkspaceStore());
NodeRef nodeRef = ItemResolver.getNodeRef(this, rootRef, absPath);
if (nodeRef == null)
{
throw new AccessControlException("Unable to determine access control for path " + absPath);
}
// test each of the actions specified
PermissionService permissionService = getRepositoryImpl().getServiceRegistry().getPermissionService();
String[] checkActions = actions.split(",");
for (String checkAction : checkActions)
{
checkAction = checkAction.trim();
AccessStatus accessStatus = null;
if (checkAction.equals("add_node"))
{
accessStatus = permissionService.hasPermission(nodeRef, PermissionService.ADD_CHILDREN);
}
else if (checkAction.equals("set_property"))
{
accessStatus = permissionService.hasPermission(nodeRef, PermissionService.WRITE_PROPERTIES);
}
else if (checkAction.equals("remove"))
{
accessStatus = permissionService.hasPermission(nodeRef, PermissionService.DELETE);
}
else if (checkAction.equals("read"))
{
accessStatus = permissionService.hasPermission(nodeRef, PermissionService.READ);
}
else
{
// fall-through check for alfresco specific permissions
accessStatus = permissionService.hasPermission(nodeRef, checkAction);
}
// abort if permission not granted
if (accessStatus == AccessStatus.DENIED)
{
throw new AccessControlException("Permission " + checkAction + " not granted on path " + absPath);
}
}
}
/* (non-Javadoc)
* @see javax.jcr.Session#getImportContentHandler(java.lang.String, int)
*/
public ContentHandler getImportContentHandler(String parentAbsPath, int uuidBehavior) throws PathNotFoundException, ConstraintViolationException, VersionException, LockException, RepositoryException
{
// locate noderef for path
NodeService nodeService = getRepositoryImpl().getServiceRegistry().getNodeService();
NodeRef rootRef = nodeService.getRootNode(getWorkspaceStore());
NodeRef nodeRef = ItemResolver.getNodeRef(this, rootRef, parentAbsPath);
if (nodeRef == null)
{
throw new PathNotFoundException("Parent path " + parentAbsPath + " does not exist.");
}
// create content handler for import
JCRImportHandler jcrImportHandler = new JCRImportHandler(this);
ImporterComponent importerComponent = getRepositoryImpl().getImporterComponent();
return importerComponent.handlerImport(nodeRef, null, jcrImportHandler, new JCRImportBinding(uuidBehavior), null);
}
/* (non-Javadoc)
* @see javax.jcr.Session#importXML(java.lang.String, java.io.InputStream, int)
*/
public void importXML(String parentAbsPath, InputStream in, int uuidBehavior) throws IOException, PathNotFoundException, ItemExistsException, ConstraintViolationException, VersionException, InvalidSerializedDataException, LockException, RepositoryException
{
ContentHandler handler = getImportContentHandler(parentAbsPath, uuidBehavior);
try
{
XMLReader parser = XMLReaderFactory.createXMLReader();
parser.setContentHandler(handler);
parser.setFeature("http://xml.org/sax/features/namespaces", true);
parser.setFeature("http://xml.org/sax/features/namespace-prefixes", false);
parser.parse(new InputSource(in));
}
catch (SAXException se)
{
// check for wrapped repository exception
Exception e = se.getException();
if (e != null && e instanceof AlfrescoRuntimeException)
{
throw (AlfrescoRuntimeException) e;
}
else
{
throw new InvalidSerializedDataException("Failed to import provided xml stream", se);
}
}
}
/* (non-Javadoc)
* @see javax.jcr.Session#exportSystemView(java.lang.String, org.xml.sax.ContentHandler, boolean, boolean)
*/
public void exportSystemView(String absPath, ContentHandler contentHandler, boolean skipBinary, boolean noRecurse) throws PathNotFoundException, SAXException, RepositoryException
{
JCRSystemXMLExporter exporter = new JCRSystemXMLExporter(this, contentHandler);
ExporterCrawlerParameters parameters = createExportParameters(absPath, skipBinary, noRecurse);
ExporterService exporterService = getRepositoryImpl().getServiceRegistry().getExporterService();
exporterService.exportView(exporter, parameters, null);
}
/* (non-Javadoc)
* @see javax.jcr.Session#exportSystemView(java.lang.String, java.io.OutputStream, boolean, boolean)
*/
public void exportSystemView(String absPath, OutputStream out, boolean skipBinary, boolean noRecurse) throws IOException, PathNotFoundException, RepositoryException
{
JCRSystemXMLExporter exporter = new JCRSystemXMLExporter(this, createExportContentHandler(out));
ExporterCrawlerParameters parameters = createExportParameters(absPath, skipBinary, noRecurse);
ExporterService exporterService = getRepositoryImpl().getServiceRegistry().getExporterService();
exporterService.exportView(exporter, parameters, null);
}
/* (non-Javadoc)
* @see javax.jcr.Session#exportDocumentView(java.lang.String, org.xml.sax.ContentHandler, boolean, boolean)
*/
public void exportDocumentView(String absPath, ContentHandler contentHandler, boolean skipBinary, boolean noRecurse) throws PathNotFoundException, SAXException, RepositoryException
{
JCRDocumentXMLExporter exporter = new JCRDocumentXMLExporter(this, contentHandler);
ExporterCrawlerParameters parameters = createExportParameters(absPath, skipBinary, noRecurse);
ExporterService exporterService = getRepositoryImpl().getServiceRegistry().getExporterService();
exporterService.exportView(exporter, parameters, null);
}
/* (non-Javadoc)
* @see javax.jcr.Session#exportDocumentView(java.lang.String, java.io.OutputStream, boolean, boolean)
*/
public void exportDocumentView(String absPath, OutputStream out, boolean skipBinary, boolean noRecurse) throws IOException, PathNotFoundException, RepositoryException
{
JCRDocumentXMLExporter exporter = new JCRDocumentXMLExporter(this, createExportContentHandler(out));
ExporterCrawlerParameters parameters = createExportParameters(absPath, skipBinary, noRecurse);
ExporterService exporterService = getRepositoryImpl().getServiceRegistry().getExporterService();
exporterService.exportView(exporter, parameters, null);
}
/* (non-Javadoc)
* @see javax.jcr.Session#setNamespacePrefix(java.lang.String, java.lang.String)
*/
public void setNamespacePrefix(String prefix, String uri) throws NamespaceException, RepositoryException
{
namespaceResolver.registerNamespace(prefix, uri);
}
/* (non-Javadoc)
* @see javax.jcr.Session#getNamespacePrefixes()
*/
public String[] getNamespacePrefixes() throws RepositoryException
{
return namespaceResolver.getPrefixes();
}
/* (non-Javadoc)
* @see javax.jcr.Session#getNamespaceURI(java.lang.String)
*/
public String getNamespaceURI(String prefix) throws NamespaceException, RepositoryException
{
return namespaceResolver.getURI(prefix);
}
/* (non-Javadoc)
* @see javax.jcr.Session#getNamespacePrefix(java.lang.String)
*/
public String getNamespacePrefix(String uri) throws NamespaceException, RepositoryException
{
return namespaceResolver.getPrefix(uri);
}
/* (non-Javadoc)
* @see javax.jcr.Session#logout()
*/
public void logout()
{
if (isLive())
{
// invalidate authentication
getRepositoryImpl().getServiceRegistry().getAuthenticationService().invalidateTicket(getTicket());
ticket = null;
// clean up resources
try
{
sessionIsolation.rollback();
}
catch(RepositoryException e)
{
// force logout
}
repository.deregisterSession();
}
}
/* (non-Javadoc)
* @see javax.jcr.Session#isLive()
*/
public boolean isLive()
{
return ticket != null;
}
/* (non-Javadoc)
* @see javax.jcr.Session#addLockToken(java.lang.String)
*/
public void addLockToken(String lt)
{
// TODO: UnsupportedRepositoryOperationException
}
/* (non-Javadoc)
* @see javax.jcr.Session#getLockTokens()
*/
public String[] getLockTokens()
{
LockService lockService = getRepositoryImpl().getServiceRegistry().getLockService();
List<NodeRef> nodeRefs = lockService.getLocks(getWorkspaceStore(), LockType.WRITE_LOCK);
String[] tokens = new String[nodeRefs.size()];
int i = 0;
for (NodeRef nodeRef : nodeRefs)
{
tokens[i++] = nodeRef.toString();
}
return tokens;
}
/* (non-Javadoc)
* @see javax.jcr.Session#removeLockToken(java.lang.String)
*/
public void removeLockToken(String lt)
{
// TODO: UnsupportedRepositoryOperationException
}
/**
* Gets the workspace store reference for the given workspace name
*
* @param workspaceName the workspace name
* @return the store reference
* @throws NoSuchWorkspaceException
*/
private StoreRef getWorkspaceStore(String workspaceName)
throws NoSuchWorkspaceException
{
if (workspaceName == null)
{
// TODO: Provide a default "Null Workspace" as per JCR specification
throw new NoSuchWorkspaceException("A default workspace could not be established.");
}
StoreRef workspace = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, workspaceName);
NodeService nodeService = getRepositoryImpl().getServiceRegistry().getNodeService();
boolean exists = false;
try
{
exists = nodeService.exists(workspace);
}
catch(org.alfresco.repo.security.permissions.AccessDeniedException e)
{
// note: fallthrough - store does not exist
}
if (!exists)
{
throw new NoSuchWorkspaceException("Workspace " + workspaceName + " does not exist.");
}
return workspace;
}
/**
* Create a Content Handler that outputs to the specified output stream.
*
* @param output stream the output stream to write to
* @return the content handler
*/
private ContentHandler createExportContentHandler(OutputStream output)
throws RepositoryException
{
// Define output format
OutputFormat format = OutputFormat.createPrettyPrint();
format.setNewLineAfterDeclaration(false);
format.setIndentSize(2);
format.setEncoding("UTF-8");
// Construct an XML Writer
try
{
return new XMLWriter(output, format);
}
catch (UnsupportedEncodingException e)
{
throw new RepositoryException("Failed to create content handler for export", e);
}
}
/**
* Create Export Parameters
*
* @param exportPath path to export from
* @param skipBinary skip binary content in export
* @param noRecurse do not recurse to children
* @return export parameters
*/
private ExporterCrawlerParameters createExportParameters(String exportPath, boolean skipBinary, boolean noRecurse)
{
// construct exporter parameters
ExporterCrawlerParameters parameters = new ExporterCrawlerParameters();
Location exportFrom = new Location(getWorkspaceStore());
exportFrom.setPath(exportPath);
parameters.setExportFrom(exportFrom);
parameters.setCrawlSelf(true);
parameters.setCrawlContent(!skipBinary);
parameters.setCrawlChildNodes(!noRecurse);
parameters.setCrawlNullProperties(false);
return parameters;
}
/**
* JCR Session Import Binding
*/
private class JCRImportBinding implements ImporterBinding
{
private ImporterBinding.UUID_BINDING uuidBinding;
/**
* Construct
*
* @param uuidBehaviour JCR Import UUID Behaviour
*/
private JCRImportBinding(int uuidBehaviour)
{
switch (uuidBehaviour)
{
case ImportUUIDBehavior.IMPORT_UUID_CREATE_NEW:
uuidBinding = ImporterBinding.UUID_BINDING.CREATE_NEW;
break;
case ImportUUIDBehavior.IMPORT_UUID_COLLISION_REMOVE_EXISTING:
uuidBinding = ImporterBinding.UUID_BINDING.REMOVE_EXISTING;
break;
case ImportUUIDBehavior.IMPORT_UUID_COLLISION_REPLACE_EXISTING:
uuidBinding = ImporterBinding.UUID_BINDING.REPLACE_EXISTING;
break;
case ImportUUIDBehavior.IMPORT_UUID_COLLISION_THROW:
uuidBinding = ImporterBinding.UUID_BINDING.THROW_ON_COLLISION;
break;
default:
throw new ImporterException("Unknown Import UUID Behaviour: " + uuidBehaviour);
}
}
/*
* (non-Javadoc)
* @see org.alfresco.service.cmr.view.ImporterBinding#getUUIDBinding()
*/
public UUID_BINDING getUUIDBinding()
{
return uuidBinding;
}
/*
* (non-Javadoc)
* @see org.alfresco.service.cmr.view.ImporterBinding#getValue(java.lang.String)
*/
public String getValue(String key)
{
return null;
}
/*
* (non-Javadoc)
* @see org.alfresco.service.cmr.view.ImporterBinding#searchWithinTransaction()
*/
public boolean allowReferenceWithinTransaction()
{
return false;
}
/*
* (non-Javadoc)
* @see org.alfresco.service.cmr.view.ImporterBinding#getExcludedClasses()
*/
public QName[] getExcludedClasses()
{
return null;
}
}
//
// Session / Transaction Management
//
/**
* Strategy for handling Session Isolation
*/
private interface SessionIsolation
{
// Start transaction
public void begin() throws RepositoryException;
// Commit transaction
public void commit() throws RepositoryException;
// Rollback transaction
public void rollback() throws RepositoryException;
}
/**
* Implementation of session isolation which relies on an outer transaction
* to control the isolation boundary.
*
* @author davidc
*/
private class OuterTransaction implements SessionIsolation
{
/* (non-Javadoc)
* @see org.alfresco.jcr.session.SessionImpl.SessionIsolation#begin()
*/
public void begin() throws RepositoryException
{
}
/* (non-Javadoc)
* @see org.alfresco.jcr.session.SessionImpl.SessionIsolation#commit()
*/
public void commit() throws RepositoryException
{
}
/* (non-Javadoc)
* @see org.alfresco.jcr.session.SessionImpl.SessionIsolation#rollback()
*/
public void rollback() throws RepositoryException
{
}
}
/**
* Session isolation strategy which uses transactions to control the isolation.
*
* @author davidc
*/
private class InnerTransaction implements SessionIsolation
{
private UserTransaction userTransaction = null;
/* (non-Javadoc)
* @see org.alfresco.jcr.session.SessionImpl.SessionIsolation#begin()
*/
public void begin()
throws RepositoryException
{
try
{
UserTransaction trx = repository.getServiceRegistry().getTransactionService().getUserTransaction();
trx.begin();
userTransaction = trx;
}
catch (NotSupportedException e)
{
throw new RepositoryException("Failed to start Repository transaction", e);
}
catch (SystemException e)
{
throw new RepositoryException("Failed to start Repository transaction", e);
}
}
/* (non-Javadoc)
* @see org.alfresco.jcr.session.SessionImpl.SessionIsolation#commit()
*/
public void commit()
throws RepositoryException
{
try
{
userTransaction.commit();
}
catch (HeuristicRollbackException e)
{
throw new RepositoryException("Failed to commit Repository transaction", e);
}
catch (HeuristicMixedException e)
{
throw new RepositoryException("Failed to commit Repository transaction", e);
}
catch (RollbackException e)
{
throw new RepositoryException("Failed to commit Repository transaction", e);
}
catch (SystemException e)
{
throw new RepositoryException("Failed to commit Repository transaction", e);
}
}
/* (non-Javadoc)
* @see org.alfresco.jcr.session.SessionImpl.SessionIsolation#rollback()
*/
public void rollback()
throws RepositoryException
{
try
{
userTransaction.rollback();
}
catch (SystemException e)
{
throw new RepositoryException("Failed to rollback Repository transaction", e);
}
}
}
}

View File

@@ -0,0 +1,98 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.session;
import javax.jcr.Repository;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.SimpleCredentials;
import org.alfresco.jcr.test.BaseJCRTest;
/**
* Test JCR Session
*
* @author David Caruana
*/
public class SessionImplTest extends BaseJCRTest
{
protected Session superuserSession;
@Override
protected void setUp() throws Exception
{
super.setUp();
SimpleCredentials superuser = new SimpleCredentials("superuser", "".toCharArray());
superuser.setAttribute("attr1", "superuserValue");
superuser.setAttribute("attr2", new Integer(1));
superuserSession = repository.login(superuser, getWorkspace());
}
@Override
protected void tearDown() throws Exception
{
superuserSession.logout();
super.tearDown();
}
public void testRepository()
throws RepositoryException
{
Repository sessionRepository = superuserSession.getRepository();
assertNotNull(sessionRepository);
assertEquals(repository, sessionRepository);
}
public void testUserId()
{
{
String userId = superuserSession.getUserID();
assertNotNull(userId);
assertEquals("superuser", userId);
}
}
public void testAttributes()
{
{
String[] names = superuserSession.getAttributeNames();
assertNotNull(names);
assertEquals(2, names.length);
String value1 = (String)superuserSession.getAttribute("attr1");
assertNotNull(value1);
assertEquals("superuserValue", value1);
Integer value2 = (Integer)superuserSession.getAttribute("attr2");
assertNotNull(value2);
assertEquals(new Integer(1), value2);
String value3 = (String)superuserSession.getAttribute("unknown");
assertNull(value3);
}
}
public void testLogout()
{
boolean isLive = superuserSession.isLive();
assertTrue(isLive);
superuserSession.logout();
isLive = superuserSession.isLive();
assertFalse(isLive);
}
}

View File

@@ -0,0 +1,268 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.session;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import javax.jcr.AccessDeniedException;
import javax.jcr.InvalidItemStateException;
import javax.jcr.InvalidSerializedDataException;
import javax.jcr.ItemExistsException;
import javax.jcr.NamespaceRegistry;
import javax.jcr.NoSuchWorkspaceException;
import javax.jcr.PathNotFoundException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.Workspace;
import javax.jcr.lock.LockException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NodeTypeManager;
import javax.jcr.observation.ObservationManager;
import javax.jcr.query.QueryManager;
import javax.jcr.version.Version;
import javax.jcr.version.VersionException;
import org.alfresco.jcr.item.ItemResolver;
import org.alfresco.jcr.item.JCRPath;
import org.alfresco.jcr.query.QueryManagerImpl;
import org.alfresco.jcr.util.JCRProxyFactory;
import org.alfresco.service.cmr.repository.ChildAssociationRef;
import org.alfresco.service.cmr.repository.CopyService;
import org.alfresco.service.cmr.repository.NodeRef;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.Path;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.namespace.QName;
import org.alfresco.util.ParameterCheck;
import org.xml.sax.ContentHandler;
/**
* Alfresco implementation of a JCR Workspace
*
* @author David Caruana
*/
public class WorkspaceImpl implements Workspace
{
private SessionImpl session;
private Workspace proxy = null;
private QueryManagerImpl queryManager = null;
/**
* Construct
*
* @param session the session
*/
public WorkspaceImpl(SessionImpl session)
{
this.session = session;
}
/**
* Get proxied JCR Workspace
*
* @return proxied JCR Workspace
*/
public Workspace getProxy()
{
if (proxy == null)
{
proxy = (Workspace)JCRProxyFactory.create(this, Workspace.class, session);
}
return proxy;
}
/* (non-Javadoc)
* @see javax.jcr.Workspace#getSession()
*/
public Session getSession()
{
return session.getProxy();
}
/* (non-Javadoc)
* @see javax.jcr.Workspace#getName()
*/
public String getName()
{
return session.getWorkspaceStore().getIdentifier();
}
/* (non-Javadoc)
* @see javax.jcr.Workspace#copy(java.lang.String, java.lang.String)
*/
public void copy(String srcAbsPath, String destAbsPath) throws ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, RepositoryException
{
ParameterCheck.mandatoryString("srcAbsPath", srcAbsPath);
ParameterCheck.mandatoryString("destAbsPath", destAbsPath);
// find source node
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
NodeRef rootRef = nodeService.getRootNode(session.getWorkspaceStore());
NodeRef sourceRef = ItemResolver.getNodeRef(session, rootRef, srcAbsPath);
if (sourceRef == null)
{
throw new PathNotFoundException("Source path " + srcAbsPath + " cannot be found.");
}
// find dest node
NodeRef destRef = null;
QName destName = null;
Path destPath = new JCRPath(session.getNamespaceResolver(), destAbsPath).getPath();
if (destPath.size() == 1)
{
destRef = rootRef;
destName = ((JCRPath.SimpleElement)destPath.get(0)).getQName();
}
else
{
Path destParentPath = destPath.subPath(destPath.size() -2);
destRef = ItemResolver.getNodeRef(session, rootRef, destParentPath.toPrefixString(session.getNamespaceResolver()));
if (destRef == null)
{
throw new PathNotFoundException("Destination path " + destParentPath + " cannot be found.");
}
destName = ((JCRPath.SimpleElement)destPath.get(destPath.size() -1)).getQName();
}
// validate name
// TODO: Replace with proper name validation
if (destName.getLocalName().indexOf('[') != -1 || destName.getLocalName().indexOf(']') != -1)
{
throw new RepositoryException("Node name '" + destName + "' is invalid");
}
// determine child association type for destination
ChildAssociationRef childAssocRef = nodeService.getPrimaryParent(sourceRef);
// copy node
CopyService copyService = session.getRepositoryImpl().getServiceRegistry().getCopyService();
copyService.copy(sourceRef, destRef, childAssocRef.getTypeQName(), destName);
// finally save
session.save();
}
/* (non-Javadoc)
* @see javax.jcr.Workspace#copy(java.lang.String, java.lang.String, java.lang.String)
*/
public void copy(String srcWorkspace, String srcAbsPath, String destAbsPath) throws NoSuchWorkspaceException, ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
/* (non-Javadoc)
* @see javax.jcr.Workspace#clone(java.lang.String, java.lang.String, java.lang.String, boolean)
*/
public void clone(String srcWorkspace, String srcAbsPath, String destAbsPath, boolean removeExisting) throws NoSuchWorkspaceException, ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
/* (non-Javadoc)
* @see javax.jcr.Workspace#move(java.lang.String, java.lang.String)
*/
public void move(String srcAbsPath, String destAbsPath) throws ConstraintViolationException, VersionException, AccessDeniedException, PathNotFoundException, ItemExistsException, LockException, RepositoryException
{
session.move(srcAbsPath, destAbsPath);
session.save();
}
/* (non-Javadoc)
* @see javax.jcr.Workspace#restore(javax.jcr.version.Version[], boolean)
*/
public void restore(Version[] versions, boolean removeExisting) throws ItemExistsException, UnsupportedRepositoryOperationException, VersionException, LockException, InvalidItemStateException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
/* (non-Javadoc)
* @see javax.jcr.Workspace#getQueryManager()
*/
public QueryManager getQueryManager() throws RepositoryException
{
if (queryManager == null)
{
queryManager = new QueryManagerImpl(session);
}
return queryManager;
}
/* (non-Javadoc)
* @see javax.jcr.Workspace#getNamespaceRegistry()
*/
public NamespaceRegistry getNamespaceRegistry() throws RepositoryException
{
return session.getRepositoryImpl().getNamespaceRegistry();
}
/* (non-Javadoc)
* @see javax.jcr.Workspace#getNodeTypeManager()
*/
public NodeTypeManager getNodeTypeManager() throws RepositoryException
{
return session.getTypeManager();
}
/* (non-Javadoc)
* @see javax.jcr.Workspace#getObservationManager()
*/
public ObservationManager getObservationManager() throws UnsupportedRepositoryOperationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
/* (non-Javadoc)
* @see javax.jcr.Workspace#getAccessibleWorkspaceNames()
*/
public String[] getAccessibleWorkspaceNames() throws RepositoryException
{
NodeService nodeService = session.getRepositoryImpl().getServiceRegistry().getNodeService();
List<StoreRef> storeRefs = nodeService.getStores();
List<String> workspaceStores = new ArrayList<String>();
for (StoreRef storeRef : storeRefs)
{
if (storeRef.getProtocol().equals(StoreRef.PROTOCOL_WORKSPACE))
{
workspaceStores.add(storeRef.getIdentifier());
}
}
return workspaceStores.toArray(new String[workspaceStores.size()]);
}
/* (non-Javadoc)
* @see javax.jcr.Workspace#getImportContentHandler(java.lang.String, int)
*/
public ContentHandler getImportContentHandler(String parentAbsPath, int uuidBehavior) throws PathNotFoundException, ConstraintViolationException, VersionException, LockException, AccessDeniedException, RepositoryException
{
return session.getImportContentHandler(parentAbsPath, uuidBehavior);
}
/* (non-Javadoc)
* @see javax.jcr.Workspace#importXML(java.lang.String, java.io.InputStream, int)
*/
public void importXML(String parentAbsPath, InputStream in, int uuidBehavior) throws IOException, PathNotFoundException, ItemExistsException, ConstraintViolationException, InvalidSerializedDataException, LockException, AccessDeniedException, RepositoryException
{
session.importXML(parentAbsPath, in, uuidBehavior);
}
}

View File

@@ -0,0 +1,98 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.tck;
import java.util.Hashtable;
import javax.jcr.Repository;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import org.alfresco.jcr.repository.RepositoryFactory;
import org.alfresco.jcr.repository.RepositoryImpl;
import org.alfresco.jcr.test.TestData;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
/**
* Setup Repository for access via JNDI by TCK Web Application
*
* @author David Caruana
*/
public class RepositoryStartupServlet extends HttpServlet
{
private static final long serialVersionUID = -4763518135895358778L;
private static InitialContext jndiContext;
private final static String repositoryName = "Alfresco.Repository";
/**
* Initializes the servlet
*
* @throws ServletException
*/
public void init()
throws ServletException
{
super.init();
WebApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
RepositoryImpl repository = (RepositoryImpl)context.getBean(RepositoryFactory.REPOSITORY_BEAN);
repository.setDefaultWorkspace(TestData.TEST_WORKSPACE);
try
{
Hashtable<String, String> env = new Hashtable<String, String>();
env.put(Context.PROVIDER_URL, "http://www.alfresco.org");
env.put(Context.INITIAL_CONTEXT_FACTORY, "com.day.crx.jndi.provider.MemoryInitialContextFactory");
jndiContext = new InitialContext(env);
jndiContext.bind(repositoryName, (Repository)repository);
}
catch (NamingException e)
{
throw new ServletException(e);
}
}
/**
* Destroy the servlet
*/
public void destroy()
{
super.destroy();
if (jndiContext != null)
{
try
{
jndiContext.unbind(repositoryName);
}
catch (NamingException e)
{
// Note: Itentionally ignore...
}
}
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,57 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.test;
import javax.jcr.Repository;
import junit.framework.TestCase;
import org.alfresco.jcr.repository.RepositoryFactory;
import org.alfresco.jcr.repository.RepositoryImpl;
import org.alfresco.service.cmr.repository.StoreRef;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* Base JCR Test
*
* @author David Caruana
*/
public class BaseJCRTest extends TestCase
{
private RepositoryImpl repositoryImpl;
protected Repository repository;
protected StoreRef storeRef;
private static ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:org/alfresco/jcr/test/test-context.xml");
protected String getWorkspace()
{
return storeRef.getIdentifier();
}
@Override
protected void setUp() throws Exception
{
storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, "Test_" + System.currentTimeMillis());
TestData.generateTestData(applicationContext, storeRef.getIdentifier());
repositoryImpl = (RepositoryImpl)applicationContext.getBean(RepositoryFactory.REPOSITORY_BEAN);
repositoryImpl.setDefaultWorkspace(storeRef.getIdentifier());
repository = repositoryImpl;
}
}

View File

@@ -0,0 +1,131 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.test;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import org.alfresco.repo.importer.ImporterBootstrap;
import org.alfresco.repo.security.authentication.AuthenticationComponent;
import org.alfresco.repo.security.authentication.MutableAuthenticationDao;
import org.alfresco.service.ServiceRegistry;
import org.alfresco.service.cmr.repository.NodeService;
import org.alfresco.service.cmr.repository.StoreRef;
import org.alfresco.service.cmr.security.PermissionService;
import org.alfresco.service.cmr.view.ImporterService;
import org.alfresco.service.namespace.NamespaceService;
import org.alfresco.service.transaction.TransactionService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestData
{
public static final String TEST_WORKSPACE = "test";
/**
* Generate Test Workspace within Repository
*
* @param args
*/
public static void main(String[] args)
{
ApplicationContext context = new ClassPathXmlApplicationContext("org/alfresco/jcr/test/test-context.xml");
generateTestData(context, TEST_WORKSPACE);
System.out.println("Generated TCK test data to workspace: " + TEST_WORKSPACE);
System.exit(0);
}
/**
* Bootstrap Repository with JCR Test Data
*
* @param applicationContext
* @param workspaceName
*/
public static void generateTestData(ApplicationContext applicationContext, String workspaceName)
{
{
// Bootstrap Users
MutableAuthenticationDao authDAO = (MutableAuthenticationDao) applicationContext.getBean("alfDaoImpl");
if (authDAO.userExists("superuser") == false)
{
authDAO.createUser("superuser", "".toCharArray());
}
if (authDAO.userExists("user") == false)
{
authDAO.createUser("user", "".toCharArray());
}
if (authDAO.userExists("anonymous") == false)
{
authDAO.createUser("anonymous", "".toCharArray());
}
}
try
{
AuthenticationComponent authenticationComponent = (AuthenticationComponent)applicationContext.getBean("authenticationComponent");
authenticationComponent.setSystemUserAsCurrentUser();
try
{
// Bootstrap Workspace Test Data
StoreRef storeRef = new StoreRef(StoreRef.PROTOCOL_WORKSPACE, workspaceName);
ImporterBootstrap bootstrap = new ImporterBootstrap();
bootstrap.setAuthenticationComponent((AuthenticationComponent) applicationContext.getBean("authenticationComponent"));
bootstrap.setImporterService((ImporterService) applicationContext.getBean(ServiceRegistry.IMPORTER_SERVICE.getLocalName()));
bootstrap.setNodeService((NodeService) applicationContext.getBean(ServiceRegistry.NODE_SERVICE.getLocalName()));
bootstrap.setNamespaceService((NamespaceService) applicationContext.getBean(ServiceRegistry.NAMESPACE_SERVICE.getLocalName()));
bootstrap.setTransactionService((TransactionService) applicationContext.getBean(ServiceRegistry.TRANSACTION_SERVICE.getLocalName()));
bootstrap.setStoreUrl(storeRef.toString());
List<Properties> views = new ArrayList<Properties>();
Properties testView = new Properties();
testView.setProperty("path", "/");
testView.setProperty("location", "org/alfresco/jcr/test/testData.xml");
views.add(testView);
bootstrap.setBootstrapViews(views);
bootstrap.bootstrap();
// Bootstrap clears security context
authenticationComponent.setSystemUserAsCurrentUser();
PermissionService permissionService = (PermissionService)applicationContext.getBean(ServiceRegistry.PERMISSIONS_SERVICE.getLocalName());
NodeService nodeService = (NodeService)applicationContext.getBean(ServiceRegistry.NODE_SERVICE.getLocalName());
// permissionService.setPermission(nodeService.getRootNode(storeRef), PermissionService.ALL_AUTHORITIES, PermissionService.ALL_PERMISSIONS, true);
permissionService.setPermission(nodeService.getRootNode(storeRef), "superuser", PermissionService.ALL_PERMISSIONS, true);
permissionService.setPermission(nodeService.getRootNode(storeRef), "anonymous", PermissionService.READ, true);
permissionService.setPermission(nodeService.getRootNode(storeRef), "user", PermissionService.READ, true);
permissionService.setPermission(nodeService.getRootNode(storeRef), "user", PermissionService.WRITE, true);
}
finally
{
authenticationComponent.clearCurrentSecurityContext();
}
}
catch (RuntimeException e)
{
System.out.println("Exception: " + e);
e.printStackTrace();
throw e;
}
}
}

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<testdata xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:alf="http://www.alfresco.org" xmlns:d="http://www.alfresco.org/model/dictionary/1.0" xmlns:view="http://www.alfresco.org/view/repository/1.0" xmlns:act="http://www.alfresco.org/model/action/1.0" xmlns:app="http://www.alfresco.org/model/application/1.0" xmlns:usr="http://www.alfresco.org/model/user/1.0" xmlns:ver="http://www.alfresco.org/model/versionstore/1.0" xmlns:cm="http://www.alfresco.org/model/content/1.0" xmlns:sv="http://www.jcp.org/jcr/sv/1.0" xmlns:mix="http://www.jcp.org/jcr/mix/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:jcrtest="http://www.alfresco.org/test/jcr/1.0" xmlns:sys="http://www.alfresco.org/model/system/1.0" xmlns:rule="http://www.alfresco.org/model/rule/1.0" xmlns:fm="http://www.alfresco.org/model/forum/1.0" xmlns="" jcr:primaryType="jcrtest:testtype" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="36110c2e-68bf-11da-98b9-375bcb5cbca6" jcrtest:booleanProp="true" jcrtest:doubleProp="3.141592653589793" sys:node-uuid="36110c2e-68bf-11da-98b9-375bcb5cbca6" jcrtest:dateProp="2005-09-16T19:20:05.034+01:00" jcrtest:longProp="90834953485278298" jcrtest:nameProp="jcrtest:test" sys:store-protocol="workspace" cm:name="36110c2e-68bf-11da-98b9-375bcb5cbca6" jcrtest:stringProp="2005-09-16T20:20:05.555+01:00" sys:store-identifier="test">
<firstChild jcr:primaryType="jcrtest:testtype" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="36137d2f-68bf-11da-98b9-375bcb5cbca6" sys:store-protocol="workspace" sys:node-uuid="36137d2f-68bf-11da-98b9-375bcb5cbca6" cm:name="36137d2f-68bf-11da-98b9-375bcb5cbca6" sys:store-identifier="test"></firstChild>
<sameNameTests jcr:primaryType="jcrtest:testtype" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="36137d30-68bf-11da-98b9-375bcb5cbca6" sys:store-protocol="workspace" sys:node-uuid="36137d30-68bf-11da-98b9-375bcb5cbca6" cm:name="36137d30-68bf-11da-98b9-375bcb5cbca6" sys:store-identifier="test">
<sameNameSibling jcr:primaryType="jcrtest:testtype" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="3615c721-68bf-11da-98b9-375bcb5cbca6" sys:store-protocol="workspace" sys:node-uuid="3615c721-68bf-11da-98b9-375bcb5cbca6" cm:name="3615c721-68bf-11da-98b9-375bcb5cbca6" sys:store-identifier="test"></sameNameSibling>
<sameNameSibling jcr:primaryType="jcrtest:testtype" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="3615c722-68bf-11da-98b9-375bcb5cbca6" sys:store-protocol="workspace" sys:node-uuid="3615c722-68bf-11da-98b9-375bcb5cbca6" cm:name="3615c722-68bf-11da-98b9-375bcb5cbca6" sys:store-identifier="test"></sameNameSibling>
</sameNameTests>
<multiValued jcr:primaryType="jcrtest:testtype" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="36183823-68bf-11da-98b9-375bcb5cbca6" sys:store-protocol="workspace" cm:name="36183823-68bf-11da-98b9-375bcb5cbca6" jcrtest:multiProp="value_x0020_one value_x0020_two value_x0020_three" sys:node-uuid="36183823-68bf-11da-98b9-375bcb5cbca6" sys:store-identifier="test"></multiValued>
<contentValue jcr:primaryType="cm:content" jcr:mixinTypes="cm:auditable sys:referenceable mix:referenceable" jcr:uuid="36183824-68bf-11da-98b9-375bcb5cbca6" cm:modifier="System" cm:modified="2005-12-09T14:22:21.676Z" sys:node-uuid="36183824-68bf-11da-98b9-375bcb5cbca6" cm:creator="System" sys:store-protocol="workspace" cm:content="dHJ1ZQ==" cm:name="Test_x0020_Content" sys:store-identifier="test" cm:created="2005-12-09T14:22:21.660Z"></contentValue>
<query jcr:primaryType="jcrtest:testtype" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="361f6416-68bf-11da-98b9-375bcb5cbca6" sys:store-protocol="workspace" sys:node-uuid="361f6416-68bf-11da-98b9-375bcb5cbca6" cm:name="361f6416-68bf-11da-98b9-375bcb5cbca6" sys:store-identifier="test">
<one jcr:primaryType="jcrtest:testtype" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="3621ae07-68bf-11da-98b9-375bcb5cbca6" sys:store-protocol="workspace" jcrtest:prop1="a" cm:name="3621ae07-68bf-11da-98b9-375bcb5cbca6" sys:node-uuid="3621ae07-68bf-11da-98b9-375bcb5cbca6" sys:store-identifier="test"></one>
<two jcr:primaryType="jcrtest:testtype" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="3621ae08-68bf-11da-98b9-375bcb5cbca6" sys:store-protocol="workspace" jcrtest:prop1="c" cm:name="3621ae08-68bf-11da-98b9-375bcb5cbca6" sys:node-uuid="3621ae08-68bf-11da-98b9-375bcb5cbca6" sys:store-identifier="test"></two>
<three jcr:primaryType="jcrtest:testtype" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="3621ae09-68bf-11da-98b9-375bcb5cbca6" sys:store-protocol="workspace" jcrtest:prop1="e" cm:name="3621ae09-68bf-11da-98b9-375bcb5cbca6" sys:node-uuid="3621ae09-68bf-11da-98b9-375bcb5cbca6" sys:store-identifier="test"></three>
<four jcr:primaryType="jcrtest:testtype" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="36241f0a-68bf-11da-98b9-375bcb5cbca6" sys:store-protocol="workspace" jcrtest:prop1="g" cm:name="36241f0a-68bf-11da-98b9-375bcb5cbca6" sys:node-uuid="36241f0a-68bf-11da-98b9-375bcb5cbca6" sys:store-identifier="test"></four>
<node1 jcr:primaryType="jcrtest:testtype" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="36241f0b-68bf-11da-98b9-375bcb5cbca6" sys:store-protocol="workspace" jcrtest:prop1="b" cm:name="36241f0b-68bf-11da-98b9-375bcb5cbca6" sys:node-uuid="36241f0b-68bf-11da-98b9-375bcb5cbca6" sys:store-identifier="test"></node1>
<node1 jcr:primaryType="jcrtest:testtype" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="3626900c-68bf-11da-98b9-375bcb5cbca6" sys:store-protocol="workspace" jcrtest:prop1="d" cm:name="3626900c-68bf-11da-98b9-375bcb5cbca6" sys:node-uuid="3626900c-68bf-11da-98b9-375bcb5cbca6" sys:store-identifier="test"></node1>
<node1 jcr:primaryType="jcrtest:testtype" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="3628d9fd-68bf-11da-98b9-375bcb5cbca6" sys:store-protocol="workspace" jcrtest:prop1="f" cm:name="3628d9fd-68bf-11da-98b9-375bcb5cbca6" sys:node-uuid="3628d9fd-68bf-11da-98b9-375bcb5cbca6" sys:store-identifier="test"></node1>
<node1 jcr:primaryType="jcrtest:testtype" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="3628d9fe-68bf-11da-98b9-375bcb5cbca6" sys:store-protocol="workspace" jcrtest:prop1="h" cm:name="3628d9fe-68bf-11da-98b9-375bcb5cbca6" sys:node-uuid="3628d9fe-68bf-11da-98b9-375bcb5cbca6" sys:store-identifier="test"></node1>
<document jcr:primaryType="jcrtest:testdoc" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="362b4aff-68bf-11da-98b9-375bcb5cbca6" sys:store-protocol="workspace" jcrtest:title="Doc_x0020_1" cm:name="362b4aff-68bf-11da-98b9-375bcb5cbca6" sys:node-uuid="362b4aff-68bf-11da-98b9-375bcb5cbca6" sys:store-identifier="test">
<para-1-1 jcr:primaryType="jcrtest:testpara" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="362d94f0-68bf-11da-98b9-375bcb5cbca6" jcrtest:subtitle="P_x0020_1_x0020_1" sys:store-protocol="workspace" cm:name="362d94f0-68bf-11da-98b9-375bcb5cbca6" sys:node-uuid="362d94f0-68bf-11da-98b9-375bcb5cbca6" jcrtest:content="A_x0020_bit_x0020_of_x0020_wiffle" sys:store-identifier="test"></para-1-1>
<para-1-2 jcr:primaryType="jcrtest:testpara" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="362d94f1-68bf-11da-98b9-375bcb5cbca6" jcrtest:subtitle="P_x0020_1_x0020_2" sys:store-protocol="workspace" cm:name="362d94f1-68bf-11da-98b9-375bcb5cbca6" sys:node-uuid="362d94f1-68bf-11da-98b9-375bcb5cbca6" jcrtest:content="More_x0020_whitterings" sys:store-identifier="test"></para-1-2>
<para-1-3 jcr:primaryType="jcrtest:testpara" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="362d94f2-68bf-11da-98b9-375bcb5cbca6" jcrtest:subtitle="P_x0020_1_x0020_3" sys:store-protocol="workspace" cm:name="362d94f2-68bf-11da-98b9-375bcb5cbca6" sys:node-uuid="362d94f2-68bf-11da-98b9-375bcb5cbca6" jcrtest:content="Carrot,_x0020_spud,_x0020_turnip_x0020_and_x0020_leek." sys:store-identifier="test"></para-1-3>
</document>
<document-2 jcr:primaryType="jcrtest:testdoc" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="363005f3-68bf-11da-98b9-375bcb5cbca6" sys:store-protocol="workspace" jcrtest:title="Doc_x0020_2" cm:name="363005f3-68bf-11da-98b9-375bcb5cbca6" sys:node-uuid="363005f3-68bf-11da-98b9-375bcb5cbca6" sys:store-identifier="test">
<para-2-1 jcr:primaryType="jcrtest:testpara" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="363005f4-68bf-11da-98b9-375bcb5cbca6" jcrtest:subtitle="P_x0020_2_x0020_1" sys:store-protocol="workspace" cm:name="363005f4-68bf-11da-98b9-375bcb5cbca6" sys:node-uuid="363005f4-68bf-11da-98b9-375bcb5cbca6" jcrtest:content="tiger,_x0020_lion" sys:store-identifier="test"></para-2-1>
<para-2-2 jcr:primaryType="jcrtest:testpara" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="363276f5-68bf-11da-98b9-375bcb5cbca6" jcrtest:subtitle="P_x0020_2_x0020_2" sys:store-protocol="workspace" cm:name="363276f5-68bf-11da-98b9-375bcb5cbca6" sys:node-uuid="363276f5-68bf-11da-98b9-375bcb5cbca6" jcrtest:content="biscuit,_x0020_bun,_x0020_cake" sys:store-identifier="test"></para-2-2>
<para-2-3 jcr:primaryType="jcrtest:testpara" jcr:mixinTypes="sys:referenceable mix:referenceable" jcr:uuid="363276f6-68bf-11da-98b9-375bcb5cbca6" jcrtest:subtitle="P_x0020_2_x0020_3" sys:store-protocol="workspace" cm:name="363276f6-68bf-11da-98b9-375bcb5cbca6" sys:node-uuid="363276f6-68bf-11da-98b9-375bcb5cbca6" jcrtest:content="penguin,_x0020_hawk,_x0020_dove" sys:store-identifier="test"></para-2-3>
</document-2>
</query>
</testdata>

View File

@@ -0,0 +1,682 @@
<?xml version="1.0" encoding="UTF-8"?>
<sv:node xmlns:nt="http://www.jcp.org/jcr/nt/1.0" xmlns:alf="http://www.alfresco.org" xmlns:d="http://www.alfresco.org/model/dictionary/1.0" xmlns:view="http://www.alfresco.org/view/repository/1.0" xmlns:act="http://www.alfresco.org/model/action/1.0" xmlns:app="http://www.alfresco.org/model/application/1.0" xmlns:usr="http://www.alfresco.org/model/user/1.0" xmlns:ver="http://www.alfresco.org/model/versionstore/1.0" xmlns:cm="http://www.alfresco.org/model/content/1.0" xmlns:sv="http://www.jcp.org/jcr/sv/1.0" xmlns:mix="http://www.jcp.org/jcr/mix/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0" xmlns:jcrtest="http://www.alfresco.org/test/jcr/1.0" xmlns:sys="http://www.alfresco.org/model/system/1.0" xmlns:rule="http://www.alfresco.org/model/rule/1.0" xmlns:fm="http://www.alfresco.org/model/forum/1.0" xmlns="" sv:name="testdata">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testtype</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>36110c2e-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:booleanProp" sv:type="Boolean">
<sv:value>true</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:doubleProp" sv:type="Double">
<sv:value>3.141592653589793</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>36110c2e-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:dateProp" sv:type="Date">
<sv:value>2005-09-16T19:20:05.034+01:00</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:longProp" sv:type="Long">
<sv:value>90834953485278298</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:nameProp" sv:type="Name">
<sv:value>jcrtest:test</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>36110c2e-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:stringProp" sv:type="String">
<sv:value>2005-09-16T20:20:05.555+01:00</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
<sv:node sv:name="firstChild">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testtype</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>36137d2f-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>36137d2f-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>36137d2f-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
</sv:node>
<sv:node sv:name="sameNameTests">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testtype</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>36137d30-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>36137d30-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>36137d30-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
<sv:node sv:name="sameNameSibling">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testtype</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>3615c721-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>3615c721-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>3615c721-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
</sv:node>
<sv:node sv:name="sameNameSibling">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testtype</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>3615c722-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>3615c722-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>3615c722-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
</sv:node>
</sv:node>
<sv:node sv:name="multiValued">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testtype</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>36183823-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>36183823-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:multiProp" sv:type="String">
<sv:value>value one</sv:value>
<sv:value>value two</sv:value>
<sv:value>value three</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>36183823-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
</sv:node>
<sv:node sv:name="contentValue">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>cm:content</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>cm:auditable</sv:value>
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>36183824-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="cm:modifier" sv:type="String">
<sv:value>System</sv:value>
</sv:property>
<sv:property sv:name="cm:modified" sv:type="Date">
<sv:value>2005-12-09T14:22:21.676Z</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>36183824-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="cm:creator" sv:type="String">
<sv:value>System</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="cm:content" sv:type="Binary">
<sv:value>dHJ1ZQ==</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>Test Content</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
<sv:property sv:name="cm:created" sv:type="Date">
<sv:value>2005-12-09T14:22:21.660Z</sv:value>
</sv:property>
</sv:node>
<sv:node sv:name="query">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testtype</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>361f6416-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>361f6416-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>361f6416-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
<sv:node sv:name="one">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testtype</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>3621ae07-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:prop1" sv:type="String">
<sv:value>a</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>3621ae07-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>3621ae07-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
</sv:node>
<sv:node sv:name="two">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testtype</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>3621ae08-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:prop1" sv:type="String">
<sv:value>c</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>3621ae08-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>3621ae08-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
</sv:node>
<sv:node sv:name="three">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testtype</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>3621ae09-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:prop1" sv:type="String">
<sv:value>e</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>3621ae09-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>3621ae09-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
</sv:node>
<sv:node sv:name="four">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testtype</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>36241f0a-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:prop1" sv:type="String">
<sv:value>g</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>36241f0a-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>36241f0a-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
</sv:node>
<sv:node sv:name="node1">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testtype</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>36241f0b-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:prop1" sv:type="String">
<sv:value>b</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>36241f0b-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>36241f0b-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
</sv:node>
<sv:node sv:name="node1">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testtype</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>3626900c-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:prop1" sv:type="String">
<sv:value>d</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>3626900c-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>3626900c-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
</sv:node>
<sv:node sv:name="node1">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testtype</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>3628d9fd-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:prop1" sv:type="String">
<sv:value>f</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>3628d9fd-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>3628d9fd-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
</sv:node>
<sv:node sv:name="node1">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testtype</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>3628d9fe-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:prop1" sv:type="String">
<sv:value>h</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>3628d9fe-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>3628d9fe-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
</sv:node>
<sv:node sv:name="document">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testdoc</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>362b4aff-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:title" sv:type="String">
<sv:value>Doc 1</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>362b4aff-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>362b4aff-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
<sv:node sv:name="para-1-1">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testpara</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>362d94f0-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:subtitle" sv:type="String">
<sv:value>P 1 1</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>362d94f0-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>362d94f0-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:content" sv:type="String">
<sv:value>A bit of wiffle</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
</sv:node>
<sv:node sv:name="para-1-2">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testpara</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>362d94f1-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:subtitle" sv:type="String">
<sv:value>P 1 2</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>362d94f1-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>362d94f1-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:content" sv:type="String">
<sv:value>More whitterings</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
</sv:node>
<sv:node sv:name="para-1-3">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testpara</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>362d94f2-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:subtitle" sv:type="String">
<sv:value>P 1 3</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>362d94f2-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>362d94f2-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:content" sv:type="String">
<sv:value>Carrot, spud, turnip and leek.</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
</sv:node>
</sv:node>
<sv:node sv:name="document-2">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testdoc</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>363005f3-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:title" sv:type="String">
<sv:value>Doc 2</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>363005f3-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>363005f3-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
<sv:node sv:name="para-2-1">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testpara</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>363005f4-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:subtitle" sv:type="String">
<sv:value>P 2 1</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>363005f4-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>363005f4-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:content" sv:type="String">
<sv:value>tiger, lion</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
</sv:node>
<sv:node sv:name="para-2-2">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testpara</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>363276f5-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:subtitle" sv:type="String">
<sv:value>P 2 2</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>363276f5-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>363276f5-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:content" sv:type="String">
<sv:value>biscuit, bun, cake</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
</sv:node>
<sv:node sv:name="para-2-3">
<sv:property sv:name="jcr:primaryType" sv:type="Name">
<sv:value>jcrtest:testpara</sv:value>
</sv:property>
<sv:property sv:name="jcr:mixinTypes" sv:type="Name">
<sv:value>sys:referenceable</sv:value>
<sv:value>mix:referenceable</sv:value>
</sv:property>
<sv:property sv:name="jcr:uuid" sv:type="String">
<sv:value>363276f6-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:subtitle" sv:type="String">
<sv:value>P 2 3</sv:value>
</sv:property>
<sv:property sv:name="sys:store-protocol" sv:type="String">
<sv:value>workspace</sv:value>
</sv:property>
<sv:property sv:name="cm:name" sv:type="String">
<sv:value>363276f6-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="sys:node-uuid" sv:type="String">
<sv:value>363276f6-68bf-11da-98b9-375bcb5cbca6</sv:value>
</sv:property>
<sv:property sv:name="jcrtest:content" sv:type="String">
<sv:value>penguin, hawk, dove</sv:value>
</sv:property>
<sv:property sv:name="sys:store-identifier" sv:type="String">
<sv:value>test</sv:value>
</sv:property>
</sv:node>
</sv:node>
</sv:node>
</sv:node>

View File

@@ -0,0 +1,17 @@
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>
<beans>
<import resource="classpath:alfresco/application-context.xml" />
<bean id="testDictionaryBootstrap" class="org.alfresco.repo.dictionary.DictionaryBootstrap" init-method="bootstrap" depends-on="JCR.DictionaryBootstrap">
<property name="dictionaryDAO"><ref bean="dictionaryDAO"/></property>
<property name="models">
<list>
<value>org/alfresco/jcr/test/testModel.xml</value>
</list>
</property>
</bean>
</beans>

View File

@@ -0,0 +1 @@
true

View File

@@ -0,0 +1,111 @@
<view:view xmlns:view="http://www.alfresco.org/view/repository/1.0"
xmlns:jcrtest="http://www.alfresco.org/test/jcr/1.0"
xmlns:cm="http://www.alfresco.org/model/content/1.0">
<jcrtest:testtype view:childName="testroot">
</jcrtest:testtype>
<jcrtest:testtype view:childName="testdata">
<!-- Properties for XXXPropertyTests -->
<jcrtest:booleanProp>true</jcrtest:booleanProp>
<jcrtest:dateProp>2005-09-16T18:20:05.034Z</jcrtest:dateProp>
<jcrtest:doubleProp>3.141592653589793</jcrtest:doubleProp>
<jcrtest:longProp>90834953485278298</jcrtest:longProp>
<jcrtest:nameProp>{http://www.alfresco.org/test/jcr/1.0}test</jcrtest:nameProp>
<jcrtest:stringProp>2005-09-16T20:20:05.555+01:00</jcrtest:stringProp>
<jcrtest:children>
<jcrtest:testtype view:childName="firstChild"/>
<!-- Same name sibling tests -->
<jcrtest:testtype view:childName="sameNameTests">
<jcrtest:children>
<jcrtest:testtype view:childName="sameNameSibling"/>
<jcrtest:testtype view:childName="sameNameSibling"/>
</jcrtest:children>
</jcrtest:testtype>
<!-- Multi-valued Property -->
<jcrtest:testtype view:childName="multiValued">
<jcrtest:multiProp>
<view:value>value one</view:value>
<view:value>value two</view:value>
<view:value>value three</view:value>
</jcrtest:multiProp>
</jcrtest:testtype>
<!-- Some Content -->
<cm:content view:childName="contentValue">
<cm:name>Test Content</cm:name>
<cm:content>contentUrl=org/alfresco/jcr/test/testContent.txt|mimetype=text/plain|size=|encoding=UTF-8</cm:content>
</cm:content>
<!-- Query -->
<jcrtest:testtype view:childName="query">
<jcrtest:children>
<jcrtest:testtype view:childName="one">
<jcrtest:prop1>a</jcrtest:prop1>
</jcrtest:testtype>
<jcrtest:testtype view:childName="two">
<jcrtest:prop1>c</jcrtest:prop1>
</jcrtest:testtype>
<jcrtest:testtype view:childName="three">
<jcrtest:prop1>e</jcrtest:prop1>
</jcrtest:testtype>
<jcrtest:testtype view:childName="four">
<jcrtest:prop1>g</jcrtest:prop1>
</jcrtest:testtype>
<jcrtest:testtype view:childName="node1">
<jcrtest:prop1>b</jcrtest:prop1>
</jcrtest:testtype>
<jcrtest:testtype view:childName="node1">
<jcrtest:prop1>d</jcrtest:prop1>
</jcrtest:testtype>
<jcrtest:testtype view:childName="node1">
<jcrtest:prop1>f</jcrtest:prop1>
</jcrtest:testtype>
<jcrtest:testtype view:childName="node1">
<jcrtest:prop1>h</jcrtest:prop1>
</jcrtest:testtype>
<jcrtest:testdoc view:childName="document">
<jcrtest:title>Doc 1</jcrtest:title>
<jcrtest:children>
<jcrtest:testpara view:childName="para-1-1">
<jcrtest:subtitle>P 1 1</jcrtest:subtitle>
<jcrtest:content>A bit of wiffle</jcrtest:content>
</jcrtest:testpara>
<jcrtest:testpara view:childName="para-1-2">
<jcrtest:subtitle>P 1 2</jcrtest:subtitle>
<jcrtest:content>More whitterings</jcrtest:content>
</jcrtest:testpara>
<jcrtest:testpara view:childName="para-1-3">
<jcrtest:subtitle>P 1 3</jcrtest:subtitle>
<jcrtest:content>Carrot, spud, turnip and leek.</jcrtest:content>
</jcrtest:testpara>
</jcrtest:children>
</jcrtest:testdoc>
<jcrtest:testdoc view:childName="document-2">
<jcrtest:title>Doc 2</jcrtest:title>
<jcrtest:children>
<jcrtest:testpara view:childName="para-2-1">
<jcrtest:subtitle>P 2 1</jcrtest:subtitle>
<jcrtest:content>tiger, lion</jcrtest:content>
</jcrtest:testpara>
<jcrtest:testpara view:childName="para-2-2">
<jcrtest:subtitle>P 2 2</jcrtest:subtitle>
<jcrtest:content>biscuit, bun, cake</jcrtest:content>
</jcrtest:testpara>
<jcrtest:testpara view:childName="para-2-3">
<jcrtest:subtitle>P 2 3</jcrtest:subtitle>
<jcrtest:content>penguin, hawk, dove</jcrtest:content>
</jcrtest:testpara>
</jcrtest:children>
</jcrtest:testdoc>
</jcrtest:children>
</jcrtest:testtype>
</jcrtest:children>
</jcrtest:testtype>
</view:view>

View File

@@ -0,0 +1,152 @@
<model name="jcrtest:jcrtestmodel" xmlns="http://www.alfresco.org/model/dictionary/1.0">
<description>JCR Test Model Definitions</description>
<version>1.0</version>
<imports>
<import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
<import uri="http://www.alfresco.org/model/system/1.0" prefix="sys"/>
<import uri="" prefix=""/>
</imports>
<namespaces>
<namespace uri="http://www.alfresco.org/test/jcr/1.0" prefix="jcrtest"/>
</namespaces>
<types>
<type name="jcrtest:basetesttype">
<title>Base Test Type</title>
<parent>sys:base</parent>
<associations>
<child-association name="jcrtest:children">
<target>
<class>sys:base</class>
</target>
</child-association>
</associations>
</type>
<type name="jcrtest:testtype">
<title>Test Type</title>
<parent>jcrtest:basetesttype</parent>
<properties>
<property name="jcrtest:booleanProp">
<type>d:boolean</type>
</property>
<property name="jcrtest:dateProp">
<type>d:date</type>
</property>
<property name="jcrtest:doubleProp">
<type>d:double</type>
</property>
<property name="jcrtest:longProp">
<type>d:long</type>
</property>
<property name="jcrtest:nameProp">
<type>d:qname</type>
</property>
<property name="jcrtest:stringProp">
<type>d:text</type>
</property>
<property name="jcrtest:multiProp">
<type>d:text</type>
<multiple>true</multiple>
</property>
<property name="jcrtest:prop1">
<type>d:text</type>
</property>
</properties>
</type>
<type name="jcrtest:testdoc">
<title>Test Doc Type</title>
<parent>jcrtest:basetesttype</parent>
<properties>
<property name="jcrtest:title">
<type>d:text</type>
</property>
</properties>
</type>
<type name="jcrtest:testpara">
<title>Test Doc Type</title>
<parent>sys:base</parent>
<properties>
<property name="jcrtest:subtitle">
<type>d:text</type>
</property>
<property name="jcrtest:content">
<type>d:text</type>
</property>
</properties>
</type>
<type name="jcrtest:testsetprop">
<title>Test Set Properties</title>
<parent>jcrtest:basetesttype</parent>
<properties>
<property name="jcrtest:setBoolean">
<type>d:boolean</type>
</property>
<property name="jcrtest:setMultiBoolean">
<type>d:boolean</type>
<multiple>true</multiple>
</property>
<property name="jcrtest:setDate">
<type>d:date</type>
</property>
<property name="jcrtest:setMultiDate">
<type>d:date</type>
<multiple>true</multiple>
</property>
<property name="jcrtest:setDouble">
<type>d:double</type>
</property>
<property name="jcrtest:setMultiDouble">
<type>d:double</type>
<multiple>true</multiple>
</property>
<property name="jcrtest:setLong">
<type>d:long</type>
</property>
<property name="jcrtest:setMultiLong">
<type>d:long</type>
<multiple>true</multiple>
</property>
<property name="jcrtest:setName">
<type>d:qname</type>
</property>
<property name="jcrtest:setMultiName">
<type>d:qname</type>
<multiple>true</multiple>
</property>
<property name="jcrtest:setString">
<type>d:text</type>
</property>
<property name="jcrtest:setMultiString">
<type>d:text</type>
<multiple>true</multiple>
</property>
<property name="jcrtest:setContent">
<type>d:content</type>
</property>
<property name="jcrtest:setNodeRef">
<type>d:noderef</type>
</property>
<property name="jcrtest:setMultiNodeRef">
<type>d:noderef</type>
<multiple>true</multiple>
</property>
<property name="jcrtest:setAny">
<type>d:any</type>
</property>
<property name="jcrtest:setMultipleAny">
<type>d:any</type>
<multiple>true</multiple>
</property>
</properties>
</type>
</types>
</model>

View File

@@ -0,0 +1,94 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.util;
import java.util.NoSuchElementException;
import javax.jcr.RangeIterator;
/**
* Alfresco implementation of a Node Iterator
*
* @author David Caruana
*/
public abstract class AbstractRangeIterator implements RangeIterator
{
private int position = -1;
/**
* Construct
*
* @param context session context
* @param nodes node list
*/
public AbstractRangeIterator()
{
}
/**
* Skip 1 position
*
* @return current position
*/
protected long skip()
{
skip(1);
return position;
}
/* (non-Javadoc)
* @see javax.jcr.RangeIterator#skip(long)
*/
public void skip(long skipNum)
{
if (skipNum < 0)
{
throw new IllegalArgumentException("skipNum must be positive.");
}
if (position + skipNum >= getSize())
{
throw new NoSuchElementException("Cannot skip " + skipNum + " elements from position " + getPosition() + " as only " + getSize() + " elements are available.");
}
position += skipNum;
}
/* (non-Javadoc)
* @see javax.jcr.RangeIterator#getPosition()
*/
public long getPosition()
{
return position + 1;
}
/* (non-Javadoc)
* @see java.util.Iterator#hasNext()
*/
public boolean hasNext()
{
return getPosition() < getSize();
}
/* (non-Javadoc)
* @see java.util.Iterator#remove()
*/
public void remove()
{
throw new UnsupportedOperationException();
}
}

View File

@@ -0,0 +1,201 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.util;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import javax.jcr.AccessDeniedException;
import javax.jcr.RepositoryException;
import javax.jcr.lock.LockException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import org.alfresco.error.AlfrescoRuntimeException;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.repo.node.integrity.IntegrityException;
import org.alfresco.service.cmr.dictionary.InvalidTypeException;
import org.alfresco.service.cmr.lock.NodeLockedException;
import org.alfresco.service.cmr.security.AuthenticationService;
/**
* Factory for creating a JCR Session Context Proxy
*
* The Session Context Proxy is responsible for ensuring that the appropriate Alfresco
* Repository context is setup when a method is executed within a JCR session. For
* example, the appropriate authenticated user is validated.
*
* @author David Caruana
*
*/
public class JCRProxyFactory
{
/**
* Create a Session Context Proxy
*
* @param target target object to wrap
* @param proxyInterface the proxy interface to export
* @param context the session context
* @return the proxied target
*/
public static Object create(Object target, Class proxyInterface, SessionImpl context)
{
InvocationHandler handler = new SessionContextInvocationHandler(target, context);
return Proxy.newProxyInstance(proxyInterface.getClassLoader(), new Class[]{proxyInterface}, handler);
}
/**
* Session Context Invocation Handler
*
* @author David Caruana
*/
private static class SessionContextInvocationHandler implements InvocationHandler
{
private Object target;
private SessionImpl session;
private AuthenticationService authenticationService;
/**
* Constuct.
*
* @param instance the object instance holding the method
* @param delegateMethod the method to invoke
*/
private SessionContextInvocationHandler(Object target, SessionImpl context)
{
this.target = target;
this.session = context;
this.authenticationService = session.getRepositoryImpl().getServiceRegistry().getAuthenticationService();
}
/* (non-Javadoc)
* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
// Handle Object level methods
if (method.getName().equals("toString"))
{
return toString();
}
else if (method.getName().equals("hashCode"))
{
return hashCode();
}
else if (method.getName().equals("equals"))
{
if (Proxy.isProxyClass(args[0].getClass()))
{
return equals(Proxy.getInvocationHandler(args[0]));
}
return false;
}
try
{
// establish authentication context
String username = authenticationService.getCurrentUserName();
try
{
// setup authentication context, if one does not exist (for example, in remote case)
if (!method.getName().equals("logout"))
{
if (username == null)
{
authenticationService.validate(session.getTicket());
}
}
// invoke underlying service
return method.invoke(target, args);
}
catch (InvocationTargetException e)
{
Throwable cause = e.getCause();
throw cause;
}
finally
{
// cleanup authentication context (only if one didn't exist before)
if (username == null)
{
authenticationService.clearCurrentSecurityContext();
}
}
}
catch(Throwable cause)
{
// Map Alfresco exceptions to JCR exceptions
if (cause instanceof IntegrityException)
{
throw new ConstraintViolationException(cause);
}
else if (cause instanceof NodeLockedException)
{
throw new LockException(cause);
}
else if (cause instanceof InvalidTypeException)
{
throw new NoSuchNodeTypeException(cause);
}
else if (cause instanceof org.alfresco.repo.security.permissions.AccessDeniedException)
{
throw new AccessDeniedException(cause);
}
else if (cause instanceof AlfrescoRuntimeException)
{
throw new RepositoryException(cause);
}
throw cause;
}
}
@Override
public boolean equals(Object obj)
{
if (obj == this)
{
return true;
}
else if (obj == null || !(obj instanceof SessionContextInvocationHandler))
{
return false;
}
SessionContextInvocationHandler other = (SessionContextInvocationHandler)obj;
return target.equals(other.target);
}
@Override
public int hashCode()
{
return target.hashCode();
}
@Override
public String toString()
{
return target.toString();
}
}
}

View File

@@ -0,0 +1,556 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.version;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.List;
import javax.jcr.AccessDeniedException;
import javax.jcr.InvalidItemStateException;
import javax.jcr.Item;
import javax.jcr.ItemExistsException;
import javax.jcr.ItemNotFoundException;
import javax.jcr.ItemVisitor;
import javax.jcr.MergeException;
import javax.jcr.NoSuchWorkspaceException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.ReferentialIntegrityException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;
import javax.jcr.lock.Lock;
import javax.jcr.lock.LockException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.NodeType;
import javax.jcr.version.Version;
import javax.jcr.version.VersionException;
import javax.jcr.version.VersionHistory;
import javax.jcr.version.VersionIterator;
import org.alfresco.jcr.session.SessionImpl;
import org.alfresco.jcr.util.JCRProxyFactory;
/**
* Alfresco Implementation of a JCR Version History
*
* @author David Caruana
*/
public class VersionHistoryImpl implements VersionHistory
{
private SessionImpl session;
private org.alfresco.service.cmr.version.VersionHistory versionHistory;
private VersionHistory proxy = null;
/**
* Construct
*
* @param context
* @param versionHistory
*/
public VersionHistoryImpl(SessionImpl context, org.alfresco.service.cmr.version.VersionHistory versionHistory)
{
this.session = context;
this.versionHistory = versionHistory;
}
/**
* Get Version History Proxy
*
* @return version history proxy
*/
public VersionHistory getProxy()
{
if (proxy == null)
{
proxy = (VersionHistory)JCRProxyFactory.create(this, VersionHistory.class, session);
}
return proxy;
}
/**
* Get Session
*
* @return session impl
*/
/*package*/ SessionImpl getSessionImpl()
{
return session;
}
/**
* Get Version History impl
*
* @return version history impl
*/
/*package*/ org.alfresco.service.cmr.version.VersionHistory getVersionHistoryImpl()
{
return versionHistory;
}
/*
* (non-Javadoc)
* @see javax.jcr.version.VersionHistory#getVersionableUUID()
*/
public String getVersionableUUID() throws RepositoryException
{
return versionHistory.getRootVersion().getVersionedNodeRef().getId();
}
/*
* (non-Javadoc)
* @see javax.jcr.version.VersionHistory#getRootVersion()
*/
public Version getRootVersion() throws RepositoryException
{
return new VersionImpl(this, versionHistory.getRootVersion()).getProxy();
}
/*
* (non-Javadoc)
* @see javax.jcr.version.VersionHistory#getAllVersions()
*/
public VersionIterator getAllVersions() throws RepositoryException
{
Collection<org.alfresco.service.cmr.version.Version> versions = versionHistory.getAllVersions();
List<org.alfresco.service.cmr.version.Version> versionsList = new ArrayList<org.alfresco.service.cmr.version.Version>(versions);
return new VersionListIterator(this, versionsList);
}
/*
* (non-Javadoc)
* @see javax.jcr.version.VersionHistory#getVersion(java.lang.String)
*/
public Version getVersion(String versionName) throws VersionException, RepositoryException
{
org.alfresco.service.cmr.version.Version version = versionHistory.getVersion(versionName);
return new VersionImpl(this, version).getProxy();
}
public Version getVersionByLabel(String label) throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void addVersionLabel(String versionName, String label, boolean moveLabel) throws VersionException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void removeVersionLabel(String label) throws VersionException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean hasVersionLabel(String label) throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean hasVersionLabel(Version version, String label) throws VersionException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public String[] getVersionLabels() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public String[] getVersionLabels(Version version) throws VersionException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void removeVersion(String versionName) throws ReferentialIntegrityException, AccessDeniedException, UnsupportedRepositoryOperationException, VersionException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
// Node implementation
// TODO: To support this set of methods will require the projection of all the JCR Version nodes.
// That's not simple.
public Node addNode(String relPath) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Node addNode(String relPath, String primaryNodeTypeName) throws ItemExistsException, PathNotFoundException, NoSuchNodeTypeException, LockException, VersionException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void orderBefore(String srcChildRelPath, String destChildRelPath) throws UnsupportedRepositoryOperationException, VersionException, ConstraintViolationException, ItemNotFoundException, LockException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, Value value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, Value value, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, Value[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, Value[] values, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, String[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, String[] values, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, String value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, String value, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, InputStream value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, boolean value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, double value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, long value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, Calendar value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, Node value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Node getNode(String relPath) throws PathNotFoundException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public NodeIterator getNodes() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public NodeIterator getNodes(String namePattern) throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property getProperty(String relPath) throws PathNotFoundException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public PropertyIterator getProperties() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public PropertyIterator getProperties(String namePattern) throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Item getPrimaryItem() throws ItemNotFoundException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public String getUUID() throws UnsupportedRepositoryOperationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public int getIndex() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public PropertyIterator getReferences() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean hasNode(String relPath) throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean hasProperty(String relPath) throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean hasNodes() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean hasProperties() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public NodeType getPrimaryNodeType() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public NodeType[] getMixinNodeTypes() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean isNodeType(String nodeTypeName) throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void addMixin(String mixinName) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void removeMixin(String mixinName) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean canAddMixin(String mixinName) throws NoSuchNodeTypeException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public NodeDefinition getDefinition() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Version checkin() throws VersionException, UnsupportedRepositoryOperationException, InvalidItemStateException, LockException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void checkout() throws UnsupportedRepositoryOperationException, LockException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void doneMerge(Version version) throws VersionException, InvalidItemStateException, UnsupportedRepositoryOperationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void cancelMerge(Version version) throws VersionException, InvalidItemStateException, UnsupportedRepositoryOperationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void update(String srcWorkspaceName) throws NoSuchWorkspaceException, AccessDeniedException, LockException, InvalidItemStateException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public NodeIterator merge(String srcWorkspace, boolean bestEffort) throws NoSuchWorkspaceException, AccessDeniedException, MergeException, LockException, InvalidItemStateException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public String getCorrespondingNodePath(String workspaceName) throws ItemNotFoundException, NoSuchWorkspaceException, AccessDeniedException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean isCheckedOut() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void restore(String versionName, boolean removeExisting) throws VersionException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void restore(Version version, boolean removeExisting) throws VersionException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void restore(Version version, String relPath, boolean removeExisting) throws PathNotFoundException, ItemExistsException, VersionException, ConstraintViolationException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void restoreByLabel(String versionLabel, boolean removeExisting) throws VersionException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public VersionHistory getVersionHistory() throws UnsupportedRepositoryOperationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Version getBaseVersion() throws UnsupportedRepositoryOperationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Lock lock(boolean isDeep, boolean isSessionScoped) throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, InvalidItemStateException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Lock getLock() throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void unlock() throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, InvalidItemStateException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean holdsLock() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean isLocked() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public String getPath() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public String getName() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Item getAncestor(int depth) throws ItemNotFoundException, AccessDeniedException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Node getParent() throws ItemNotFoundException, AccessDeniedException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public int getDepth() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Session getSession() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean isNode()
{
return true;
}
public boolean isNew()
{
return false;
}
public boolean isModified()
{
return false;
}
public boolean isSame(Item otherItem) throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void accept(ItemVisitor visitor) throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void save() throws AccessDeniedException, ItemExistsException, ConstraintViolationException, InvalidItemStateException, ReferentialIntegrityException, VersionException, LockException, NoSuchNodeTypeException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void refresh(boolean keepChanges) throws InvalidItemStateException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void remove() throws VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
}

View File

@@ -0,0 +1,515 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.version;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.List;
import javax.jcr.AccessDeniedException;
import javax.jcr.InvalidItemStateException;
import javax.jcr.Item;
import javax.jcr.ItemExistsException;
import javax.jcr.ItemNotFoundException;
import javax.jcr.ItemVisitor;
import javax.jcr.MergeException;
import javax.jcr.NoSuchWorkspaceException;
import javax.jcr.Node;
import javax.jcr.NodeIterator;
import javax.jcr.PathNotFoundException;
import javax.jcr.Property;
import javax.jcr.PropertyIterator;
import javax.jcr.ReferentialIntegrityException;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.UnsupportedRepositoryOperationException;
import javax.jcr.Value;
import javax.jcr.ValueFormatException;
import javax.jcr.lock.Lock;
import javax.jcr.lock.LockException;
import javax.jcr.nodetype.ConstraintViolationException;
import javax.jcr.nodetype.NoSuchNodeTypeException;
import javax.jcr.nodetype.NodeDefinition;
import javax.jcr.nodetype.NodeType;
import javax.jcr.version.Version;
import javax.jcr.version.VersionException;
import javax.jcr.version.VersionHistory;
import org.alfresco.jcr.item.NodeRefNodeIteratorImpl;
import org.alfresco.jcr.util.JCRProxyFactory;
import org.alfresco.service.cmr.repository.NodeRef;
/**
* Alfresco implementation of a JCR Version
*
* @author David Caruana
*/
public class VersionImpl implements Version
{
private VersionHistoryImpl versionHistoryImpl;
private org.alfresco.service.cmr.version.Version version;
private Version proxy;
/**
* Construct
*
* @param versionHistoryImpl
* @param version
*/
public VersionImpl(VersionHistoryImpl versionHistoryImpl, org.alfresco.service.cmr.version.Version version)
{
this.versionHistoryImpl = versionHistoryImpl;
this.version = version;
}
/**
* Get Version Proxy
*
* @return
*/
public Version getProxy()
{
if (proxy == null)
{
proxy = (Version)JCRProxyFactory.create(this, Version.class, versionHistoryImpl.getSessionImpl());
}
return proxy;
}
/*
* (non-Javadoc)
* @see javax.jcr.version.Version#getContainingHistory()
*/
public VersionHistory getContainingHistory() throws RepositoryException
{
return versionHistoryImpl.getProxy();
}
/*
* (non-Javadoc)
* @see javax.jcr.version.Version#getCreated()
*/
public Calendar getCreated() throws RepositoryException
{
Calendar calendar = Calendar.getInstance();
calendar.setTime(version.getCreatedDate());
return calendar;
}
/*
* (non-Javadoc)
* @see javax.jcr.version.Version#getSuccessors()
*/
public Version[] getSuccessors() throws RepositoryException
{
Collection<org.alfresco.service.cmr.version.Version> successors = versionHistoryImpl.getVersionHistoryImpl().getSuccessors(version);
Version[] versions = new Version[successors.size()];
int i = 0;
for (org.alfresco.service.cmr.version.Version sucessor : successors)
{
versions[i++] = new VersionImpl(versionHistoryImpl, sucessor).getProxy();
}
return versions;
}
/*
* (non-Javadoc)
* @see javax.jcr.version.Version#getPredecessors()
*/
public Version[] getPredecessors() throws RepositoryException
{
org.alfresco.service.cmr.version.Version predecessor = versionHistoryImpl.getVersionHistoryImpl().getPredecessor(version);
Version[] versions = new Version[1];
versions[0] = new VersionImpl(versionHistoryImpl, predecessor).getProxy();
return versions;
}
/*
* (non-Javadoc)
* @see javax.jcr.Node#hasNodes()
*/
public boolean hasNodes() throws RepositoryException
{
return true;
}
/*
* (non-Javadoc)
* @see javax.jcr.Node#getNodes()
*/
public NodeIterator getNodes() throws RepositoryException
{
List<NodeRef> nodeRefs = new ArrayList<NodeRef>();
nodeRefs.add(version.getFrozenStateNodeRef());
return new NodeRefNodeIteratorImpl(versionHistoryImpl.getSessionImpl(), nodeRefs);
}
// Node implementation
// TODO: To support this set of methods will require the projection of all the JCR Version nodes.
// That's not simple.
public Node addNode(String relPath) throws ItemExistsException, PathNotFoundException, VersionException, ConstraintViolationException, LockException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Node addNode(String relPath, String primaryNodeTypeName) throws ItemExistsException, PathNotFoundException, NoSuchNodeTypeException, LockException, VersionException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void orderBefore(String srcChildRelPath, String destChildRelPath) throws UnsupportedRepositoryOperationException, VersionException, ConstraintViolationException, ItemNotFoundException, LockException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, Value value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, Value value, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, Value[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, Value[] values, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, String[] values) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, String[] values, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, String value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, String value, int type) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, InputStream value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, boolean value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, double value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, long value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, Calendar value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property setProperty(String name, Node value) throws ValueFormatException, VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Node getNode(String relPath) throws PathNotFoundException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public NodeIterator getNodes(String namePattern) throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Property getProperty(String relPath) throws PathNotFoundException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public PropertyIterator getProperties() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public PropertyIterator getProperties(String namePattern) throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Item getPrimaryItem() throws ItemNotFoundException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public String getUUID() throws UnsupportedRepositoryOperationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public int getIndex() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public PropertyIterator getReferences() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean hasNode(String relPath) throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean hasProperty(String relPath) throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean hasProperties() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public NodeType getPrimaryNodeType() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public NodeType[] getMixinNodeTypes() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean isNodeType(String nodeTypeName) throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void addMixin(String mixinName) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void removeMixin(String mixinName) throws NoSuchNodeTypeException, VersionException, ConstraintViolationException, LockException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean canAddMixin(String mixinName) throws NoSuchNodeTypeException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public NodeDefinition getDefinition() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Version checkin() throws VersionException, UnsupportedRepositoryOperationException, InvalidItemStateException, LockException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void checkout() throws UnsupportedRepositoryOperationException, LockException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void doneMerge(Version version) throws VersionException, InvalidItemStateException, UnsupportedRepositoryOperationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void cancelMerge(Version version) throws VersionException, InvalidItemStateException, UnsupportedRepositoryOperationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void update(String srcWorkspaceName) throws NoSuchWorkspaceException, AccessDeniedException, LockException, InvalidItemStateException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public NodeIterator merge(String srcWorkspace, boolean bestEffort) throws NoSuchWorkspaceException, AccessDeniedException, MergeException, LockException, InvalidItemStateException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public String getCorrespondingNodePath(String workspaceName) throws ItemNotFoundException, NoSuchWorkspaceException, AccessDeniedException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean isCheckedOut() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void restore(String versionName, boolean removeExisting) throws VersionException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void restore(Version version, boolean removeExisting) throws VersionException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void restore(Version version, String relPath, boolean removeExisting) throws PathNotFoundException, ItemExistsException, VersionException, ConstraintViolationException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void restoreByLabel(String versionLabel, boolean removeExisting) throws VersionException, ItemExistsException, UnsupportedRepositoryOperationException, LockException, InvalidItemStateException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public VersionHistory getVersionHistory() throws UnsupportedRepositoryOperationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Version getBaseVersion() throws UnsupportedRepositoryOperationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Lock lock(boolean isDeep, boolean isSessionScoped) throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, InvalidItemStateException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Lock getLock() throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void unlock() throws UnsupportedRepositoryOperationException, LockException, AccessDeniedException, InvalidItemStateException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean holdsLock() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean isLocked() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public String getPath() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public String getName() throws RepositoryException
{
return version.getVersionLabel();
}
public Item getAncestor(int depth) throws ItemNotFoundException, AccessDeniedException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Node getParent() throws ItemNotFoundException, AccessDeniedException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public int getDepth() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public Session getSession() throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public boolean isNode()
{
return true;
}
public boolean isNew()
{
return false;
}
public boolean isModified()
{
return false;
}
public boolean isSame(Item otherItem) throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void accept(ItemVisitor visitor) throws RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void save() throws AccessDeniedException, ItemExistsException, ConstraintViolationException, InvalidItemStateException, ReferentialIntegrityException, VersionException, LockException, NoSuchNodeTypeException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void refresh(boolean keepChanges) throws InvalidItemStateException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
public void remove() throws VersionException, LockException, ConstraintViolationException, RepositoryException
{
throw new UnsupportedRepositoryOperationException();
}
}

View File

@@ -0,0 +1,78 @@
/*
* Copyright (C) 2005 Alfresco, Inc.
*
* Licensed under the Mozilla Public License version 1.1
* with a permitted attribution clause. You may obtain a
* copy of the License at
*
* http://www.alfresco.org/legal/license.txt
*
* 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.alfresco.jcr.version;
import java.util.List;
import javax.jcr.version.Version;
import javax.jcr.version.VersionIterator;
import org.alfresco.jcr.util.AbstractRangeIterator;
/**
* Alfresco implementation of a Property Iterator
*
* @author David Caruana
*/
public class VersionListIterator extends AbstractRangeIterator
implements VersionIterator
{
private VersionHistoryImpl versionHistory;
private List<org.alfresco.service.cmr.version.Version> versions;
/**
* Construct
*
* @param context session context
* @param versions version list
*/
public VersionListIterator(VersionHistoryImpl versionHistory, List<org.alfresco.service.cmr.version.Version> versions)
{
this.versionHistory = versionHistory;
this.versions = versions;
}
/*
* (non-Javadoc)
* @see javax.jcr.version.VersionIterator#nextVersion()
*/
public Version nextVersion()
{
long position = skip();
org.alfresco.service.cmr.version.Version version = versions.get((int)position);
return new VersionImpl(versionHistory, version).getProxy();
}
/* (non-Javadoc)
* @see javax.jcr.RangeIterator#getSize()
*/
public long getSize()
{
return versions.size();
}
/* (non-Javadoc)
* @see java.util.Iterator#next()
*/
public Object next()
{
return nextVersion();
}
}