Index: jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java =================================================================== --- jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java (revision 772129) +++ jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/SessionImpl.java Wed May 06 13:15:40 CEST 2009 @@ -89,6 +89,8 @@ import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver; import org.apache.jackrabbit.spi.commons.conversion.NameResolver; import org.apache.jackrabbit.spi.commons.conversion.PathResolver; +import org.apache.jackrabbit.spi.commons.conversion.IdentifierResolver; +import org.apache.jackrabbit.spi.commons.conversion.MalformedPathException; import org.apache.jackrabbit.spi.commons.name.NameConstants; import org.apache.jackrabbit.spi.commons.namespace.NamespaceResolver; import org.apache.jackrabbit.spi.commons.value.ValueFactoryQImpl; @@ -139,7 +141,8 @@ workspace = createWorkspaceInstance(config, sessionInfo); // build local name-mapping - npResolver = new DefaultNamePathResolver(this, true); + IdentifierResolver idResolver = new IdResolver(); + npResolver = new DefaultNamePathResolver(this, idResolver, true); // build ValueFactory valueFactory = new ValueFactoryQImpl(config.getRepositoryService().getQValueFactory(), npResolver); @@ -601,7 +604,6 @@ } //--------------------------------------------------< NamespaceResolver >--- - public String getPrefix(String uri) throws NamespaceException { try { return getNamespacePrefix(uri); @@ -967,4 +969,35 @@ throw new NoSuchWorkspaceException("Unknown workspace: '" + workspaceName + "'."); } } + + //-------------------------------------------------------------------------- + /** + * Inner class implementing the IdentifierResolver interface + */ + private final class IdResolver implements IdentifierResolver { + + //---------------------------------------------< IdentifierResolver >--- + /** + * @see IdentifierResolver#getPath(String) + */ + public Path getPath(String identifier) throws MalformedPathException { + try { + NodeId id = getIdFactory().createNodeId(identifier); + return getHierarchyManager().getNodeEntry(id).getPath(); + } catch (RepositoryException e) { + throw new MalformedPathException("Invalid identifier '" + identifier + "'."); -} + } + } + + /** + * @see IdentifierResolver#checkFormat(String) + */ + public void checkFormat(String identifier) throws MalformedPathException { + try { + NodeId id = getIdFactory().createNodeId(identifier); + } catch (Exception e) { + throw new MalformedPathException("Invalid identifier '" + identifier + "'."); + } + } + } +} Index: jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEventListener.java =================================================================== --- jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEventListener.java (revision 772129) +++ jackrabbit-jcr2spi/src/main/java/org/apache/jackrabbit/jcr2spi/hierarchy/HierarchyEventListener.java Wed May 06 10:12:26 CEST 2009 @@ -28,7 +28,6 @@ import org.apache.jackrabbit.spi.Path; import javax.jcr.RepositoryException; -import javax.jcr.PathNotFoundException; import java.util.Collection; import java.util.Collections; import java.util.Set; @@ -153,7 +152,7 @@ try { Path parentPath = ev.getPath().getAncestor(1); parent = hierarchyMgr.lookup(parentPath); - } catch (PathNotFoundException e) { + } catch (RepositoryException e) { // should not occur log.debug(e.getMessage()); } Index: jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/RepositoryServiceImpl.java =================================================================== --- jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/RepositoryServiceImpl.java (revision 772129) +++ jackrabbit-spi2jcr/src/main/java/org/apache/jackrabbit/spi2jcr/RepositoryServiceImpl.java Tue May 05 15:56:38 CEST 2009 @@ -48,6 +48,7 @@ import org.apache.jackrabbit.spi.commons.conversion.MalformedPathException; import org.apache.jackrabbit.spi.commons.value.QValueFactoryImpl; import org.apache.jackrabbit.spi.commons.value.ValueFormat; +import org.apache.jackrabbit.spi.commons.value.ValueFactoryQImpl; import org.apache.jackrabbit.JcrConstants; import javax.jcr.RepositoryException; @@ -74,6 +75,8 @@ import javax.jcr.ImportUUIDBehavior; import javax.jcr.Value; import javax.jcr.ItemVisitor; +import javax.jcr.ValueFactory; +import javax.jcr.GuestCredentials; import javax.jcr.util.TraversingItemVisitor; import javax.jcr.observation.ObservationManager; import javax.jcr.observation.EventListener; @@ -128,6 +131,11 @@ private final IdFactoryImpl idFactory = (IdFactoryImpl) IdFactoryImpl.getInstance(); /** + * The QValueFactory + */ + private QValueFactory qValueFactory = QValueFactoryImpl.getInstance(); + + /** * Set to true if the underlying JCR repository supports * observation. */ @@ -145,7 +153,17 @@ this.repository = repository; this.batchReadConfig = batchReadConfig; this.supportsObservation = "true".equals(repository.getDescriptor(Repository.OPTION_OBSERVATION_SUPPORTED)); + + try { + Session s = repository.login(new GuestCredentials()); + ValueFactory vf = s.getValueFactory(); + if (vf instanceof ValueFactoryQImpl) { + qValueFactory = ((ValueFactoryQImpl) vf).getQValueFactory(); - } + } + } catch (RepositoryException e) { + // ignore + } + } /** * {@inheritDoc} @@ -172,7 +190,7 @@ * {@inheritDoc} */ public QValueFactory getQValueFactory() { - return QValueFactoryImpl.getInstance(); + return qValueFactory; } /** Index: jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java =================================================================== --- jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java (revision 772129) +++ jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2dav/RepositoryServiceImpl.java Wed Apr 15 17:30:24 CEST 2009 @@ -65,6 +65,7 @@ import org.apache.jackrabbit.spi.commons.conversion.ParsingNameResolver; import org.apache.jackrabbit.spi.commons.conversion.ParsingPathResolver; import org.apache.jackrabbit.spi.commons.conversion.PathResolver; +import org.apache.jackrabbit.spi.commons.conversion.IdentifierResolver; import org.apache.jackrabbit.spi.commons.name.NameConstants; import org.apache.jackrabbit.spi.commons.namespace.AbstractNamespaceResolver; import org.apache.jackrabbit.spi.commons.namespace.NamespaceResolver; @@ -2359,7 +2360,11 @@ } } - + //----------------------------------------------< NamespaceResolverImpl >--- + /** + * NamespaceResolver implementation that uses a sessionInfo to determine + * namespace mappings either from cache or from the server. + */ private class NamespaceResolverImpl implements NamespaceResolver { private final SessionInfo sessionInfo; @@ -2398,6 +2403,53 @@ } } + //---------------------------------------------< IdentifierResolverImpl >--- + private class IdentifierResolverImpl implements IdentifierResolver { + + private final SessionInfo sessionInfo; + + private IdentifierResolverImpl(SessionInfo sessionInfo) { + this.sessionInfo = sessionInfo; + } + + private Path buildPath(String uniqueID) throws RepositoryException { + String uri = uriResolver.getItemUri(getIdFactory().createNodeId(uniqueID), sessionInfo.getWorkspaceName(), sessionInfo); + return uriResolver.getQPath(uri, sessionInfo); + } + + private Path resolvePath(String jcrPath) throws RepositoryException { + return ((SessionInfoImpl) sessionInfo).getNamePathResolver().getQPath(jcrPath); + } + + /** + * @inheritDoc + */ + public Path getPath(String identifier) throws MalformedPathException { + try { + int pos = identifier.indexOf('/'); + if (pos == -1) { + // unique id identifier + return buildPath(identifier); + } else if (pos == 0) { + // jcr-path identifier + return resolvePath(identifier); + } else { + Path p1 = buildPath(identifier.substring(0, pos)); + Path p2 = resolvePath(identifier.substring(pos)); + return getPathFactory().create(p1, p2, true); + } + } catch (RepositoryException e) { + throw new MalformedPathException(identifier); + } + } + + /** + * @inheritDoc + */ + public void checkFormat(String identifier) throws MalformedPathException { + // cannot be determined. assume ok. + } + } //-----------------------------------------------< NamePathResolverImpl >--- /** * Implements a namespace resolver based on a session info. @@ -2410,7 +2462,8 @@ private NamePathResolverImpl(SessionInfo sessionInfo) { NamespaceResolver nsResolver = new NamespaceResolverImpl(sessionInfo); nResolver = new ParsingNameResolver(getNameFactory(), nsResolver); - pResolver = new ParsingPathResolver(getPathFactory(), nResolver); + IdentifierResolver idResolver = new IdentifierResolverImpl(sessionInfo); + pResolver = new ParsingPathResolver(getPathFactory(), nResolver, idResolver); } private NamePathResolverImpl(NamespaceResolver nsResolver) { @@ -2442,11 +2495,21 @@ /** * @inheritDoc */ + public Path getQPath(String path, boolean normalizeIdentifier) throws MalformedPathException, IllegalNameException, NamespaceException { + return pResolver.getQPath(path, normalizeIdentifier); + } + + /** + * @inheritDoc + */ public String getJCRPath(Path path) throws NamespaceException { return pResolver.getJCRPath(path); } } + /** + * Namespace Cache + */ private static class NamespaceCache extends AbstractNamespaceResolver { private final HashMap prefixToURI = new HashMap(); Index: jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/QValueFactoryImpl.java =================================================================== --- jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/QValueFactoryImpl.java (revision 772129) +++ jackrabbit-spi2dav/src/main/java/org/apache/jackrabbit/spi2davex/QValueFactoryImpl.java Fri Apr 17 10:31:39 CEST 2009 @@ -17,26 +17,21 @@ package org.apache.jackrabbit.spi2davex; import org.apache.jackrabbit.spi.Name; -import org.apache.jackrabbit.spi.NameFactory; import org.apache.jackrabbit.spi.Path; -import org.apache.jackrabbit.spi.PathFactory; -import org.apache.jackrabbit.spi.QPropertyDefinition; import org.apache.jackrabbit.spi.QValue; import org.apache.jackrabbit.spi.QValueFactory; import org.apache.jackrabbit.spi.commons.conversion.NamePathResolver; -import org.apache.jackrabbit.spi.commons.name.NameConstants; -import org.apache.jackrabbit.spi.commons.name.NameFactoryImpl; -import org.apache.jackrabbit.spi.commons.name.PathFactoryImpl; +import org.apache.jackrabbit.spi.commons.value.AbstractQValueFactory; +import org.apache.jackrabbit.spi.commons.value.AbstractQValue; import org.apache.jackrabbit.util.ISO8601; import org.apache.jackrabbit.util.TransientFileFactory; -import org.apache.jackrabbit.uuid.UUID; import org.apache.jackrabbit.value.ValueFactoryImpl; +import org.apache.jackrabbit.webdav.DavException; import org.apache.jackrabbit.webdav.jcr.ItemResourceConstants; import org.apache.jackrabbit.webdav.jcr.property.ValuesProperty; import org.apache.jackrabbit.webdav.property.DavProperty; import org.apache.jackrabbit.webdav.property.DefaultDavProperty; import org.apache.jackrabbit.webdav.xml.DomUtil; -import org.apache.jackrabbit.webdav.DavException; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.SAXException; @@ -67,12 +62,8 @@ /** * ValueFactoryImpl... */ -class QValueFactoryImpl implements QValueFactory { +class QValueFactoryImpl extends AbstractQValueFactory { - private static final PathFactory PATH_FACTORY = PathFactoryImpl.getInstance(); - private static final NameFactory NAME_FACTORY = NameFactoryImpl.getInstance(); - private static final String DEFAULT_ENCODING = "UTF-8"; - private final NamePathResolver resolver; private final ValueLoader loader; @@ -240,92 +231,51 @@ return new BinaryQValue(value); } - /** - * @see QValueFactory#computeAutoValues(QPropertyDefinition) - */ - public QValue[] computeAutoValues(QPropertyDefinition propertyDefinition) throws RepositoryException { - Name nodeType = propertyDefinition.getDeclaringNodeType(); - Name name = propertyDefinition.getName(); - - if (NameConstants.NT_HIERARCHYNODE.equals(nodeType) && NameConstants.JCR_CREATED.equals(name)) { - return new QValue[] { create(Calendar.getInstance()) }; - } else if (NameConstants.NT_RESOURCE.equals(nodeType) && NameConstants.JCR_LASTMODIFIED.equals(name)) { - return new QValue[] { create(Calendar.getInstance()) }; - } else if (NameConstants.MIX_REFERENCEABLE.equals(nodeType) && NameConstants.JCR_UUID.equals(name)) { - return new QValue[] { create(UUID.randomUUID().toString(), PropertyType.STRING) }; - } else { - throw new RepositoryException("createFromDefinition not implemented for: " + name); - } - } - //--------------------------------------------------------< Inner Class >--- /** * QValue implementation for all valid PropertyTypes * except for BINARY. * @see QValueFactoryImpl.BinaryQValue */ - private static class QValueImpl implements QValue, Serializable { + private static class QValueImpl extends AbstractQValue implements Serializable { private static final QValue TRUE = new QValueImpl(Boolean.TRUE); private static final QValue FALSE = new QValueImpl(Boolean.FALSE); - private final Object val; - private final int type; - private QValueImpl(String value, int type) { - val = value; - this.type = type; + super(value, type); } private QValueImpl(Long value) { - val = value; - type = PropertyType.LONG; + super(value); } private QValueImpl(Double value) { - val = value; - type = PropertyType.DOUBLE; + super(value); } private QValueImpl(Boolean value) { - val = value; - type = PropertyType.BOOLEAN; + super(value); } private QValueImpl(Calendar value) { - val = value; - this.type = PropertyType.DATE; + super(value, PropertyType.DATE); } private QValueImpl(Name value) { - val = value; - type = PropertyType.NAME; + super(value); } private QValueImpl(Path value) { - val = value; - type = PropertyType.PATH; + super(value); } protected String getQString(int type) throws RepositoryException { return getString(); } + //---------------------------------------------------------< QValue >--- /** - * @see QValue#getType() - */ - public int getType() { - return type; - } - - /** - * @see QValue#getLength() - */ - public long getLength() throws RepositoryException { - return getString().length(); - } - - /** * @see QValue#getString() */ public String getString() { @@ -338,7 +288,7 @@ public InputStream getStream() throws RepositoryException { try { // convert via string - return new ByteArrayInputStream(getString().getBytes(QValueFactoryImpl.DEFAULT_ENCODING)); + return new ByteArrayInputStream(getString().getBytes(DEFAULT_ENCODING)); } catch (UnsupportedEncodingException e) { throw new RepositoryException(QValueFactoryImpl.DEFAULT_ENCODING + " is not supported encoding on this platform", e); } @@ -430,63 +380,9 @@ } } - public boolean getBoolean() throws RepositoryException { - if (val instanceof Boolean) { - return ((Boolean) val).booleanValue(); - } else { - return new Boolean(getString()).booleanValue(); - } - } - /** - * @see QValue#getName() - */ - public Name getName() throws RepositoryException { - if (val instanceof Name) { - return (Name) val; - } else { - try { - return NAME_FACTORY.create(getString()); - } catch (IllegalArgumentException e) { - throw new ValueFormatException("not a valid Name value: " + getString(), e); - } - } - } - - /** - * @see QValue#getPath() - */ - public Path getPath() throws RepositoryException { - if (val instanceof Path) { - return (Path) val; - } else { - try { - return PATH_FACTORY.create(getString()); - } catch (IllegalArgumentException e) { - throw new ValueFormatException("not a valid Path value: " + getString(), e); - } - } - } - - /** - * @see QValue#discard() - */ - public void discard() { - // nothing to do - } - //---------------------------------------------------------< Object >--- /** - * Returns the string representation of this internal value. - * - * @return string representation of this internal value. - * @see Object#toString() - */ - public String toString() { - return val.toString(); - } - - /** * @see Object#equals(Object) */ public boolean equals(Object obj) { @@ -507,15 +403,7 @@ } return false; } - - /** - * @return the hashCode of the internal value object. - * @see Object#hashCode() - */ - public int hashCode() { - return val.hashCode(); - } + } - } //--------------------------------------------------------< Inner Class >--- /**