MARMOTTA-571: Ingore server-managed properties on POST creation of LDP-RS.
Project: http://git-wip-us.apache.org/repos/asf/marmotta/repo Commit: http://git-wip-us.apache.org/repos/asf/marmotta/commit/9d170cc8 Tree: http://git-wip-us.apache.org/repos/asf/marmotta/tree/9d170cc8 Diff: http://git-wip-us.apache.org/repos/asf/marmotta/diff/9d170cc8 Branch: refs/heads/master Commit: 9d170cc8e95be76978fbe28b8823e905c7dcf688 Parents: 56b14cf Author: Jakob Frank <[email protected]> Authored: Thu Nov 13 14:47:43 2014 +0100 Committer: Jakob Frank <[email protected]> Committed: Thu Nov 13 14:47:43 2014 +0100 ---------------------------------------------------------------------- .../platform/ldp/services/LdpServiceImpl.java | 32 ++----- .../ServerManagedPropertiesInterceptor.java | 95 ++++++++++++++++++++ 2 files changed, 104 insertions(+), 23 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/marmotta/blob/9d170cc8/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/services/LdpServiceImpl.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/services/LdpServiceImpl.java b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/services/LdpServiceImpl.java index 500b77b..bfdb07a 100644 --- a/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/services/LdpServiceImpl.java +++ b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/services/LdpServiceImpl.java @@ -34,6 +34,7 @@ import org.apache.marmotta.platform.ldp.patch.model.PatchLine; import org.apache.marmotta.platform.ldp.patch.parser.ParseException; import org.apache.marmotta.platform.ldp.patch.parser.RdfPatchParserImpl; import org.apache.marmotta.platform.ldp.util.LdpUtils; +import org.apache.marmotta.platform.ldp.util.ServerManagedPropertiesInterceptor; import org.apache.marmotta.platform.ldp.webservices.LdpWebService; import org.openrdf.model.*; import org.openrdf.model.impl.ValueFactoryImpl; @@ -43,7 +44,6 @@ import org.openrdf.repository.RepositoryConnection; import org.openrdf.repository.RepositoryException; import org.openrdf.repository.RepositoryResult; import org.openrdf.repository.event.base.InterceptingRepositoryConnectionWrapper; -import org.openrdf.repository.event.base.RepositoryConnectionInterceptorAdapter; import org.openrdf.rio.*; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -58,7 +58,6 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.Date; -import java.util.HashSet; import java.util.List; import java.util.Set; @@ -410,8 +409,11 @@ public class LdpServiceImpl implements LdpService { log.debug("Creating new LDP-RS, data provided as {}", rdfFormat.getName()); connection.add(container, LDP.contains, resource, ldpContext); - // FIXME: We are (are we?) allowed to filter out server-managed properties here - connection.add(stream, resource.stringValue(), rdfFormat, resource); + final InterceptingRepositoryConnectionWrapper filtered = new InterceptingRepositoryConnectionWrapper(connection.getRepository(), connection); + final ServerManagedPropertiesInterceptor managedPropertiesInterceptor = new ServerManagedPropertiesInterceptor(ldpContext, resource); + filtered.addRepositoryConnectionInterceptor(managedPropertiesInterceptor); + + filtered.add(stream, resource.stringValue(), rdfFormat, resource); return resource.stringValue(); } @@ -470,28 +472,12 @@ public class LdpServiceImpl implements LdpService { connection.clear(resource); final InterceptingRepositoryConnectionWrapper filtered = new InterceptingRepositoryConnectionWrapper(connection.getRepository(), connection); - final Set<URI> deniedProperties = new HashSet<>(); - filtered.addRepositoryConnectionInterceptor(new RepositoryConnectionInterceptorAdapter() { - @Override - public boolean add(RepositoryConnection conn, Resource subject, URI predicate, Value object, Resource... contexts) { - try { - if (connection.hasStatement(subject, predicate, object, true, ldpContext)) { - // Ignore/Strip any triple that is already present in the mgmt-context (i.e. "unchanged" props). - return true; - } else if (resource.equals(subject) && SERVER_MANAGED_PROPERTIES.contains(predicate)) { - // We do NOT allow changing server-managed properties. - deniedProperties.add(predicate); - return true; - } - } catch (RepositoryException e) { - log.error("Error while filtering server managed properties: {}", e.getMessage()); - } - return false; - } - }); + final ServerManagedPropertiesInterceptor managedPropertiesInterceptor = new ServerManagedPropertiesInterceptor(ldpContext, resource); + filtered.addRepositoryConnectionInterceptor(managedPropertiesInterceptor); filtered.add(stream, resource.stringValue(), rdfFormat, resource); + final Set<URI> deniedProperties = managedPropertiesInterceptor.getDeniedProperties(); if (!deniedProperties.isEmpty()) { final URI prop = deniedProperties.iterator().next(); log.debug("Invalid property modification in update: <{}> is a server controlled property", prop); http://git-wip-us.apache.org/repos/asf/marmotta/blob/9d170cc8/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/util/ServerManagedPropertiesInterceptor.java ---------------------------------------------------------------------- diff --git a/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/util/ServerManagedPropertiesInterceptor.java b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/util/ServerManagedPropertiesInterceptor.java new file mode 100644 index 0000000..54eeadb --- /dev/null +++ b/platform/marmotta-ldp/src/main/java/org/apache/marmotta/platform/ldp/util/ServerManagedPropertiesInterceptor.java @@ -0,0 +1,95 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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.apache.marmotta.platform.ldp.util; + +import org.apache.marmotta.platform.ldp.api.LdpService; +import org.openrdf.model.Resource; +import org.openrdf.model.URI; +import org.openrdf.model.Value; +import org.openrdf.model.impl.StatementImpl; +import org.openrdf.repository.RepositoryConnection; +import org.openrdf.repository.RepositoryException; +import org.openrdf.repository.event.base.RepositoryConnectionInterceptorAdapter; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +/** + * A ConnectionInterceptor that filters out all write operations that happen to + * <li>the <strong>managed context</strong>, or</li> + * <li>use a <strong>managed property</strong></li> + */ +public class ServerManagedPropertiesInterceptor extends RepositoryConnectionInterceptorAdapter { + + private final Logger log = LoggerFactory.getLogger(this.getClass()); + + private final URI managedContext; + private final Resource subject; + private final Set<? extends Value> managedProperties; + private final Set<URI> deniedProperties; + + public ServerManagedPropertiesInterceptor(URI managedContext, Resource subject) { + this(managedContext, subject, LdpService.SERVER_MANAGED_PROPERTIES); + } + + public ServerManagedPropertiesInterceptor(URI managedContext, Resource subject, Set<? extends Value> managedProperties) { + this.managedContext = managedContext; + this.subject = subject; + this.managedProperties = managedProperties; + deniedProperties = new HashSet<>(); + } + + @Override + public boolean add(RepositoryConnection conn, Resource subject, URI predicate, Value object, Resource... contexts) { + return isManaged(conn, subject, predicate, object, "ADD"); + } + + @Override + public boolean remove(RepositoryConnection conn, Resource subject, URI predicate, Value object, Resource... contexts) { + return isManaged(conn, subject, predicate, object, "DEL"); + } + + private boolean isManaged(RepositoryConnection conn, Resource subject, URI predicate, Value object, String operation) { + try { + if (conn.hasStatement(subject, predicate, object, true, managedContext)) { + // Ignore/Strip any triple that is already present in the mgmt-context (i.e. "unchanged" props). + if (log.isTraceEnabled()) { + log.trace("[{}] filtering out statement that is already present in the managed context: {}", operation, new StatementImpl(subject, predicate, object)); + } + return true; + } else if (this.subject.equals(subject) && managedProperties.contains(predicate)) { + // We do NOT allow changing server-managed properties. + if (log.isTraceEnabled()) { + log.trace("[{}] filtering out statement with managed propterty {}: {}", operation, predicate, new StatementImpl(subject, predicate, object)); + } + deniedProperties.add(predicate); + return true; + } + } catch (RepositoryException e) { + log.error("Error while filtering server managed properties: {}", e.getMessage()); + } + return false; + } + + public Set<URI> getDeniedProperties() { + return Collections.unmodifiableSet(deniedProperties); + } + +}
