Index: extensions/modeshape-connector-store-jpa/src/main/java/org/modeshape/connector/store/jpa/util/Serializer.java =================================================================== --- extensions/modeshape-connector-store-jpa/src/main/java/org/modeshape/connector/store/jpa/util/Serializer.java (revision 2119) +++ extensions/modeshape-connector-store-jpa/src/main/java/org/modeshape/connector/store/jpa/util/Serializer.java (working copy) @@ -50,9 +50,9 @@ import org.modeshape.graph.property.Property; import org.modeshape.graph.property.PropertyFactory; import org.modeshape.graph.property.PropertyType; import org.modeshape.graph.property.Reference; +import org.modeshape.graph.property.ReferenceFactory; import org.modeshape.graph.property.UuidFactory; import org.modeshape.graph.property.ValueFactories; -import org.modeshape.graph.property.ValueFactory; import org.modeshape.graph.property.ValueFormatException; /** @@ -292,8 +292,12 @@ public class Serializer { char c = ((Character)value).charValue(); stream.writeChar(c); } else if (value instanceof Reference) { - stream.writeChar('R'); Reference ref = (Reference)value; + if (ref.isWeak()) { + stream.writeChar('W'); + } else { + stream.writeChar('R'); + } stream.writeObject(ref.getString()); references.write(ref); } else if (value instanceof Binary) { @@ -446,7 +450,6 @@ public class Serializer { assert oldUuidToNewUuid != null; UuidFactory uuidFactory = valueFactories.getUuidFactory(); - ValueFactory referenceFactory = valueFactories.getReferenceFactory(); // Read the number of properties ... int count = input.readInt(); @@ -518,6 +521,7 @@ public class Serializer { case 'R': // Reference String refValue = (String)input.readObject(); + ReferenceFactory referenceFactory = valueFactories.getReferenceFactory(); Reference ref = referenceFactory.create(refValue); try { UUID toUuid = uuidFactory.create(ref); @@ -533,6 +537,25 @@ public class Serializer { // Write the reference ... output.writeObject(refValue); break; + case 'W': + // Weak Reference + refValue = (String)input.readObject(); + referenceFactory = valueFactories.getWeakReferenceFactory(); + ref = referenceFactory.create(refValue); + try { + UUID toUuid = uuidFactory.create(ref); + String newUuid = oldUuidToNewUuid.get(toUuid.toString()); + if (newUuid != null) { + // Create a new reference ... + ref = referenceFactory.create(newUuid); + refValue = ref.getString(); + } + } catch (ValueFormatException e) { + // Unknown reference, so simply write it again ... + } + // Write the reference ... + output.writeObject(refValue); + break; case 'B': // Binary // Read the length of the content ... @@ -781,6 +804,17 @@ public class Serializer { if (references != null) references.read(ref); } break; + case 'W': + // Weak reference + refValue = (String)stream.readObject(); + ref = valueFactories.getWeakReferenceFactory().create(refValue); + if (skip) { + if (references != null) references.remove(ref); + } else { + value = ref; + if (references != null) references.read(ref); + } + break; case 'B': // Binary // Read the length of the content ... Index: extensions/modeshape-search-lucene/src/main/java/org/modeshape/search/lucene/LuceneSearchSession.java =================================================================== --- extensions/modeshape-search-lucene/src/main/java/org/modeshape/search/lucene/LuceneSearchSession.java (revision 2119) +++ extensions/modeshape-search-lucene/src/main/java/org/modeshape/search/lucene/LuceneSearchSession.java (working copy) @@ -77,6 +77,7 @@ import org.modeshape.graph.property.DateTime; import org.modeshape.graph.property.Name; import org.modeshape.graph.property.Path; import org.modeshape.graph.property.Property; +import org.modeshape.graph.property.Reference; import org.modeshape.graph.property.ValueFactories; import org.modeshape.graph.property.ValueFactory; import org.modeshape.graph.property.basic.BasicName; @@ -500,6 +501,8 @@ public class LuceneSearchSession implements WorkspaceSession { // Add a separate field for each property value ... String valueStr = processor.stringFactory.create(pathFactory.create(value)); doc.add(new Field(nameString, valueStr, rule.getStoreOption(), Field.Index.NOT_ANALYZED)); + // Add a value to the common reference value ... + doc.add(new Field(ContentIndex.REFERENCES, stringValue, Field.Store.NO, Field.Index.NOT_ANALYZED)); } continue; } @@ -512,6 +515,8 @@ public class LuceneSearchSession implements WorkspaceSession { doc.add(new Field(nameString, stringValue, rule.getStoreOption(), Field.Index.NOT_ANALYZED)); // Add a value to the common reference value ... doc.add(new Field(ContentIndex.REFERENCES, stringValue, Field.Store.NO, Field.Index.NOT_ANALYZED)); + // Add a value to the strong reference value ... + doc.add(new Field(ContentIndex.STRONG_REFERENCES, stringValue, Field.Store.NO, Field.Index.NOT_ANALYZED)); } continue; } @@ -534,7 +539,14 @@ public class LuceneSearchSession implements WorkspaceSession { doc.add(new Field(nameString, stringValue, rule.getStoreOption(), Field.Index.NOT_ANALYZED)); boolean treatedAsReference = false; - if (rule.canBeReference()) { + if (value instanceof Reference) { + Reference ref = (Reference)value; + doc.add(new Field(ContentIndex.REFERENCES, stringValue, Field.Store.YES, Field.Index.NOT_ANALYZED)); + if (!ref.isWeak()) { + doc.add(new Field(ContentIndex.STRONG_REFERENCES, stringValue, Field.Store.YES, Field.Index.NOT_ANALYZED)); + } + treatedAsReference = true; + } else if (rule.canBeReference()) { if (stringValue.length() == 36 && stringValue.charAt(8) == '-') { // The value looks like a string representation of a UUID ... try { @@ -971,7 +983,13 @@ public class LuceneSearchSession implements WorkspaceSession { Operator operator, Object value ) { String field = referenceValue.propertyName(); - if (field == null) field = LuceneSearchWorkspace.ContentIndex.REFERENCES; + if (field == null) { + if (referenceValue.includesWeakReferences()) { + field = LuceneSearchWorkspace.ContentIndex.REFERENCES; + } else { + field = LuceneSearchWorkspace.ContentIndex.STRONG_REFERENCES; + } + } ValueFactories factories = processor.valueFactories; String stringValue = processor.stringFactory.create(value); switch (operator) { Index: extensions/modeshape-search-lucene/src/main/java/org/modeshape/search/lucene/LuceneSearchWorkspace.java =================================================================== --- extensions/modeshape-search-lucene/src/main/java/org/modeshape/search/lucene/LuceneSearchWorkspace.java (revision 2119) +++ extensions/modeshape-search-lucene/src/main/java/org/modeshape/search/lucene/LuceneSearchWorkspace.java (working copy) @@ -68,6 +68,7 @@ public class LuceneSearchWorkspace implements SearchEngineWorkspace { public static final String DEPTH = "::dep"; public static final String FULL_TEXT = "::fts"; public static final String REFERENCES = "::ref"; + public static final String STRONG_REFERENCES = "::refInt"; } private final String workspaceName; Index: modeshape-graph/src/main/java/org/modeshape/graph/property/PropertyType.java =================================================================== --- modeshape-graph/src/main/java/org/modeshape/graph/property/PropertyType.java (revision 2119) +++ modeshape-graph/src/main/java/org/modeshape/graph/property/PropertyType.java (working copy) @@ -55,6 +55,7 @@ public enum PropertyType { PATH("Path", ValueComparators.PATH_COMPARATOR, new ObjectCanonicalizer(), Path.class), UUID("UUID", ValueComparators.UUID_COMPARATOR, new ObjectCanonicalizer(), UUID.class), REFERENCE("Reference", ValueComparators.REFERENCE_COMPARATOR, new ObjectCanonicalizer(), Reference.class), + WEAKREFERENCE("WeakReference", ValueComparators.REFERENCE_COMPARATOR, new ObjectCanonicalizer(), Reference.class), URI("URI", ValueComparators.URI_COMPARATOR, new ObjectCanonicalizer(), URI.class), OBJECT("Object", ValueComparators.OBJECT_COMPARATOR, new ObjectCanonicalizer(), Object.class); Index: modeshape-graph/src/main/java/org/modeshape/graph/property/Reference.java =================================================================== --- modeshape-graph/src/main/java/org/modeshape/graph/property/Reference.java (revision 2119) +++ modeshape-graph/src/main/java/org/modeshape/graph/property/Reference.java (working copy) @@ -51,4 +51,11 @@ public interface Reference extends Comparable, Serializable { */ public String getString( TextEncoder encoder ); + /** + * Determine whether this reference is considered a weak reference. + * + * @return true if this is a weak reference, or false otherwise + */ + public boolean isWeak(); + } Index: modeshape-graph/src/main/java/org/modeshape/graph/property/ValueFactories.java =================================================================== --- modeshape-graph/src/main/java/org/modeshape/graph/property/ValueFactories.java (revision 2119) +++ modeshape-graph/src/main/java/org/modeshape/graph/property/ValueFactories.java (working copy) @@ -120,7 +120,14 @@ public interface ValueFactories extends Iterable> { * * @return the factory; never null */ - ValueFactory getReferenceFactory(); + ReferenceFactory getReferenceFactory(); + + /** + * Get the value factory for {@link PropertyType#REFERENCE reference} properties. + * + * @return the factory; never null + */ + ReferenceFactory getWeakReferenceFactory(); /** * Get the value factory for {@link PropertyType#PATH path} properties. Index: modeshape-graph/src/main/java/org/modeshape/graph/property/basic/AbstractValueFactories.java =================================================================== --- modeshape-graph/src/main/java/org/modeshape/graph/property/basic/AbstractValueFactories.java (revision 2119) +++ modeshape-graph/src/main/java/org/modeshape/graph/property/basic/AbstractValueFactories.java (working copy) @@ -74,6 +74,8 @@ public abstract class AbstractValueFactories implements ValueFactories { return getPathFactory(); case REFERENCE: return getReferenceFactory(); + case WEAKREFERENCE: + return getWeakReferenceFactory(); case STRING: return getStringFactory(); case URI: Index: modeshape-graph/src/main/java/org/modeshape/graph/property/basic/ReferenceValueFactory.java =================================================================== --- modeshape-graph/src/main/java/org/modeshape/graph/property/basic/ReferenceValueFactory.java (revision 2119) +++ modeshape-graph/src/main/java/org/modeshape/graph/property/basic/ReferenceValueFactory.java (working copy) @@ -40,6 +40,7 @@ import org.modeshape.graph.property.Name; import org.modeshape.graph.property.Path; import org.modeshape.graph.property.PropertyType; import org.modeshape.graph.property.Reference; +import org.modeshape.graph.property.ReferenceFactory; import org.modeshape.graph.property.ValueFactory; import org.modeshape.graph.property.ValueFormatException; @@ -47,11 +48,15 @@ import org.modeshape.graph.property.ValueFormatException; * The standard {@link ValueFactory} for {@link PropertyType#REFERENCE} values. */ @Immutable -public class ReferenceValueFactory extends AbstractValueFactory { +public class ReferenceValueFactory extends AbstractValueFactory implements ReferenceFactory { + + private final boolean weak; public ReferenceValueFactory( TextDecoder decoder, - ValueFactory stringValueFactory ) { - super(PropertyType.REFERENCE, decoder, stringValueFactory); + ValueFactory stringValueFactory, + boolean weak ) { + super(weak ? PropertyType.WEAKREFERENCE : PropertyType.REFERENCE, decoder, stringValueFactory); + this.weak = weak; } /** @@ -61,9 +66,9 @@ public class ReferenceValueFactory extends AbstractValueFactory { if (value == null) return null; try { UUID uuid = UUID.fromString(value); - return new UuidReference(uuid); + return new UuidReference(uuid, weak); } catch (IllegalArgumentException err) { - return new StringReference(value); + return new StringReference(value, weak); } } Index: modeshape-graph/src/main/java/org/modeshape/graph/property/basic/StandardValueFactories.java =================================================================== --- modeshape-graph/src/main/java/org/modeshape/graph/property/basic/StandardValueFactories.java (revision 2119) +++ modeshape-graph/src/main/java/org/modeshape/graph/property/basic/StandardValueFactories.java (working copy) @@ -37,7 +37,7 @@ import org.modeshape.graph.property.NameFactory; import org.modeshape.graph.property.NamespaceRegistry; import org.modeshape.graph.property.PathFactory; import org.modeshape.graph.property.PropertyType; -import org.modeshape.graph.property.Reference; +import org.modeshape.graph.property.ReferenceFactory; import org.modeshape.graph.property.UuidFactory; import org.modeshape.graph.property.ValueFactory; import org.modeshape.graph.property.ValueTypeSystem; @@ -59,7 +59,8 @@ public class StandardValueFactories extends AbstractValueFactories { private final ValueFactory longFactory; private final NameFactory nameFactory; private final PathFactory pathFactory; - private final ValueFactory referenceFactory; + private final ReferenceFactory referenceFactory; + private final ReferenceFactory weakReferenceFactory; private final ValueFactory uriFactory; private final UuidFactory uuidFactory; private final ValueFactory objectFactory; @@ -119,7 +120,10 @@ public class StandardValueFactories extends AbstractValueFactories { this.nameFactory = (NameFactory)getFactory(factories, new NameValueFactory(this.namespaceRegistry, decoder, this.stringFactory)); this.pathFactory = (PathFactory)getFactory(factories, new PathValueFactory(decoder, this.stringFactory, this.nameFactory)); - this.referenceFactory = getFactory(factories, new ReferenceValueFactory(decoder, this.stringFactory)); + this.referenceFactory = (ReferenceFactory)getFactory(factories, new ReferenceValueFactory(decoder, this.stringFactory, + false)); + this.weakReferenceFactory = (ReferenceFactory)getFactory(factories, new ReferenceValueFactory(decoder, + this.stringFactory, true)); this.uuidFactory = (UuidFactory)getFactory(factories, new UuidValueFactory(decoder, this.stringFactory)); this.uriFactory = getFactory(factories, new UriValueFactory(this.namespaceRegistry, decoder, this.stringFactory)); this.objectFactory = getFactory(factories, new ObjectValueFactory(decoder, this.stringFactory, this.binaryFactory)); @@ -214,12 +218,21 @@ public class StandardValueFactories extends AbstractValueFactories { /** * {@inheritDoc} */ - public ValueFactory getReferenceFactory() { + public ReferenceFactory getReferenceFactory() { return this.referenceFactory; } /** * {@inheritDoc} + * + * @see org.modeshape.graph.property.ValueFactories#getWeakReferenceFactory() + */ + public ReferenceFactory getWeakReferenceFactory() { + return this.weakReferenceFactory; + } + + /** + * {@inheritDoc} */ public ValueFactory getStringFactory() { return this.stringFactory; Index: modeshape-graph/src/main/java/org/modeshape/graph/property/basic/StringReference.java =================================================================== --- modeshape-graph/src/main/java/org/modeshape/graph/property/basic/StringReference.java (revision 2119) +++ modeshape-graph/src/main/java/org/modeshape/graph/property/basic/StringReference.java (working copy) @@ -38,10 +38,27 @@ public class StringReference implements Reference { /** */ private static final long serialVersionUID = 2299467578161645109L; - private String id; + private/*final*/String id; + private/*final*/boolean isWeak; public StringReference( String id ) { this.id = id; + this.isWeak = false; + } + + public StringReference( String id, + boolean weak ) { + this.id = id; + this.isWeak = weak; + } + + /** + * {@inheritDoc} + * + * @see org.modeshape.graph.property.Reference#isWeak() + */ + public boolean isWeak() { + return isWeak; } /** @@ -64,6 +81,11 @@ public class StringReference implements Reference { */ public int compareTo( Reference that ) { if (this == that) return 0; + if (this.isWeak()) { + if (!that.isWeak()) return -1; + } else { + if (that.isWeak()) return 1; + } if (that instanceof StringReference) { return this.id.compareTo(((StringReference)that).getString()); } @@ -77,7 +99,8 @@ public class StringReference implements Reference { public boolean equals( Object obj ) { if (obj == this) return true; if (obj instanceof Reference) { - return this.id.equals(((Reference)obj).getString()); + Reference that = (Reference)obj; + return this.isWeak() == that.isWeak() && this.getString().equals(that.getString()); } return super.equals(obj); } Index: modeshape-graph/src/main/java/org/modeshape/graph/property/basic/UuidReference.java =================================================================== --- modeshape-graph/src/main/java/org/modeshape/graph/property/basic/UuidReference.java (revision 2119) +++ modeshape-graph/src/main/java/org/modeshape/graph/property/basic/UuidReference.java (working copy) @@ -38,10 +38,18 @@ public class UuidReference implements Reference { /** */ private static final long serialVersionUID = 2299467578161645109L; - private UUID uuid; + private/*final*/UUID uuid; + private/*final*/boolean isWeak; public UuidReference( UUID uuid ) { this.uuid = uuid; + this.isWeak = false; + } + + public UuidReference( UUID uuid, + boolean weak ) { + this.uuid = uuid; + this.isWeak = weak; } /** @@ -68,9 +76,23 @@ public class UuidReference implements Reference { /** * {@inheritDoc} + * + * @see org.modeshape.graph.property.Reference#isWeak() + */ + public boolean isWeak() { + return isWeak; + } + + /** + * {@inheritDoc} */ public int compareTo( Reference that ) { if (this == that) return 0; + if (this.isWeak()) { + if (!that.isWeak()) return -1; + } else { + if (that.isWeak()) return 1; + } if (that instanceof UuidReference) { return this.uuid.compareTo(((UuidReference)that).getUuid()); } @@ -84,10 +106,12 @@ public class UuidReference implements Reference { public boolean equals( Object obj ) { if (obj == this) return true; if (obj instanceof UuidReference) { - return this.uuid.equals(((UuidReference)obj).getUuid()); + UuidReference that = (UuidReference)obj; + return this.isWeak() == that.isWeak() && this.uuid.equals(that.getUuid()); } if (obj instanceof Reference) { - return this.getString().equals(((Reference)obj).getString()); + Reference that = (Reference)obj; + return this.isWeak() == that.isWeak() && this.getString().equals(that.getString()); } return super.equals(obj); } Index: modeshape-graph/src/main/java/org/modeshape/graph/query/QueryBuilder.java =================================================================== --- modeshape-graph/src/main/java/org/modeshape/graph/query/QueryBuilder.java (revision 2119) +++ modeshape-graph/src/main/java/org/modeshape/graph/query/QueryBuilder.java (working copy) @@ -1201,6 +1201,16 @@ public class QueryBuilder { String property ); /** + * Constrains the nodes in the the supplied table such that they must have a matching value for any of the node's non-weak + * reference properties. + * + * @param table the name of the table; may not be null and must refer to a valid name or alias of a table appearing in the + * FROM clause + * @return the interface for completing the value portion of the criteria specification; never null + */ + public ComparisonBuilder strongReferenceValue( String table ); + + /** * Constrains the nodes in the the supplied table such that they must satisfy the supplied full-text search on the nodes' * property values. * @@ -1483,6 +1493,15 @@ public class QueryBuilder { /** * {@inheritDoc} * + * @see org.modeshape.graph.query.QueryBuilder.DynamicOperandBuilder#strongReferenceValue(java.lang.String) + */ + public ComparisonBuilder strongReferenceValue( String table ) { + return comparisonBuilder(new ReferenceValue(selector(table), null, false)); + } + + /** + * {@inheritDoc} + * * @see org.modeshape.graph.query.QueryBuilder.DynamicOperandBuilder#referenceValue(java.lang.String) */ public ComparisonBuilder referenceValue( String table ) { Index: modeshape-graph/src/main/java/org/modeshape/graph/query/model/ReferenceValue.java =================================================================== --- modeshape-graph/src/main/java/org/modeshape/graph/query/model/ReferenceValue.java (revision 2119) +++ modeshape-graph/src/main/java/org/modeshape/graph/query/model/ReferenceValue.java (working copy) @@ -38,6 +38,7 @@ public class ReferenceValue implements DynamicOperand { private final Set selectorNames; private final String propertyName; private final int hc; + private final boolean includeWeakReferences; /** * Create a dynamic operand that evaluates to all of the reference values of the node identified by the selector. @@ -49,6 +50,25 @@ public class ReferenceValue implements DynamicOperand { this.selectorNames = SelectorName.nameSetFrom(selectorName); this.propertyName = null; this.hc = HashCode.compute(selectorName, this.propertyName); + this.includeWeakReferences = true; + } + + /** + * Create a dynamic operand that evaluates to the values of a single reference property of the node identified by the + * selector. + * + * @param selectorName the name of the selector + * @param propertyName the name of the property + * @param includeWeakReferences true if weak references are to be included + * @throws IllegalArgumentException if the selector name is null + */ + public ReferenceValue( SelectorName selectorName, + String propertyName, + boolean includeWeakReferences ) { + this.selectorNames = SelectorName.nameSetFrom(selectorName); + this.propertyName = propertyName; + this.hc = HashCode.compute(selectorName, this.propertyName); + this.includeWeakReferences = includeWeakReferences; } /** @@ -64,6 +84,7 @@ public class ReferenceValue implements DynamicOperand { this.selectorNames = SelectorName.nameSetFrom(selectorName); this.propertyName = propertyName; this.hc = HashCode.compute(selectorName, this.propertyName); + this.includeWeakReferences = true; } /** @@ -94,6 +115,15 @@ public class ReferenceValue implements DynamicOperand { } /** + * Get whether weak references should be included. + * + * @return true if weak references should be included, or false otherwise + */ + public boolean includesWeakReferences() { + return includeWeakReferences; + } + + /** * {@inheritDoc} * * @see java.lang.Object#toString() Index: modeshape-jcr/src/main/java/org/modeshape/jcr/AbstractJcrNode.java =================================================================== --- modeshape-jcr/src/main/java/org/modeshape/jcr/AbstractJcrNode.java (revision 2119) +++ modeshape-jcr/src/main/java/org/modeshape/jcr/AbstractJcrNode.java (working copy) @@ -77,6 +77,7 @@ import org.modeshape.graph.property.Name; import org.modeshape.graph.property.NamespaceRegistry; import org.modeshape.graph.property.Path; import org.modeshape.graph.property.PathFactory; +import org.modeshape.graph.property.Reference; import org.modeshape.graph.property.ValueFactories; import org.modeshape.graph.query.QueryBuilder; import org.modeshape.graph.query.model.QueryCommand; @@ -223,8 +224,8 @@ abstract class AbstractJcrNode extends AbstractJcrItem implements javax.jcr.Node final JcrValue valueFrom( javax.jcr.Node value ) throws UnsupportedRepositoryOperationException, RepositoryException { ValueFactories factories = cache.factories(); - String uuid = factories.getStringFactory().create(value.getIdentifier()); - return new JcrValue(factories, cache, PropertyType.REFERENCE, uuid); + Reference ref = factories.getReferenceFactory().create(value.getIdentifier()); + return new JcrValue(factories, cache, PropertyType.REFERENCE, ref); } final JcrValue[] valuesFrom( int propertyType, Index: modeshape-jcr/src/main/java/org/modeshape/jcr/JcrSession.java =================================================================== --- modeshape-jcr/src/main/java/org/modeshape/jcr/JcrSession.java (revision 2119) +++ modeshape-jcr/src/main/java/org/modeshape/jcr/JcrSession.java (working copy) @@ -79,6 +79,8 @@ import org.modeshape.graph.property.DateTime; import org.modeshape.graph.property.NamespaceRegistry; import org.modeshape.graph.property.Path; import org.modeshape.graph.property.PathFactory; +import org.modeshape.graph.property.Reference; +import org.modeshape.graph.property.ReferenceFactory; import org.modeshape.graph.property.ValueFactories; import org.modeshape.graph.property.Path.Segment; import org.modeshape.graph.query.QueryBuilder; @@ -851,8 +853,8 @@ class JcrSession implements Session { if (!value.isNodeType(JcrMixLexicon.REFERENCEABLE.getString(JcrSession.this.namespaces()))) { throw new RepositoryException(JcrI18n.nodeNotReferenceable.text()); } - String uuid = valueFactories.getStringFactory().create(value.getIdentifier()); - return new JcrValue(valueFactories, sessionCache, PropertyType.REFERENCE, uuid); + Reference ref = valueFactories.getReferenceFactory().create(value.getIdentifier()); + return new JcrValue(valueFactories, sessionCache, PropertyType.REFERENCE, ref); } @Override @@ -861,8 +863,10 @@ class JcrSession implements Session { if (!value.isNodeType(JcrMixLexicon.REFERENCEABLE.getString(JcrSession.this.namespaces()))) { throw new RepositoryException(JcrI18n.nodeNotReferenceable.text()); } - String uuid = valueFactories.getStringFactory().create(value.getIdentifier()); - return new JcrValue(valueFactories, sessionCache, PropertyType.WEAKREFERENCE, uuid); + ReferenceFactory factory = weak ? valueFactories.getWeakReferenceFactory() : valueFactories.getReferenceFactory(); + int refType = weak ? PropertyType.WEAKREFERENCE : PropertyType.REFERENCE; + Reference ref = factory.create(value.getIdentifier()); + return new JcrValue(valueFactories, sessionCache, refType, ref); } @Override @@ -1293,7 +1297,7 @@ class JcrSession implements Session { query = builder.select("jcr:primaryType") .fromAllNodesAs("allNodes") .where() - .referenceValue("allNodes") + .strongReferenceValue("allNodes") .isIn(someUuidsInBranch) .and() .path("allNodes") @@ -1304,7 +1308,7 @@ class JcrSession implements Session { query = builder.select("jcr:primaryType") .fromAllNodesAs("allNodes") .where() - .referenceValue("allNodes") + .strongReferenceValue("allNodes") .isIn(someUuidsInBranch) .end() .query(); Index: modeshape-jcr/src/main/java/org/modeshape/jcr/JcrValue.java =================================================================== --- modeshape-jcr/src/main/java/org/modeshape/jcr/JcrValue.java (revision 2119) +++ modeshape-jcr/src/main/java/org/modeshape/jcr/JcrValue.java (working copy) @@ -423,7 +423,6 @@ final class JcrValue implements Value, org.modeshape.jcr.api.Value { } case PropertyType.REFERENCE: - case PropertyType.WEAKREFERENCE: if (this.type != PropertyType.STRING && this.type != PropertyType.BINARY) { throw createValueFormatException(Node.class); } @@ -432,6 +431,15 @@ final class JcrValue implements Value, org.modeshape.jcr.api.Value { } catch (org.modeshape.graph.property.ValueFormatException vfe) { throw createValueFormatException(vfe); } + case PropertyType.WEAKREFERENCE: + if (this.type != PropertyType.STRING && this.type != PropertyType.BINARY) { + throw createValueFormatException(Node.class); + } + try { + return this.withTypeAndValue(type, valueFactories.getWeakReferenceFactory().create(value)); + } catch (org.modeshape.graph.property.ValueFormatException vfe) { + throw createValueFormatException(vfe); + } case PropertyType.DOUBLE: if (this.type != PropertyType.STRING && this.type != PropertyType.BINARY && this.type != PropertyType.LONG && this.type != PropertyType.DATE) { Index: modeshape-jcr/src/main/java/org/modeshape/jcr/NodeTypeSchemata.java =================================================================== --- modeshape-jcr/src/main/java/org/modeshape/jcr/NodeTypeSchemata.java (revision 2119) +++ modeshape-jcr/src/main/java/org/modeshape/jcr/NodeTypeSchemata.java (working copy) @@ -164,11 +164,16 @@ class NodeTypeSchemata implements Schemata { first = false; } boolean canBeReference = false; + boolean isStrongReference = false; switch (defn.getRequiredType()) { case PropertyType.REFERENCE: + isStrongReference = true; + canBeReference = true; + break; case PropertyType.WEAKREFERENCE: case PropertyType.UNDEFINED: canBeReference = true; + break; } String type = typeSystem.getDefaultType(); if (defn.getRequiredType() != PropertyType.UNDEFINED) { @@ -186,7 +191,12 @@ class NodeTypeSchemata implements Schemata { builder.addColumn(tableName, columnName, type, fullTextSearchable); // And build an indexing rule for this type ... - if (indexRuleBuilder != null) addIndexRule(indexRuleBuilder, defn, type, typeSystem, canBeReference); + if (indexRuleBuilder != null) addIndexRule(indexRuleBuilder, + defn, + type, + typeSystem, + canBeReference, + isStrongReference); } } @@ -197,14 +207,17 @@ class NodeTypeSchemata implements Schemata { * @param defn the property definition; never null * @param type the TypeSystem type, which may be a more general type than dictated by the definition, since multiple * definitions with the same name require the index rule to use the common base type; never null - * @param canBeReference true if the property described the rule can hold reference values, or false otherwise * @param typeSystem the type system; never null + * @param canBeReference true if the property described the rule can hold reference values, or false otherwise + * @param isStrongReference true if the index rule can be a reference and it should be included in referential integrity + * checks */ protected final void addIndexRule( IndexRules.Builder builder, JcrPropertyDefinition defn, String type, TypeSystem typeSystem, - boolean canBeReference ) { + boolean canBeReference, + boolean isStrongReference ) { Store store = Store.YES; Index index = defn.isFullTextSearchable() ? Index.ANALYZED : Index.NO; if (typeSystem.getStringFactory().getTypeName().equals(type)) {