Skip to content

Commit

Permalink
Always store in-domain URIs are reference properties, and serialize t…
Browse files Browse the repository at this point in the history
…hem in the current HTTP context
  • Loading branch information
cbeer committed Nov 4, 2014
1 parent 17e0d5e commit 1b0efdb
Show file tree
Hide file tree
Showing 10 changed files with 232 additions and 172 deletions.
Expand Up @@ -30,6 +30,8 @@
import static org.fcrepo.kernel.impl.identifiers.NodeResourceConverter.nodeToResource;
import static org.fcrepo.kernel.impl.rdf.converters.PropertyConverter.getPropertyNameFromPredicate;
import static org.fcrepo.kernel.impl.utils.FedoraTypesUtils.getClosestExistingAncestor;
import static org.fcrepo.kernel.impl.utils.FedoraTypesUtils.getPropertyType;
import static org.fcrepo.kernel.impl.utils.FedoraTypesUtils.isReferenceProperty;
import static org.modeshape.jcr.api.JcrConstants.NT_FOLDER;
import static org.slf4j.LoggerFactory.getLogger;

Expand All @@ -38,7 +40,6 @@

import javax.jcr.Node;
import javax.jcr.PathNotFoundException;
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.Value;
Expand Down Expand Up @@ -160,7 +161,7 @@ public Value createValue(final Node node,
final RDFNode data,
final String propertyName) throws RepositoryException {
final ValueFactory valueFactory = node.getSession().getValueFactory();
return createValue(valueFactory, data, nodePropertiesTools.getPropertyType(node, propertyName));
return createValue(valueFactory, data, getPropertyType(node, propertyName));
}

/**
Expand Down Expand Up @@ -267,11 +268,14 @@ public void addProperty(final FedoraResource resource,

final String propertyName =
getPropertyNameFromPredicate(node, predicate, value, namespaces);
final Value v = createValue(node, value, propertyName);
final Property property = nodePropertiesTools.appendOrReplaceNodeProperty(node, propertyName, v);

if (value.isURIResource() && idTranslator.inDomain(value.asResource())) {
nodePropertiesTools.addReferencePlaceholders(idTranslator, node, property, value.asResource());
if (value.isURIResource()
&& idTranslator.inDomain(value.asResource())
&& !isReferenceProperty(node, propertyName)) {
nodePropertiesTools.addReferencePlaceholders(idTranslator, node, propertyName, value.asResource());
} else {
final Value v = createValue(node, value, propertyName);
nodePropertiesTools.appendOrReplaceNodeProperty(node, propertyName, v);
}
}

Expand Down Expand Up @@ -322,15 +326,16 @@ public void removeProperty(final FedoraResource resource,
+ node.getPath());
}

// if the property doesn't exist, we don't need to worry about it.
if (node.hasProperty(propertyName)) {
if (objectNode.isURIResource()
&& idTranslator.inDomain(objectNode.asResource())
&& !isReferenceProperty(node, propertyName)) {
nodePropertiesTools.removeReferencePlaceholders(idTranslator,
node,
propertyName,
objectNode.asResource());
} else {
final Value v = createValue(node, objectNode, propertyName);

final Property property = nodePropertiesTools.removeNodeProperty(node, propertyName, v);

if (objectNode.isURIResource() && idTranslator.inDomain(objectNode.asResource())) {
nodePropertiesTools.removeReferencePlaceholders(idTranslator, node, property, objectNode.asResource());
}
nodePropertiesTools.removeNodeProperty(node, propertyName, v);
}
}

Expand All @@ -350,14 +355,15 @@ public Statement skolemize(final IdentifierConverter<Resource, FedoraResource> i

if (t.getSubject().isAnon()) {
skolemized = m.createStatement(getSkolemizedResource(idTranslator, skolemized.getSubject()),
t.getPredicate(),
t.getObject());
skolemized.getPredicate(),
skolemized.getObject());
} else if (idTranslator.inDomain(t.getSubject()) && t.getSubject().getURI().contains("#")) {
findOrCreateHashUri(idTranslator, t.getSubject());
}

if (t.getObject().isAnon()) {
skolemized = skolemized.changeObject(getSkolemizedResource(idTranslator, t.getObject()));
skolemized = m.createStatement(skolemized.getSubject(), skolemized.getPredicate(), getSkolemizedResource
(idTranslator, skolemized.getObject()));
} else if (t.getObject().isResource()
&& idTranslator.inDomain(t.getObject().asResource())
&& t.getObject().asResource().getURI().contains("#")) {
Expand Down
Expand Up @@ -34,8 +34,8 @@
import static com.hp.hpl.jena.rdf.model.ResourceFactory.createProperty;
import static org.fcrepo.kernel.impl.rdf.JcrRdfTools.getJcrNamespaceForRDFNamespace;
import static org.fcrepo.kernel.impl.rdf.JcrRdfTools.getRDFNamespaceForJcrNamespace;
import static org.fcrepo.kernel.impl.utils.FedoraTypesUtils.isReferenceProperty;
import static org.fcrepo.kernel.impl.utils.NodePropertiesTools.getReferencePropertyOriginalName;
import static org.fcrepo.kernel.impl.utils.FedoraTypesUtils.getReferencePropertyOriginalName;
import static org.fcrepo.kernel.impl.utils.FedoraTypesUtils.isInternalReferenceProperty;
import static org.fcrepo.kernel.utils.NamespaceTools.getNamespaceRegistry;
import static org.slf4j.LoggerFactory.getLogger;

Expand All @@ -59,7 +59,7 @@ protected Property doForward(final javax.jcr.Property property) {
final String localName = nsProperty.getLocalName();
final String rdfLocalName;

if (isReferenceProperty.apply(property)) {
if (isInternalReferenceProperty.apply(property)) {
rdfLocalName = getReferencePropertyOriginalName(localName);
} else if (localName.contains("@")) {
rdfLocalName = localName.substring(0, localName.indexOf("@"));
Expand Down
Expand Up @@ -27,11 +27,13 @@
import javax.jcr.Property;
import javax.jcr.RepositoryException;
import javax.jcr.Session;
import javax.jcr.nodetype.NodeType;
import javax.jcr.nodetype.PropertyDefinition;

import static com.google.common.base.Preconditions.checkNotNull;
import static javax.jcr.PropertyType.REFERENCE;
import static javax.jcr.PropertyType.UNDEFINED;
import static javax.jcr.PropertyType.WEAKREFERENCE;
import static org.fcrepo.kernel.impl.utils.NodePropertiesTools.REFERENCE_PROPERTY_SUFFIX;
import static org.slf4j.LoggerFactory.getLogger;

/**
Expand All @@ -43,6 +45,8 @@
*/
public abstract class FedoraTypesUtils implements FedoraJcrTypes {

public static final String REFERENCE_PROPERTY_SUFFIX = "_ref";

private static final Logger LOGGER = getLogger(FedoraTypesUtils.class);

/**
Expand Down Expand Up @@ -88,7 +92,7 @@ public boolean apply(final FedoraResource f) {
/**
* Check if a property is a reference property.
*/
public static Predicate<Property> isReferenceProperty =
public static Predicate<Property> isInternalReferenceProperty =
new Predicate<Property>() {

@Override
Expand All @@ -111,7 +115,7 @@ public boolean apply(final Property p) {

@Override
public boolean apply(final Property p) {
return isReferenceProperty.apply(p) || JcrPropertyFunctions.isBinaryContentProperty.apply(p)
return JcrPropertyFunctions.isBinaryContentProperty.apply(p)
|| isProtectedAndShouldBeHidden.apply(p);
}
};
Expand Down Expand Up @@ -166,6 +170,125 @@ public boolean apply(final Node n) {
}
};

/**
* Get the JCR property type ID for a given property name. If unsure, mark
* it as UNDEFINED.
*
* @param node the JCR node to add the property on
* @param propertyName the property name
* @return a PropertyType value
* @throws RepositoryException
*/
public static int getPropertyType(final Node node, final String propertyName)
throws RepositoryException {
LOGGER.debug("Getting type of property: {} from node: {}",
propertyName, node);
final PropertyDefinition def =
getDefinitionForPropertyName(node, propertyName);

if (def == null) {
return UNDEFINED;
}

return def.getRequiredType();
}

/**
* Determine if a given JCR property name is single- or multi- valued.
* If unsure, choose the least restrictive
* option (multivalued)
*
* @param node the JCR node to check
* @param propertyName the property name
* (which may or may not already exist)
* @return true if the property is (or could be) multivalued
* @throws RepositoryException
*/
public static boolean isMultivaluedProperty(final Node node,
final String propertyName)
throws RepositoryException {
final PropertyDefinition def =
getDefinitionForPropertyName(node, propertyName);

if (def == null) {
return true;
}

return def.isMultiple();
}

/**
* Get the property definition information (containing type and multi-value
* information)
*
* @param node the node to use for inferring the property definition
* @param propertyName the property name to retrieve a definition for
* @return a JCR PropertyDefinition, if available, or null
* @throws javax.jcr.RepositoryException
*/
public static PropertyDefinition getDefinitionForPropertyName(final Node node,
final String propertyName)
throws RepositoryException {

final NodeType primaryNodeType = node.getPrimaryNodeType();
final PropertyDefinition[] propertyDefinitions = primaryNodeType.getPropertyDefinitions();
LOGGER.debug("Looking for property name: {}", propertyName);
for (final PropertyDefinition p : propertyDefinitions) {
LOGGER.debug("Checking property: {}", p.getName());
if (p.getName().equals(propertyName)) {
return p;
}
}

for (final NodeType nodeType : node.getMixinNodeTypes()) {
for (final PropertyDefinition p : nodeType.getPropertyDefinitions()) {
if (p.getName().equals(propertyName)) {
return p;
}
}
}
return null;
}

/**
* When we add certain URI properties, we also want to leave a reference node
* @param propertyName
* @return property name as a reference
*/
public static String getReferencePropertyName(final String propertyName) {
return propertyName + REFERENCE_PROPERTY_SUFFIX;
}

/**
* Given an internal reference node property, get the original name
* @param refPropertyName
* @return original property name of the reference property
*/
public static String getReferencePropertyOriginalName(final String refPropertyName) {
final int i = refPropertyName.lastIndexOf(REFERENCE_PROPERTY_SUFFIX);

if (i < 0) {
return refPropertyName;
}
return refPropertyName.substring(0, i);
}

/**
* Check if a property definition is a reference property
* @param node
* @param propertyName
* @return
* @throws RepositoryException
*/
public static boolean isReferenceProperty(final Node node, final String propertyName) throws RepositoryException {
final PropertyDefinition propertyDefinition = getDefinitionForPropertyName(node, propertyName);

return propertyDefinition != null &&
(propertyDefinition.getRequiredType() == REFERENCE
|| propertyDefinition.getRequiredType() == WEAKREFERENCE);
}


/**
* Get the closest ancestor that current exists
*
Expand Down

0 comments on commit 1b0efdb

Please sign in to comment.