mirror of
https://github.com/Alfresco/alfresco-community-repo.git
synced 2025-07-24 17:32:48 +00:00
- 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:
@@ -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();
|
||||
}
|
||||
|
||||
}
|
114
source/java/org/alfresco/jcr/item/ItemImpl.java
Normal file
114
source/java/org/alfresco/jcr/item/ItemImpl.java
Normal 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();
|
||||
}
|
||||
|
||||
|
||||
}
|
145
source/java/org/alfresco/jcr/item/ItemResolver.java
Normal file
145
source/java/org/alfresco/jcr/item/ItemResolver.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
192
source/java/org/alfresco/jcr/item/JCRPath.java
Normal file
192
source/java/org/alfresco/jcr/item/JCRPath.java
Normal 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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
93
source/java/org/alfresco/jcr/item/JCRPatternMatch.java
Normal file
93
source/java/org/alfresco/jcr/item/JCRPatternMatch.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
416
source/java/org/alfresco/jcr/item/JCRTypeConverter.java
Normal file
416
source/java/org/alfresco/jcr/item/JCRTypeConverter.java
Normal 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
137
source/java/org/alfresco/jcr/item/LockImpl.java
Normal file
137
source/java/org/alfresco/jcr/item/LockImpl.java
Normal 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
|
||||
}
|
||||
|
||||
}
|
1239
source/java/org/alfresco/jcr/item/NodeImpl.java
Normal file
1239
source/java/org/alfresco/jcr/item/NodeImpl.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -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();
|
||||
}
|
||||
|
||||
}
|
684
source/java/org/alfresco/jcr/item/PropertyImpl.java
Normal file
684
source/java/org/alfresco/jcr/item/PropertyImpl.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
76
source/java/org/alfresco/jcr/item/PropertyListIterator.java
Normal file
76
source/java/org/alfresco/jcr/item/PropertyListIterator.java
Normal 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();
|
||||
}
|
||||
|
||||
}
|
193
source/java/org/alfresco/jcr/item/ValueFactoryImpl.java
Normal file
193
source/java/org/alfresco/jcr/item/ValueFactoryImpl.java
Normal 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);
|
||||
}
|
||||
|
||||
}
|
321
source/java/org/alfresco/jcr/item/ValueImpl.java
Normal file
321
source/java/org/alfresco/jcr/item/ValueImpl.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
@@ -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;
|
||||
}
|
||||
|
||||
}
|
@@ -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());
|
||||
}
|
||||
|
||||
}
|
@@ -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();
|
||||
}
|
||||
|
||||
}
|
204
source/java/org/alfresco/jcr/item/property/PropertyResolver.java
Normal file
204
source/java/org/alfresco/jcr/item/property/PropertyResolver.java
Normal 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;
|
||||
}
|
||||
|
||||
}
|
Reference in New Issue
Block a user