http://git-wip-us.apache.org/repos/asf/jena/blob/c4b0113d/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredRDFListImpl.java ---------------------------------------------------------------------- diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredRDFListImpl.java b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredRDFListImpl.java new file mode 100644 index 0000000..060dca4 --- /dev/null +++ b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredRDFListImpl.java @@ -0,0 +1,1058 @@ +/* + * 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.jena.permissions.model.impl; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.apache.jena.graph.Node ; +import org.apache.jena.graph.Triple ; +import org.apache.jena.permissions.AccessDeniedException; +import org.apache.jena.permissions.SecurityEvaluator; +import org.apache.jena.permissions.SecurityEvaluator.Action; +import org.apache.jena.permissions.impl.ItemHolder; +import org.apache.jena.permissions.impl.SecuredItemImpl; +import org.apache.jena.permissions.impl.SecuredItemInvoker; +import org.apache.jena.permissions.model.SecuredModel; +import org.apache.jena.permissions.model.SecuredRDFList; +import org.apache.jena.permissions.model.SecuredRDFNode; +import org.apache.jena.permissions.utils.RDFListIterator; +import org.apache.jena.permissions.utils.RDFListSecFilter; +import org.apache.jena.rdf.model.* ; +import org.apache.jena.util.iterator.ExtendedIterator ; +import org.apache.jena.util.iterator.Map1 ; +import org.apache.jena.util.iterator.WrappedIterator ; +import org.apache.jena.vocabulary.RDF ; + +public class SecuredRDFListImpl extends SecuredResourceImpl implements + SecuredRDFList +{ + // called plain node but still returns a secured node + private class PlainNodeMap implements Map1<RDFList, RDFNode> + { + + @Override + public RDFNode map1( final RDFList o ) + { + return SecuredRDFNodeImpl.getInstance(getModel(), o + .getRequiredProperty(listFirst()).getObject()); + } + + } + + private class SecuredListMap implements Map1<RDFList, SecuredRDFList> + { + + @Override + public SecuredRDFList map1( final RDFList o ) + { + return SecuredRDFListImpl.getInstance(getModel(), o); + } + + } + + private class SecuredNodeMap implements Map1<RDFList, SecuredRDFNode> + { + + private Property p; + public SecuredNodeMap(Property p) + { + this.p=p; + } + + @Override + public SecuredRDFNode map1( final RDFList o ) + { + return SecuredRDFNodeImpl.getInstance(getModel(), o + .getRequiredProperty(p).getObject()); + } + + } + + /* + * private class SecuredRDFListIterator implements Iterator<SecuredRDFList> + * { + * private SecuredRDFList current; + * private Boolean found; + * private final Set<Action> restrictions; + * + * private SecuredRDFListIterator( final Action restriction ) + * { + * this(SecurityEvaluator.Util.asSet(new Action[] { restriction })); + * } + * + * private SecuredRDFListIterator( final Set<Action> restrictions ) + * { + * this.current = SecuredRDFListImpl.this.holder.getSecuredItem(); + * this.restrictions = restrictions; + * } + * + * private boolean checkCandidate() + * { + * if (!endOfList()) + * { + * final SecNode candidate = current.getRequiredProperty(listFirst()) + * .getObject().asNode(); + * return getSecurityEvaluator().evaluate( + * restrictions, + * getModelNode(), + * new SecurityEvaluator.SecTriple(SecuredItemImpl + * .convert(current.asNode()), SecuredItemImpl + * .convert(RDF.first.asNode()), SecuredItemImpl + * .convert(candidate))); + * } + * return false; + * } + * + * private boolean endOfList() + * { + * return current.equals(listNil()); + * } + * + * @Override + * public boolean hasNext() + * { + * if ((found == null) && !endOfList()) + * { + * found = checkCandidate(); + * while (!found && !endOfList()) + * { + * incrementCurrent(); + * found = checkCandidate(); + * } + * } + * return found == null ? false : found; + * } + * + * private void incrementCurrent() + * { + * if (!endOfList()) + * { + * current = (SecuredRDFList) current + * .getRequiredProperty(listRest()).getResource() + * .as(RDFList.class); + * } + * } + * + * @Override + * public SecuredRDFList next() + * { + * if (hasNext()) + * { + * found = null; + * final SecuredRDFList retval = current; + * incrementCurrent(); + * return retval; + * } + * throw new NoSuchElementException(); + * } + * + * @Override + * public void remove() + * { + * throw new UnsupportedOperationException(); + * } + * + * } + */ + /** + * Get an instance of SecuredProperty + * + * @param securedModel + * the Secured Model to use. + * @param rdfList + * The rdfList to secure + * @return The SecuredProperty + */ + public static <T extends RDFList> SecuredRDFList getInstance( final SecuredModel securedModel, + final T rdfList ) + { + if (securedModel == null) + { + throw new IllegalArgumentException( + "Secured securedModel may not be null"); + } + if (rdfList == null) + { + throw new IllegalArgumentException("RDFList may not be null"); + } + + // check that property has a securedModel. + RDFList goodList = rdfList; + if (goodList.getModel() == null) + { + goodList = securedModel.createList(rdfList.asJavaList().iterator()); + } + + final ItemHolder<RDFList, SecuredRDFList> holder = new ItemHolder<RDFList, SecuredRDFList>( + goodList); + final SecuredRDFListImpl checker = new SecuredRDFListImpl(securedModel, + holder); + // if we are going to create a duplicate proxy, just return this + // one. + if (goodList instanceof SecuredRDFList) + { + if (checker.isEquivalent((SecuredRDFList) goodList)) + { + return (SecuredRDFList) goodList; + } + } + return holder.setSecuredItem(new SecuredItemInvoker(rdfList.getClass(), + checker)); + } + + /** Error message if validity check fails */ + protected String m_errorMsg = null; + + /** Pointer to the node that is the tail of the list */ + protected RDFList m_tail = null; + + /** The URI for the 'first' property in this list */ + protected Property m_listFirst = RDF.first; + + /** The URI for the 'rest' property in this list */ + protected Property m_listRest = RDF.rest; + + /** The URI for the 'nil' Resource in this list */ + protected Resource m_listNil = RDF.nil; + + /** The URI for the rdf:type of this list */ + protected Resource m_listType = RDF.List; + + private final ItemHolder<RDFList, SecuredRDFList> holder; + + protected SecuredRDFListImpl( final SecuredModel securedModel, + final ItemHolder<RDFList, SecuredRDFList> holder ) + { + super(securedModel, holder); + this.holder = holder; + } + + @Override + public void add( final RDFNode value ) + { + checkUpdate(); + checkCreateNewList(value, listNil()); + holder.getBaseItem().add(value); + } + + @Override + public SecuredRDFList append( final Iterator<? extends RDFNode> nodes ) + { + SecuredRDFList copy = copy(); + if (nodes.hasNext()) + { + if (((RDFList)copy.getBaseItem()).size()>0) +// if (copy.size() > 0) + { + copy.concatenate(copy.getModel().createList(nodes)); + } + else + { + copy = copy.getModel().createList(nodes); + } + } + return copy; + } + + @Override + public RDFList append( final RDFList list ) + { + if (holder.getBaseItem().isEmpty()) + { + return list.size() == 0 ? ModelFactory.createDefaultModel() + .createList() : list.copy(); + } + else + { + final RDFList copy = copy(); + if (list.size() > 0) + { + copy.concatenate(list.copy()); + } + return copy; + } + } + + @Override + public void apply( final ApplyFn fn ) + { + // iterator() checks Read + final ExtendedIterator<RDFNode> i = iterator(); + try + { + while (i.hasNext()) + { + fn.apply(i.next()); + } + } + finally + { + i.close(); + } + } + + @Override + public void apply( final Set<Action> perms, final ApplyFn fn ) + { + // iterator() checks Read + final ExtendedIterator<RDFNode> i = iterator(perms); + try + { + while (i.hasNext()) + { + fn.apply(i.next()); + } + } + finally + { + i.close(); + } + } + + @Override + public List<RDFNode> asJavaList() + { + // iterator() checks Read + return iterator().toList(); + } + + /** + * Removes val from underlying list. + * + * @param val + * @return the modified RDFList. + */ + private RDFList baseRemove( final RDFList val ) + { + + RDFList prev = null; + RDFList cell = holder.getBaseItem(); + final boolean searching = true; + + while (searching && !cell.isEmpty()) + { + if (cell.equals(val)) + { + // found the value to be removed + final RDFList tail = cell.getTail(); + if (prev != null) + { + prev.setTail(tail); + } + + cell.removeProperties(); + + // return this unless we have removed the head element + return (prev == null) ? tail : this; + } + else + { + // not found yet + prev = cell; + cell = cell.getTail(); + } + } + + // not found + return this; + } + + private void checkCreateNewList( final RDFNode value, final Resource tail ) + { + checkCreate(new SecurityEvaluator.SecTriple( + SecurityEvaluator.SecNode.FUTURE, + SecuredItemImpl.convert(listFirst().asNode()), + SecuredItemImpl.convert(value.asNode()))); + checkCreate(new SecurityEvaluator.SecTriple( + SecurityEvaluator.SecNode.FUTURE, + SecuredItemImpl.convert(listRest().asNode()), + SecuredItemImpl.convert(tail.asNode()))); + } + + private Set<Statement> collectStatements( final Set<Action> actions ) + { + final Set<Statement> stmts = new HashSet<Statement>(); + final ExtendedIterator<RDFList> iter = WrappedIterator.create( + new RDFListIterator(holder.getBaseItem())).filterKeep( + new RDFListSecFilter<RDFList>(this, actions)); + try + { + while (iter.hasNext()) + { + stmts.addAll(iter.next().listProperties().toSet()); + } + return stmts; + } + finally + { + iter.close(); + } + } + + @Override + public void concatenate( final Iterator<? extends RDFNode> nodes ) + { + checkUpdate(); + if (holder.getBaseItem().isEmpty()) + { + // concatenating list onto the empty list is an error + throw new EmptyListUpdateException( + "Tried to concatenate onto the empty list"); + } + else + { + final org.apache.jena.permissions.SecurityEvaluator.SecNode p = SecuredItemImpl + .convert(listFirst().asNode()); + org.apache.jena.permissions.SecurityEvaluator.SecTriple t = new org.apache.jena.permissions.SecurityEvaluator.SecTriple( + org.apache.jena.permissions.SecurityEvaluator.SecNode.FUTURE, + p, org.apache.jena.permissions.SecurityEvaluator.SecNode.ANY); + if (!canCreate(t)) + { + final List<RDFNode> list = new ArrayList<RDFNode>(); + while (nodes.hasNext()) + { + final RDFNode n = nodes.next(); + t = new org.apache.jena.permissions.SecurityEvaluator.SecTriple( + org.apache.jena.permissions.SecurityEvaluator.SecNode.FUTURE, + p, SecuredItemImpl.convert(n.asNode())); + checkCreate(t); + list.add(n); + } + holder.getBaseItem().concatenate(list.iterator()); + + } + else + { + holder.getBaseItem().concatenate(nodes); + } + } + } + + @Override + public void concatenate( final RDFList list ) + { + checkUpdate(); + if (holder.getBaseItem().isEmpty()) + { + // concatenating list onto the empty list is an error + throw new EmptyListUpdateException( + "Tried to concatenate onto the empty list"); + } + else + { + final org.apache.jena.permissions.SecurityEvaluator.SecNode p = SecuredItemImpl + .convert(listFirst().asNode()); + org.apache.jena.permissions.SecurityEvaluator.SecTriple t = new org.apache.jena.permissions.SecurityEvaluator.SecTriple( + org.apache.jena.permissions.SecurityEvaluator.SecNode.FUTURE, + p, org.apache.jena.permissions.SecurityEvaluator.SecNode.ANY); + if (!canCreate(t)) + { + final ExtendedIterator<RDFNode> iter = list.iterator(); + try + { + while (iter.hasNext()) + { + t = new org.apache.jena.permissions.SecurityEvaluator.SecTriple( + org.apache.jena.permissions.SecurityEvaluator.SecNode.FUTURE, + p, SecuredItemImpl + .convert(iter.next().asNode())); + checkCreate(t); + } + } + finally + { + iter.close(); + } + } + holder.getBaseItem().concatenate(list); + } + } + + @Override + public SecuredRDFList cons( final RDFNode value ) + { + checkUpdate(); + checkCreateNewList(value, holder.getBaseItem()); + return SecuredRDFListImpl.getInstance(getModel(), holder.getBaseItem() + .cons(value)); + } + + @Override + public boolean contains( final RDFNode value ) + { + // iterator() checks Read + final ExtendedIterator<RDFNode> iter = iterator(); + try + { + while (iter.hasNext()) + { + if (value.equals(iter.next())) + { + return true; + } + } + return false; + } + finally + { + iter.close(); + } + } + + @Override + public SecuredRDFList copy() + { + SecuredRDFList retval = null; + if (canRead()) + { + final ExtendedIterator<RDFNode> iter = getSecuredRDFListIterator(Action.Read) + .mapWith( new Map1<RDFList, RDFNode>() + { + + @Override + public RDFNode map1( final RDFList o ) + { + return o.getRequiredProperty(listFirst()).getObject(); + } + + }); + if (iter.hasNext()) + { + retval = getModel().createList(iter); + } + else + { + retval = getModel().createList(); + } + } + else + { + retval = getModel().createList(); + } + return retval; + } + + @Override + public SecuredRDFNode get( final int i ) + { + checkRead(); + final ExtendedIterator<SecuredRDFNode> iter = getSecuredRDFListIterator( + Action.Read).mapWith(new SecuredNodeMap(listFirst())); + int idx = 0; + try + { + while (iter.hasNext()) + { + if (i == idx) + { + return iter.next(); + } + else + { + idx++; + iter.next(); + } + + } + throw new ListIndexException(); + } + finally + { + iter.close(); + } + } + + @Override + public SecuredRDFNode getHead() + { + checkRead(); + Statement s = holder.getBaseItem().getRequiredProperty( listFirst() ); + checkRead( s ); + return SecuredRDFNodeImpl.getInstance(getModel(), s.getObject()); + } + + private ExtendedIterator<RDFList> getSecuredRDFListIterator( + final Action perm ) + { + return WrappedIterator + .create(new RDFListIterator(holder.getBaseItem())).filterKeep( + new RDFListSecFilter<RDFList>(this, perm)); + } + + private ExtendedIterator<RDFList> getSecuredRDFListIterator( + final Set<Action> perm ) + { + return WrappedIterator + .create(new RDFListIterator(holder.getBaseItem())).filterKeep( + new RDFListSecFilter<RDFList>(this, perm)); + } + + @Override + public boolean getStrict() + { + return holder.getBaseItem().getStrict(); + } + + @Override + public SecuredRDFList getTail() + { + checkRead(); + Statement s = holder.getBaseItem().getRequiredProperty( listRest() ); + checkRead( s ); + return SecuredRDFListImpl.getInstance(getModel(), s.getObject().as(RDFList.class)); + } + + @Override + public String getValidityErrorMessage() + { + checkRead(); + return holder.getBaseItem().getValidityErrorMessage(); + } + + @Override + public int indexOf( final RDFNode value ) + { + checkRead(); + final ExtendedIterator<SecuredRDFNode> iter = getSecuredRDFListIterator( + Action.Read).mapWith(new SecuredNodeMap(listFirst())); + try + { + int retval = 0; + while (iter.hasNext()) + { + if (value.equals(iter.next())) + { + return retval; + } + else + { + retval++; + } + } + return -1; + } + finally + { + iter.close(); + } + } + + @Override + public int indexOf( final RDFNode value, final int start ) + { + checkRead(); + final ExtendedIterator<SecuredRDFNode> iter = getSecuredRDFListIterator( + Action.Read).mapWith(new SecuredNodeMap(listFirst())); + try + { + int retval = 0; + while (iter.hasNext() && (retval < start)) + { + iter.next(); + retval++; + } + while (iter.hasNext()) + { + if (value.equals(iter.next())) + { + return retval; + } + else + { + retval++; + } + } + return -1; + } + finally + { + iter.close(); + } + } + + @Override + public boolean isEmpty() + { + checkRead(); + final ExtendedIterator<RDFNode> iter = iterator(); + try + { + return !iter.hasNext(); + } + finally + { + iter.close(); + } + } + + @Override + public boolean isValid() + { + checkRead(); + return holder.getBaseItem().isValid(); + } + + @Override + public ExtendedIterator<RDFNode> iterator() + { + checkRead(); + return getSecuredRDFListIterator(Action.Read).mapWith( + new PlainNodeMap()); + + } + + @Override + public ExtendedIterator<RDFNode> iterator( final Set<Action> constraints ) + { + checkRead(); + final Set<Action> req = new HashSet<Action>(constraints); + req.add(Action.Read); + return getSecuredRDFListIterator(req).mapWith(new PlainNodeMap()); + + } + + public Class<? extends RDFList> listAbstractionClass() + { + return RDFList.class; + } + + public Property listFirst() + { + return m_listFirst; + } + + public Resource listNil() + { + return m_listNil; + } + + public Property listRest() + { + return m_listRest; + } + + public Resource listType() + { + return m_listType; + } + + @Override + public <T> ExtendedIterator<T> mapWith( final Map1<RDFNode, T> fn ) + { + return iterator().mapWith(fn); + } + + @Override + public Object reduce( final ReduceFn fn, final Object initial ) + { + Object acc = initial; + + for (final Iterator<RDFNode> i = iterator(); i.hasNext();) + { + acc = fn.reduce(i.next(), acc); + } + + return acc; + } + + @Override + public Object reduce( final Set<Action> requiredActions, final ReduceFn fn, + final Object initial ) throws AccessDeniedException, + EmptyListException, ListIndexException, InvalidListException + { + Object acc = initial; + final Set<Action> perms = new HashSet<Action>(requiredActions); + perms.add(Action.Read); + for (final Iterator<RDFNode> i = iterator(perms); i.hasNext();) + { + acc = fn.reduce(i.next(), acc); + } + + return acc; + } + + @Override + public RDFList remove( final RDFNode val ) + { + checkUpdate(); + RDFList cell = null; + boolean denied = false; + + if (!canDelete(new Triple(Node.ANY, listFirst().asNode(), val.asNode()))) + { + // iterate over the deletable items + final ExtendedIterator<RDFList> iter = getSecuredRDFListIterator(Action.Delete);// .mapWith(new + // SecuredListMap()); + while (iter.hasNext()) + { + cell = iter.next(); + + if (val.equals(cell.getRequiredProperty(listFirst()) + .getObject())) + { + if (canDelete(new Triple(cell.asNode(), listFirst() + .asNode(), val.asNode()))) + { + return SecuredRDFListImpl.getInstance(getModel(), + baseRemove(cell)); + + } + else + { + denied = true; + } + } + } + if (denied) + { + throw new AccessDeniedException(getModelNode(), Action.Delete); + } + else + { + return this; + } + } + else + { + return SecuredRDFListImpl.getInstance(getModel(), holder + .getBaseItem().remove(val)); + } + } + + @Override + @Deprecated + public void removeAll() + { + removeList(); + } + + @Override + public SecuredRDFList removeHead() + { + checkUpdate(); + final ExtendedIterator<SecuredRDFList> iter = getSecuredRDFListIterator( + Action.Read).mapWith(new SecuredListMap()); + try + { + if (!iter.hasNext()) + { + throw new EmptyListException( + "Attempted to delete the head of a nil list"); + } + final SecuredRDFList cell = iter.next(); + final Statement s = cell.getRequiredProperty(RDF.first); + checkDelete(s); + return SecuredRDFListImpl.getInstance(getModel(), baseRemove(cell)); + + } + finally + { + iter.close(); + } + } + + @Override + public void removeList() + { + checkUpdate(); + final Triple t = new Triple(Node.ANY, listFirst().asNode(), Node.ANY); + /* + * if (!canRead(t)) + * { + * throw new EmptyListException( + * "Attempted to delete the head of a nil list" ); + * } + */ + // have to be able to read and delete to delete all. + final Set<Action> perms = SecurityEvaluator.Util.asSet(new Action[] { + Action.Delete, Action.Read }); + if (getSecurityEvaluator().evaluate(getSecurityEvaluator().getPrincipal(), perms, this.getModelNode(), + SecuredItemImpl.convert(t))) + { + holder.getBaseItem().removeList(); + } + else + { + for (final Statement s : collectStatements(perms)) + { + if (canDelete(s.asTriple())) + { + s.remove(); + } + } + } + } + + @Override + public SecuredRDFNode replace( final int i, final RDFNode value ) + { + checkUpdate(); + final SecuredNodeMap map = new SecuredNodeMap(listFirst()); + final ExtendedIterator<SecuredRDFList> iter = getSecuredRDFListIterator( + Action.Read).mapWith(new SecuredListMap()); + int idx = 0; + try + { + while (iter.hasNext()) + { + if (i == idx) + { + final SecuredRDFList list = iter.next(); + final SecuredRDFNode retval = map.map1(list); + final Triple t = new Triple(list.asNode(), listFirst() + .asNode(), retval.asNode()); + final Triple t2 = new Triple(list.asNode(), listFirst() + .asNode(), value.asNode()); + checkUpdate(t, t2); + final RDFList base = (RDFList) list.getBaseItem(); + base.getRequiredProperty(listFirst()).changeObject(value); + return retval; + } + else + { + idx++; + iter.next(); + } + + } + throw new ListIndexException(); + } + finally + { + iter.close(); + } + } + + @Override + public boolean sameListAs( final RDFList list ) + { + checkRead(); + ExtendedIterator<RDFNode> thisIter = null; + ExtendedIterator<RDFNode> thatIter = null; + try + { + thisIter = iterator(); + thatIter = list.iterator(); + while (thisIter.hasNext() && thatIter.hasNext()) + { + final RDFNode thisN = thisIter.next(); + final RDFNode thatN = thatIter.next(); + if ((thisN == null) || !thisN.equals(thatN)) + { + // not equal at this position + return false; + } + } + return !(thisIter.hasNext() || thatIter.hasNext()); + } + finally + { + if (thisIter != null) + { + thisIter.close(); + } + if (thatIter != null) + { + thatIter.close(); + } + } + } + + @Override + public SecuredRDFNode setHead( final RDFNode value ) + { + final ExtendedIterator<SecuredRDFList> iter = getSecuredRDFListIterator( + Action.Read).mapWith(new SecuredListMap()); + try + { + if (iter.hasNext()) + { + return replace(0, value); + } + else + { + throw new EmptyListException( + "Tried to set the head of an empty list"); + } + } + finally + { + iter.close(); + } + } + + @Override + public void setStrict( final boolean strict ) + { + checkUpdate(); + holder.getBaseItem().setStrict(strict); + } + + @Override + public SecuredRDFList setTail( final RDFList tail ) + { + checkUpdate(); + + final Statement rest = holder.getBaseItem().getRequiredProperty( + listRest()); + final RDFNode retval = rest.getObject(); + final Triple t = new Triple(holder.getBaseItem().asNode(), listRest() + .asNode(), retval.asNode()); + final Triple t2 = new Triple(holder.getBaseItem().asNode(), listRest() + .asNode(), tail.asNode()); + checkUpdate(t, t2); + rest.changeObject(tail); + return SecuredRDFListImpl.getInstance(getModel(), + retval.as(RDFList.class)); + } + + @Override + public int size() + { + checkRead(); + final Triple t = new Triple(Node.ANY, listFirst().asNode(), Node.ANY); + if (canRead(t)) + { + return holder.getBaseItem().size(); + } + final ExtendedIterator<RDFNode> iter = iterator(); + int i = 0; + while (iter.hasNext()) + { + i++; + iter.next(); + } + return i; + } + + @Override + public SecuredRDFList with( final RDFNode value ) + { + checkUpdate(); + checkCreate(new SecurityEvaluator.SecTriple( + SecurityEvaluator.SecNode.FUTURE, + SecuredItemImpl.convert(listFirst().asNode()), + SecuredItemImpl.convert(value.asNode()))); + return SecuredRDFListImpl.getInstance(getModel(), holder.getBaseItem() + .with(value)); + } +}
http://git-wip-us.apache.org/repos/asf/jena/blob/c4b0113d/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredRDFNodeImpl.java ---------------------------------------------------------------------- diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredRDFNodeImpl.java b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredRDFNodeImpl.java new file mode 100644 index 0000000..aba6977 --- /dev/null +++ b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredRDFNodeImpl.java @@ -0,0 +1,253 @@ +/* + * 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.jena.permissions.model.impl; + +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import org.apache.jena.enhanced.UnsupportedPolymorphismException ; +import org.apache.jena.graph.FrontsNode ; +import org.apache.jena.graph.Node ; +import org.apache.jena.permissions.impl.ItemHolder; +import org.apache.jena.permissions.impl.SecuredItemImpl; +import org.apache.jena.permissions.model.SecuredModel; +import org.apache.jena.permissions.model.SecuredRDFNode; +import org.apache.jena.permissions.model.SecuredUnsupportedPolymorphismException; +import org.apache.jena.rdf.model.Literal ; +import org.apache.jena.rdf.model.Model ; +import org.apache.jena.rdf.model.RDFNode ; +import org.apache.jena.rdf.model.Resource ; + +/** + * Implementation of SecuredRDFNode to be used by a SecuredItemInvoker proxy. + */ +public abstract class SecuredRDFNodeImpl extends SecuredItemImpl implements + SecuredRDFNode +{ + /** + * + * @param securedModel + * the Secured Model to use. + * @param rdfNode the node to secure. + * @return the secured RDFNode + */ + public static SecuredRDFNode getInstance( final SecuredModel securedModel, + final RDFNode rdfNode ) + { + if (rdfNode instanceof Literal) + { + return SecuredLiteralImpl.getInstance(securedModel, + (Literal) rdfNode); + } + else + { + return SecuredResourceImpl.getInstance(securedModel, + (Resource) rdfNode); + } + } + + // the item holder that contains this SecuredRDFNode + private final ItemHolder<? extends RDFNode, ? extends SecuredRDFNode> holder; + + // the secured securedModel that contains this node. + private final SecuredModel securedModel; + + /** + * Constructor + * + * @param securedModel + * the Secured Model to use. + * @param holder + * the item holder that will contain this SecuredRDFNode. + */ + protected SecuredRDFNodeImpl( final SecuredModel securedModel, + final ItemHolder<? extends RDFNode, ? extends SecuredRDFNode> holder ) + { + super(securedModel, holder); + if (holder.getBaseItem().getModel() == null) + { + throw new IllegalArgumentException(String.format( + "Holder base item (%s) must have a securedModel", holder + .getBaseItem().getClass())); + } + this.securedModel = securedModel; + this.holder = holder; + } + + @SuppressWarnings( "unchecked" ) + @Override + public <T extends RDFNode> T as( final Class<T> view ) + { + checkRead(); + // see if the base Item can as + T baseAs = holder.getBaseItem().as(view); + + if (view.equals(SecuredRDFNodeImpl.class) + || view.equals(RDFNode.class)) + { + return (T) this; + } + final Method m = getConstructor(view); + if (m == null) + { + throw new SecuredUnsupportedPolymorphismException(this, view); + } + try + { + return (T) m.invoke(null, securedModel, holder.getBaseItem() + .as(view)); + } + catch (final UnsupportedPolymorphismException e) + { + throw new SecuredUnsupportedPolymorphismException(this, view); + } + catch (final IllegalArgumentException e) + { + throw new RuntimeException(e); + } + catch (final IllegalAccessException e) + { + throw new RuntimeException(e); + } + catch (final InvocationTargetException e) + { + throw new RuntimeException(e); + } + /* + else + { + throw new SecuredUnsupportedPolymorphismException(this, view); + } + */ + } + + @Override + public Node asNode() + { + checkRead(); + return holder.getBaseItem().asNode(); + } + + @Override + public <T extends RDFNode> boolean canAs( final Class<T> view ) + { + checkRead(); + // see if the base Item can as + if (holder.getBaseItem().canAs(view)) + { + return getConstructor(view) != null; + } + return false; + } + + private <T extends RDFNode> Method getConstructor( final Class<T> view ) + { + String classNm = SecuredRDFNodeImpl.class.getName(); + classNm = String.format("%s.Secured%sImpl", + classNm.substring(0, classNm.lastIndexOf(".")), + view.getSimpleName()); + try + { + final Class<?> c = Class.forName(classNm); + return c.getDeclaredMethod("getInstance", SecuredModel.class, view); + } + catch (final ClassNotFoundException e) + { + return null; + } + catch (final SecurityException e) + { + return null; + } + catch (final NoSuchMethodException e) + { + return null; + } + } + + @Override + public SecuredModel getModel() + { + return securedModel; + } + + @Override + public RDFNode inModel( final Model m ) + { + checkRead(); + if (securedModel.equals(m)) + { + return this; + } + if (m instanceof SecuredModel) + { + return SecuredRDFNodeImpl.getInstance((SecuredModel) m, holder + .getBaseItem().inModel(m)); + } + return holder.getBaseItem().inModel(m); + } + + @Override + public boolean isAnon() + { + return holder.getBaseItem().isAnon(); + } + + @Override + public boolean isLiteral() + { + return holder.getBaseItem().isLiteral(); + } + + @Override + public boolean isResource() + { + return holder.getBaseItem().isResource(); + } + + @Override + public boolean isURIResource() + { + return holder.getBaseItem().isURIResource(); + } + + /** + * An RDFNode is equal to another enhanced node n iff the underlying + * nodes are equal. We generalise to allow the other object to be any class + * implementing asNode, because we allow other implemementations of + * Resource, at least in principle. + * This is deemed to be a complete and correct interpretation of RDFNode + * equality, which is why this method has been marked final. + * + * @param o An object to test for equality with this node + * @return True if o is equal to this node. + */ + @Override final public boolean equals( Object o ) + { + checkRead(); + return o instanceof FrontsNode && asNode().equals(((FrontsNode) o).asNode()); + } + + /** + * The hash code of an RDFnode is defined to be the same as the underlying node. + * @return The hashcode as an int + */ + @Override final public int hashCode() { + return holder.getBaseItem().asNode().hashCode(); + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/c4b0113d/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredRSIterator.java ---------------------------------------------------------------------- diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredRSIterator.java b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredRSIterator.java new file mode 100644 index 0000000..6151b58 --- /dev/null +++ b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredRSIterator.java @@ -0,0 +1,174 @@ +/* + * 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.jena.permissions.model.impl; + +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.apache.jena.permissions.SecurityEvaluator; +import org.apache.jena.permissions.SecurityEvaluator.Action; +import org.apache.jena.permissions.SecurityEvaluator.SecNode; +import org.apache.jena.permissions.impl.SecuredItemImpl; +import org.apache.jena.permissions.model.SecuredModel; +import org.apache.jena.rdf.model.RSIterator ; +import org.apache.jena.rdf.model.ReifiedStatement ; +import org.apache.jena.util.iterator.ExtendedIterator ; +import org.apache.jena.util.iterator.Filter ; +import org.apache.jena.util.iterator.Map1 ; + +/** + * A secured RSIterator implementation + */ +public class SecuredRSIterator implements RSIterator +{ + private class PermReifiedStatementFilter extends Filter<ReifiedStatement> + { + private final SecurityEvaluator evaluator; + private final SecNode modelNode; + private final Set<Action> actions; + + public PermReifiedStatementFilter( final Action[] actions, + final SecuredModel securedModel ) + { + this.modelNode = securedModel.getModelNode(); + this.actions = SecurityEvaluator.Util.asSet(actions); + this.evaluator = securedModel.getSecurityEvaluator(); + } + + @Override + public boolean accept( final ReifiedStatement t ) + { + return evaluator.evaluateAny(evaluator.getPrincipal(), actions, modelNode, + SecuredItemImpl.convert(t.getStatement().asTriple())); + } + + } + + private class PermReifiedStatementMap implements + Map1<ReifiedStatement, ReifiedStatement> + { + private final SecuredModel securedModel; + + public PermReifiedStatementMap( final SecuredModel securedModel ) + { + this.securedModel = securedModel; + } + + @Override + public ReifiedStatement map1( final ReifiedStatement o ) + { + return SecuredReifiedStatementImpl.getInstance(securedModel, o); + } + } + + private final ExtendedIterator<ReifiedStatement> iter; + + /** + * Constructor + * + * @param securedModel + * The secured model that provides the security context + * @param wrapped + * The wrapped iterator. + */ + public SecuredRSIterator( final SecuredModel securedModel, + final ExtendedIterator<ReifiedStatement> wrapped ) + { + final PermReifiedStatementFilter filter = new PermReifiedStatementFilter( + new Action[] { Action.Read }, securedModel); + final PermReifiedStatementMap map1 = new PermReifiedStatementMap( + securedModel); + iter = wrapped.filterKeep(filter).mapWith(map1); + } + + @Override + public <X extends ReifiedStatement> ExtendedIterator<ReifiedStatement> andThen( + final Iterator<X> other ) + { + return iter.andThen(other); + } + + @Override + public void close() + { + iter.close(); + } + + @Override + public ExtendedIterator<ReifiedStatement> filterDrop( + final Filter<ReifiedStatement> f ) + { + return iter.filterDrop(f); + } + + @Override + public ExtendedIterator<ReifiedStatement> filterKeep( + final Filter<ReifiedStatement> f ) + { + return iter.filterKeep(f); + } + + @Override + public boolean hasNext() + { + return iter.hasNext(); + } + + @Override + public <U> ExtendedIterator<U> mapWith( final Map1<ReifiedStatement, U> map1 ) + { + return iter.mapWith(map1); + } + + @Override + public ReifiedStatement next() + { + return iter.next(); + } + + @Override + public ReifiedStatement nextRS() + { + return next(); + } + + @Override + public void remove() + { + iter.remove(); + } + + @Override + public ReifiedStatement removeNext() + { + return iter.removeNext(); + } + + @Override + public List<ReifiedStatement> toList() + { + return iter.toList(); + } + + @Override + public Set<ReifiedStatement> toSet() + { + return iter.toSet(); + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/c4b0113d/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredReifiedStatementImpl.java ---------------------------------------------------------------------- diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredReifiedStatementImpl.java b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredReifiedStatementImpl.java new file mode 100644 index 0000000..b085598 --- /dev/null +++ b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredReifiedStatementImpl.java @@ -0,0 +1,99 @@ +/* + * 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.jena.permissions.model.impl; + +import org.apache.jena.permissions.impl.ItemHolder; +import org.apache.jena.permissions.impl.SecuredItemInvoker; +import org.apache.jena.permissions.model.SecuredModel; +import org.apache.jena.permissions.model.SecuredReifiedStatement; +import org.apache.jena.permissions.model.SecuredStatement; +import org.apache.jena.rdf.model.ReifiedStatement ; + +/** + * Implementation of SecuredReifiedStatement to be used by a SecuredItemInvoker + * proxy. + */ +public class SecuredReifiedStatementImpl extends SecuredResourceImpl implements + SecuredReifiedStatement +{ + /** + * Get an instance of SecuredReifiedStatement + * + * @param securedModel + * the Secured Model to use. + * @param stmt + * The ReifiedStatement to secure. + * @return SecuredReifiedStatement + */ + public static SecuredReifiedStatement getInstance( + final SecuredModel securedModel, final ReifiedStatement stmt ) + { + if (securedModel == null) + { + throw new IllegalArgumentException( + "Secured securedModel may not be null"); + } + if (stmt == null) + { + throw new IllegalArgumentException("Statement may not be null"); + } + final ItemHolder<ReifiedStatement, SecuredReifiedStatement> holder = new ItemHolder<ReifiedStatement, SecuredReifiedStatement>( + stmt); + final SecuredReifiedStatementImpl checker = new SecuredReifiedStatementImpl( + securedModel, holder); + // if we are going to create a duplicate proxy, just return this + // one. + if (stmt instanceof SecuredReifiedStatement) + { + if (checker.isEquivalent((SecuredReifiedStatement) stmt)) + { + return (SecuredReifiedStatement) stmt; + } + } + return holder.setSecuredItem(new SecuredItemInvoker(stmt.getClass(), + checker)); + } + + // the item holder that contains this SecuredResource + private final ItemHolder<? extends ReifiedStatement, ? extends SecuredReifiedStatement> holder; + + /** + * Constructor + * + * @param securedModel + * The secured model to use + * @param holder + * the item holder that will contain this SecuredReifiedStatement + */ + protected SecuredReifiedStatementImpl( + final SecuredModel securedModel, + final ItemHolder<? extends ReifiedStatement, ? extends SecuredReifiedStatement> holder ) + { + super(securedModel, holder); + this.holder = holder; + } + + @Override + public SecuredStatement getStatement() + { + checkRead(); + return SecuredStatementImpl.getInstance(getModel(), holder + .getBaseItem().getStatement()); + } + +} http://git-wip-us.apache.org/repos/asf/jena/blob/c4b0113d/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredResIterator.java ---------------------------------------------------------------------- diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredResIterator.java b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredResIterator.java new file mode 100644 index 0000000..e681de3 --- /dev/null +++ b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredResIterator.java @@ -0,0 +1,133 @@ +/* + * 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.jena.permissions.model.impl; + +import java.util.Iterator; +import java.util.List; +import java.util.Set; + +import org.apache.jena.permissions.model.SecuredModel; +import org.apache.jena.permissions.model.SecuredResource; +import org.apache.jena.rdf.model.ResIterator ; +import org.apache.jena.rdf.model.Resource ; +import org.apache.jena.util.iterator.ExtendedIterator ; +import org.apache.jena.util.iterator.Filter ; +import org.apache.jena.util.iterator.Map1 ; + +public class SecuredResIterator implements ResIterator +{ + + private class PermResourceMap implements Map1<Resource, Resource> + { + private final SecuredModel securedModel; + + public PermResourceMap( final SecuredModel securedModel ) + { + this.securedModel = securedModel; + } + + @Override + public SecuredResource map1( final Resource o ) + { + return SecuredResourceImpl.getInstance(securedModel, o); + } + } + + private final ExtendedIterator<Resource> iter; + + public SecuredResIterator( final SecuredModel securedModel, + final ExtendedIterator<Resource> wrapped) + { + + final PermResourceMap map1 = new PermResourceMap(securedModel); + iter = wrapped.mapWith(map1); + } + + @Override + public <X extends Resource> ExtendedIterator<Resource> andThen( + final Iterator<X> other ) + { + return iter.andThen(other); + } + + @Override + public void close() + { + iter.close(); + } + + @Override + public ExtendedIterator<Resource> filterDrop( final Filter<Resource> f ) + { + return iter.filterDrop(f); + } + + @Override + public ExtendedIterator<Resource> filterKeep( final Filter<Resource> f ) + { + return iter.filterKeep(f); + } + + @Override + public boolean hasNext() + { + return iter.hasNext(); + } + + @Override + public <U> ExtendedIterator<U> mapWith( final Map1<Resource, U> map1 ) + { + return iter.mapWith(map1); + } + + @Override + public Resource next() + { + return iter.next(); + } + + @Override + public Resource nextResource() + { + return next(); + } + + @Override + public void remove() + { + iter.remove(); + } + + @Override + public Resource removeNext() + { + return iter.removeNext(); + } + + @Override + public List<Resource> toList() + { + return iter.toList(); + } + + @Override + public Set<Resource> toSet() + { + return iter.toSet(); + } +} http://git-wip-us.apache.org/repos/asf/jena/blob/c4b0113d/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredResourceImpl.java ---------------------------------------------------------------------- diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredResourceImpl.java b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredResourceImpl.java new file mode 100644 index 0000000..3a19867 --- /dev/null +++ b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredResourceImpl.java @@ -0,0 +1,893 @@ +/* + * 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.jena.permissions.model.impl; + +import org.apache.jena.datatypes.RDFDatatype ; +import org.apache.jena.graph.Node ; +import org.apache.jena.graph.NodeFactory ; +import org.apache.jena.graph.Triple ; +import org.apache.jena.permissions.AccessDeniedException; +import org.apache.jena.permissions.SecurityEvaluator.Action; +import org.apache.jena.permissions.impl.ItemHolder; +import org.apache.jena.permissions.impl.SecuredItemImpl; +import org.apache.jena.permissions.impl.SecuredItemInvoker; +import org.apache.jena.permissions.model.SecuredModel; +import org.apache.jena.permissions.model.SecuredResource; +import org.apache.jena.permissions.model.SecuredStatement; +import org.apache.jena.permissions.utils.PermStatementFilter; +import org.apache.jena.rdf.model.* ; +import org.apache.jena.shared.PropertyNotFoundException ; +import org.apache.jena.util.iterator.ExtendedIterator ; + +/** + * Implementation of SecuredResource to be used by a SecuredItemInvoker proxy. + */ +public class SecuredResourceImpl extends SecuredRDFNodeImpl implements + SecuredResource +{ + /** + * Get a SecuredResource. + * + * @param securedModel + * the securedItem that provides the security context. + * @param resource + * The resource to secure. + * @return The SecuredResource + */ + public static SecuredResource getInstance( final SecuredModel securedModel, + final Resource resource ) + { + if (securedModel == null) + { + throw new IllegalArgumentException( + "Secured securedModel may not be null"); + } + if (resource == null) + { + throw new IllegalArgumentException("Resource may not be null"); + } + if (resource.isLiteral()) + { + throw new IllegalArgumentException("Resource may not be a literal"); + } + // check that resource has a securedModel. + Resource goodResource = resource; + if (goodResource.getModel() == null) + { + final Node n = resource.asNode(); + if (resource.isAnon()) + { + goodResource = securedModel.createResource(n.getBlankNodeId()); + } + else + { + goodResource = securedModel.createResource(n.getURI()); + } + } + + final ItemHolder<Resource, SecuredResource> holder = new ItemHolder<Resource, SecuredResource>( + goodResource); + + final SecuredResourceImpl checker = new SecuredResourceImpl( + securedModel, holder); + // if we are going to create a duplicate proxy, just return this + // one. + if (goodResource instanceof SecuredResource) + { + if (checker.isEquivalent((SecuredResource) goodResource)) + { + return (SecuredResource) goodResource; + } + } + + return holder.setSecuredItem(new SecuredItemInvoker( + resource.getClass(), checker)); + + } + + // the item holder that contains this SecuredResource + private final ItemHolder<? extends Resource, ? extends SecuredResource> holder; + + /** + * Constructor. + * + * @param securedModel + * The secured model to use + * @param holder + * the item holder that will contain this SecuredResource. + */ + protected SecuredResourceImpl( + final SecuredModel securedModel, + final ItemHolder<? extends Resource, ? extends SecuredResource> holder ) + { + super(securedModel, holder); + this.holder = holder; + } + + /** + * Abort the transaction in the associated securedModel. + * + * @return This resource to permit cascading. + */ + @Override + public SecuredResource abort() + { + holder.getBaseItem().abort(); + return holder.getSecuredItem(); + } + + /** + * Add the property <code>p</code> with the typed-literal value + * <code>o</code> to this resource, <i>ie</i> add (this, p, typed(o)) to + * this's securedModel. Answer + * this resource. The typed literal is equal to one constructed by using + * <code>this.getModel().createTypedLiteral(o)</code>. + */ + @Override + public SecuredResource addLiteral( final Property p, final boolean o ) + { + return addProperty( p, ResourceFactory.createTypedLiteral(o) ); + } + + /** + * Add the property <code>p</code> with the typed-literal value + * <code>o</code> to this resource, <i>ie</i> add (this, p, typed(o)) to + * this's securedModel. Answer + * this resource. The typed literal is equal to one constructed by using + * <code>this.getModel().createTypedLiteral(o)</code>. + */ + @Override + public SecuredResource addLiteral( final Property p, final char o ) + { + return addProperty( p, ResourceFactory.createTypedLiteral(o)); + } + + /** + * Add the property <code>p</code> with the typed-literal value + * <code>o</code> to this resource, <i>ie</i> add (this, p, typed(o)) to + * this's securedModel. Answer + * this resource. The typed literal is equal to one constructed by using + * <code>this.getModel().createTypedLiteral(o)</code>. + */ + @Override + public SecuredResource addLiteral( final Property value, final double d ) + { + return addProperty( value, ResourceFactory.createTypedLiteral(d)); + } + + /** + * Add the property <code>p</code> with the typed-literal value + * <code>o</code> to this resource, <i>ie</i> add (this, p, typed(o)) to + * this's securedModel. Answer + * this resource. The typed literal is equal to one constructed by using + * <code>this.getModel().createTypedLiteral(o)</code>. + */ + @Override + public SecuredResource addLiteral( final Property value, final float d ) + { + return addProperty( value, ResourceFactory.createTypedLiteral(d) ); + } + + /** + * Add the property <code>p</code> with the pre-constructed Literal value + * <code>o</code> to this resource, <i>ie</i> add (this, p, o) to this's + * securedModel. Answer this resource. <b>NOTE</b> thjat this is distinct + * from the + * other addLiteral methods in that the Literal is not turned into a + * Literal. + */ + @Override + public SecuredResource addLiteral( final Property p, final Literal o ) + { + return addProperty( p, o ); + } + + /** + * Add the property <code>p</code> with the typed-literal value + * <code>o</code> to this resource, <i>ie</i> add (this, p, typed(o)) to + * this's securedModel. Answer + * this resource. The typed literal is equal to one constructed by using + * <code>this.getModel().createTypedLiteral(o)</code>. + */ + @Override + public SecuredResource addLiteral( final Property p, final long o ) + { + return addProperty( p, ResourceFactory.createTypedLiteral(o)); + } + + /** + * Add the property <code>p</code> with the typed-literal value + * <code>o</code> to this resource, <i>ie</i> add (this, p, typed(o)) to + * this's securedModel. Answer + * this resource. The typed literal is equal to one constructed by using + * <code>this.getModel().createTypedLiteral(o)</code>. + */ + @Override + public SecuredResource addLiteral( final Property p, final Object o ) + { + return addProperty( p, ResourceFactory.createTypedLiteral(o)); + } + + /** + * Add a property to this resource. + * + * <p> + * A statement with this resource as the subject, p as the predicate and o + * as the object is added to the securedModel associated with this resource. + * </p> + * + * @param p + * The property to be added. + * @param o + * The value of the property to be added. + * @return This resource to allow cascading calls. + */ + @Override + public SecuredResource addProperty( final Property p, final RDFNode o ) + { + checkUpdate(); + checkCreate(new Triple(holder.getBaseItem().asNode(), p.asNode(), + o.asNode())); + holder.getBaseItem().addProperty(p, o); + return holder.getSecuredItem(); + } + + /** + * Add a property to this resource. + * + * <p> + * A statement with this resource as the subject, p as the predicate and o + * as the object is added to the securedModel associated with this resource. + * </p> + * + * @param p + * The property to be added. + * @param o + * The value of the property to be added. + * @return This resource to allow cascading calls. + */ + @Override + public SecuredResource addProperty( final Property p, final String o ) + { + return addProperty( p, o, ""); + } + + /** + * Add a property to this resource. + * + * <p> + * A statement with this resource as the subject, p as the predicate and o + * as the object is added to the securedModel associated with this resource. + * </p> + * + * @param p + * The property to be added. + * @param lexicalForm + * The lexical form of the literal + * @param datatype + * The datatype + * @return This resource to allow cascading calls. + */ + @Override + public SecuredResource addProperty( final Property p, final String lexicalForm, + final RDFDatatype datatype ) + { + checkUpdate(); + final Literal l = ResourceFactory.createTypedLiteral(lexicalForm, + datatype); + checkCreate(new Triple(holder.getBaseItem().asNode(), p.asNode(), + l.asNode())); + holder.getBaseItem().addProperty(p, l); + return holder.getSecuredItem(); + } + + /** + * Add a property to this resource. + * + * <p> + * A statement with this resource as the subject, p as the predicate and o + * as the object is added to the securedModel associated with this resource. + * </p> + * + * @param p + * The property to be added. + * @param o + * The value of the property to be added. + * @param l + * the language of the property + * @return This resource to allow cascading calls. + */ + @Override + public SecuredResource addProperty( final Property p, final String o, + final String l ) + { + checkUpdate(); + checkCreate(new Triple(holder.getBaseItem().asNode(), p.asNode(), + NodeFactory.createLiteral(o, l, false))); + holder.getBaseItem().addProperty(p, o, l); + return holder.getSecuredItem(); + } + + @Override + public Literal asLiteral() + { + throw new LiteralRequiredException(asNode()); + } + + @Override + public SecuredResource asResource() + { + return holder.getSecuredItem(); + } + + /** + * Begin a transaction in the associated securedModel. + * + * @return This resource to permit cascading. + */ + @Override + public SecuredResource begin() + { + holder.getBaseItem().begin(); + return holder.getSecuredItem(); + } + + public boolean canReadProperty( final Node p ) + { + return canRead(new Triple(holder.getBaseItem().asNode(), p, Node.ANY)); + } + + protected void checkReadProperty( final Node p ) + { + if (!canReadProperty(p)) + { + throw new AccessDeniedException(getModelNode(), SecuredItemImpl + .convert( + new Triple(holder.getBaseItem().asNode(), p, + Node.ANY)).toString(), Action.Read); + } + } + + /** + * Commit the transaction in the associated securedModel. + * + * @return This resource to permit cascading. + */ + @Override + public SecuredResource commit() + { + holder.getBaseItem().commit(); + return holder.getSecuredItem(); + } + + /** + * Returns an a unique identifier for anonymous resources. + * + * <p> + * The id is unique within the scope of a particular implementation. All + * models within an implementation will use the same id for the same + * anonymous resource. + * </p> + * + * <p> + * This method is undefined if called on resources which are not anonymous + * and may raise an exception. + * </p> + * + * @return A unique id for an anonymous resource. + */ + @Override + public AnonId getId() + { + checkRead(); + return holder.getBaseItem().getId(); + + } + + /** + * Returns the name of this resource within its namespace. + * + * @return The name of this property within its namespace. + */ + @Override + public String getLocalName() + { + checkRead(); + return holder.getBaseItem().getLocalName(); + } + + /** + * Returns the namespace associated with this resource. + * + * @return The namespace for this property. + */ + @Override + public String getNameSpace() + { + checkRead(); + return holder.getBaseItem().getNameSpace(); + } + + /** + * Answer some statement (this, p, O) in the associated securedModel. If + * there are + * several + * such statements, any one of them may be returned. If no such statements + * exist, + * null is returned - in this is differs from getRequiredProperty. + * + * @param p + * the property sought + * @return a statement (this, p, O), or null if no such statements exist + * here + */ + @Override + public SecuredStatement getProperty( final Property p ) + { + checkRead(); + final ExtendedIterator<Statement> iter = holder.getBaseItem() + .listProperties(p) + .filterKeep(new PermStatementFilter(Action.Read, this)); + try + { + if (iter.hasNext()) + { + return org.apache.jena.permissions.model.impl.SecuredStatementImpl + .getInstance(getModel(), iter.next()); + } + else + { + return null; + } + } + finally + { + iter.close(); + } + } + + /** + * Answer some resource R for which this.hasProperty( p, R ), + * or null if no such R exists. + */ + @Override + public SecuredResource getPropertyResourceValue( final Property p ) + { + final SecuredStatementIterator iter = listProperties(p); + try + { + while (iter.hasNext()) + { + final Statement s = iter.next(); + if (s.getObject().isResource()) + { + return SecuredResourceImpl.getInstance(getModel(), s + .getObject().asResource()); + } + } + return null; + } + finally + { + iter.close(); + } + } + + /** + * Get a property value of this resource. + * + * <p> + * The securedModel associated with the resource instance is searched for + * statements whose subject is this resource and whose predicate is p. If + * such a statement is found, it is returned. If several such statements are + * found, any one may be returned. If no such statements are found, an + * exception is thrown. + * </p> + * + * @param p + * The property sought. + * @return some (this, p, ?O) statement if one exists + * @throws PropertyNotFoundException + * if no such statement found + */ + @Override + public SecuredStatement getRequiredProperty( final Property p ) + throws PropertyNotFoundException + { + checkRead(); + final ExtendedIterator<Statement> iter = holder.getBaseItem() + .listProperties(p) + .filterKeep(new PermStatementFilter(Action.Read, this)); + try + { + if (iter.hasNext()) + { + return org.apache.jena.permissions.model.impl.SecuredStatementImpl + .getInstance(getModel(), iter.next()); + } + else + { + throw new PropertyNotFoundException(p); + } + } + finally + { + iter.close(); + } + // return org.apache.jena.security.model.impl.Factory.getInstance( + // this, holder.getBaseItem().getRequiredProperty(p)); + } + + /** + * Return the URI of the resource, or null if it's a bnode. + * + * @return The URI of the resource, or null if it's a bnode. + */ + @Override + public String getURI() + { + checkRead(); + return holder.getBaseItem().getURI(); + } + + /** + * Answer true iff this resource has the value <code>o</code> for + * property <code>p</code>. <code>o</code> is interpreted as + * a typed literal with the appropriate RDF type. + */ + @Override + public boolean hasLiteral( final Property p, final boolean o ) + { + checkRead(); + checkRead(new Triple(holder.getBaseItem().asNode(), p.asNode(), + ResourceFactory.createTypedLiteral(o).asNode())); + return holder.getBaseItem().hasLiteral(p, o); + } + + /** + * Answer true iff this resource has the value <code>o</code> for + * property <code>p</code>. <code>o</code> is interpreted as + * a typed literal with the appropriate RDF type. + */ + @Override + public boolean hasLiteral( final Property p, final char o ) + { + checkRead(); + checkRead(new Triple(holder.getBaseItem().asNode(), p.asNode(), + ResourceFactory.createTypedLiteral(o).asNode())); + return holder.getBaseItem().hasLiteral(p, o); + } + + /** + * Answer true iff this resource has the value <code>o</code> for + * property <code>p</code>. <code>o</code> is interpreted as + * a typed literal with the appropriate RDF type. + */ + @Override + public boolean hasLiteral( final Property p, final double o ) + { + checkRead(); + checkRead(new Triple(holder.getBaseItem().asNode(), p.asNode(), + ResourceFactory.createTypedLiteral(o).asNode())); + return holder.getBaseItem().hasLiteral(p, o); + } + + /** + * Answer true iff this resource has the value <code>o</code> for + * property <code>p</code>. <code>o</code> is interpreted as + * a typed literal with the appropriate RDF type. + */ + @Override + public boolean hasLiteral( final Property p, final float o ) + { + checkRead(); + checkRead(new Triple(holder.getBaseItem().asNode(), p.asNode(), + ResourceFactory.createTypedLiteral(o).asNode())); + return holder.getBaseItem().hasLiteral(p, o); + } + + /** + * Answer true iff this resource has the value <code>o</code> for + * property <code>p</code>. <code>o</code> is interpreted as + * a typed literal with the appropriate RDF type. + */ + @Override + public boolean hasLiteral( final Property p, final long o ) + { + checkRead(); + checkRead(new Triple(holder.getBaseItem().asNode(), p.asNode(), + ResourceFactory.createTypedLiteral(o).asNode())); + return holder.getBaseItem().hasLiteral(p, o); + } + + /** + * Answer true iff this resource has the value <code>o</code> for + * property <code>p</code>. <code>o</code> is interpreted as + * a typed literal with the appropriate RDF type. + */ + @Override + public boolean hasLiteral( final Property p, final Object o ) + { + checkRead(); + checkRead(new Triple(holder.getBaseItem().asNode(), p.asNode(), + ResourceFactory.createTypedLiteral(o).asNode())); + return holder.getBaseItem().hasLiteral(p, o); + } + + /** + * Determine whether this resource has any values for a given property. + * + * @param p + * The property sought. + * @return true if and only if this resource has at least one + * value for the property. + */ + @Override + public boolean hasProperty( final Property p ) + { + checkRead(); + final ExtendedIterator<Statement> iter = holder.getBaseItem() + .listProperties(p) + .filterKeep(new PermStatementFilter(Action.Read, this)); + try + { + return iter.hasNext(); + } + finally + { + iter.close(); + } + } + + /** + * Test if this resource has a given property with a given value. + * + * @param p + * The property sought. + * @param o + * The value of the property sought. + * @return true if and only if this resource has property p with + * value o. + */ + @Override + public boolean hasProperty( final Property p, final RDFNode o ) + { + checkRead(); + final ExtendedIterator<Statement> iter = holder.getBaseItem() + .getModel().listStatements(this, p, o) + .filterKeep(new PermStatementFilter(Action.Read, this)); + try + { + return iter.hasNext(); + } + finally + { + iter.close(); + } + } + + /** + * Test if this resource has a given property with a given value. + * + * @param p + * The property sought. + * @param o + * The value of the property sought. + * @return true if and only if this resource has property p with + * value o. + */ + @Override + public boolean hasProperty( final Property p, final String o ) + { + checkRead(); + final ExtendedIterator<Statement> iter = holder.getBaseItem() + .getModel().listStatements(this, p, o) + .filterKeep(new PermStatementFilter(Action.Read, this)); + try + { + return iter.hasNext(); + } + finally + { + iter.close(); + } + } + + /** + * Test if this resource has a given property with a given value. + * + * @param p + * The property sought. + * @param o + * The value of the property sought. + * @param l + * The language of the property sought. + * @return true if and only if this resource has property p with + * value o. + */ + @Override + public boolean hasProperty( final Property p, final String o, final String l ) + { + checkRead(); + final Literal ll = holder.getBaseItem().getModel().createLiteral(o, l); + final ExtendedIterator<Statement> iter = holder.getBaseItem() + .getModel().listStatements(this, p, ll) + .filterKeep(new PermStatementFilter(Action.Read, this)); + try + { + return iter.hasNext(); + } + finally + { + iter.close(); + } + } + + /** + * Answer true iff this Resource is a URI resource with the given URI. + * Using this is preferred to using getURI() and .equals(). + */ + @Override + public boolean hasURI( final String uri ) + { + checkRead(); + return holder.getBaseItem().hasURI(uri); + } + + @Override + public Resource inModel( final Model m ) + { + return (Resource) super.inModel(m); + } + + /** + * Return an iterator over all the properties of this resource. + * + * <p> + * The securedModel associated with this resource is search and an iterator + * is returned which iterates over all the statements which have this + * resource as a subject. + * </p> + * + * @return An iterator over all the statements about this object. + */ + @Override + public SecuredStatementIterator listProperties() + { + checkRead(); + return new SecuredStatementIterator(getModel(), holder.getBaseItem() + .listProperties()); + } + + /** + * List all the values of the property p. + * + * <p> + * Returns an iterator over all the statements in the associated + * securedModel whose subject is this resource and whose predicate is p. + * </p> + * + * @param p + * The predicate sought. + * @return An iterator over the statements. + */ + @Override + public SecuredStatementIterator listProperties( final Property p ) + { + checkRead(); + return new SecuredStatementIterator(getModel(), holder.getBaseItem() + .listProperties(p)); + + } + + /** + * Delete all the statements with predicate <code>p</code> for this resource + * from its associated securedModel. + * + * @param p + * the property to remove + * @return this resource, to permit cascading + */ + @Override + public SecuredResource removeAll( final Property p ) + { + checkUpdate(); + if (!canDelete(new Triple(holder.getBaseItem().asNode(), p.asNode(), + Node.ANY))) + { + final StmtIterator iter = holder.getBaseItem().listProperties(p); + try + { + if (!iter.hasNext()) + { + // thre arn't any to delete -- so return + return holder.getSecuredItem(); + } + while (iter.hasNext()) + { + checkDelete(iter.next().asTriple()); + } + } + finally + { + iter.close(); + } + } + holder.getBaseItem().removeAll(p); + return holder.getSecuredItem(); + } + + /** + * Delete all the properties for this resource from the associated + * securedModel. + * + * @return This resource to permit cascading. + */ + @Override + public SecuredResource removeProperties() + { + checkUpdate(); + if (!canDelete(new Triple(holder.getBaseItem().asNode(), Node.ANY, + Node.ANY))) + { + final StmtIterator iter = holder.getBaseItem().listProperties(); + try + { + if (!iter.hasNext()) + { + // thre arn't any to delete -- so return + return holder.getSecuredItem(); + } + while (iter.hasNext()) + { + checkDelete(iter.next().asTriple()); + } + } + finally + { + iter.close(); + } + } + holder.getBaseItem().removeProperties(); + return holder.getSecuredItem(); + } + + /** + * Return a string representation of the resource. + * + * Returns the URI of the resource unless the resource is anonymous + * in which case it returns the id of the resource enclosed in square + * brackets. + * + * @return Return a string representation of the resource. + * if it is anonymous. + */ + @Override + public String toString() + { + return holder.getBaseItem().toString(); + } + + @Override + public Object visitWith( final RDFVisitor rv ) + { + return isAnon() ? rv.visitBlank(this, getId()) : rv.visitURI(this, + getURI()); + } + +} http://git-wip-us.apache.org/repos/asf/jena/blob/c4b0113d/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredSelector.java ---------------------------------------------------------------------- diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredSelector.java b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredSelector.java new file mode 100644 index 0000000..9c18699 --- /dev/null +++ b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredSelector.java @@ -0,0 +1,94 @@ +/* + * 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.jena.permissions.model.impl; + +import org.apache.jena.permissions.SecurityEvaluator.SecNode; +import org.apache.jena.permissions.SecurityEvaluator.SecTriple; +import org.apache.jena.permissions.impl.SecuredItem; +import org.apache.jena.permissions.impl.SecuredItemImpl; +import org.apache.jena.rdf.model.* ; + +public class SecuredSelector implements Selector +{ + private final SecuredItem securedItem; + private final Selector selector; + + public SecuredSelector( final SecuredItem securedItem ) + { + this(securedItem, new SimpleSelector()); + } + + public SecuredSelector( final SecuredItem securedItem, + final Selector selector ) + { + this.securedItem = securedItem; + this.selector = selector; + } + + private SecNode getNode( final RDFNode node ) + { + return node == null ? SecNode.ANY : SecuredItemImpl.convert(node + .asNode()); + } + + @Override + public RDFNode getObject() + { + return selector.getObject(); + } + + @Override + public Property getPredicate() + { + return selector.getPredicate(); + } + + @Override + public Resource getSubject() + { + return selector.getSubject(); + } + + @Override + public boolean isSimple() + { + return securedItem.canRead(SecTriple.ANY); + } + + /** + * This method is designed to be over ridden by subclasses to define + * application + * specific constraints on the statements selected. + * + * @param s + * the statement to be tested + * @return true if the statement satisfies the constraint + */ + @Override + public boolean test( final Statement s ) + { + if (selector.test(s)) + { + final SecTriple t = new SecTriple(getNode(s.getSubject()), + getNode(s.getPredicate()), getNode(s.getObject())); + return securedItem.canRead(t); + } + return false; + } + +} http://git-wip-us.apache.org/repos/asf/jena/blob/c4b0113d/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredSeqImpl.java ---------------------------------------------------------------------- diff --git a/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredSeqImpl.java b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredSeqImpl.java new file mode 100644 index 0000000..c85ea19 --- /dev/null +++ b/jena-permissions/src/main/java/org/apache/jena/permissions/model/impl/SecuredSeqImpl.java @@ -0,0 +1,511 @@ +/* + * 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.jena.permissions.model.impl; + +import org.apache.jena.graph.Triple ; +import org.apache.jena.permissions.impl.ItemHolder; +import org.apache.jena.permissions.impl.SecuredItemInvoker; +import org.apache.jena.permissions.model.*; +import org.apache.jena.rdf.model.* ; +import org.apache.jena.util.iterator.ExtendedIterator ; +import org.apache.jena.util.iterator.Filter ; +import org.apache.jena.vocabulary.RDF ; + +/** + * Implementation of SecuredSeq to be used by a SecuredItemInvoker proxy. + * + * Sequence may have breaks in the order. + * http://www.w3.org/TR/2004/REC-rdf-mt-20040210/#Containers + * + */ +public class SecuredSeqImpl extends SecuredContainerImpl implements SecuredSeq +{ + private class RDFNodeFilter extends Filter<Statement> + { + private final RDFNode n; + + public RDFNodeFilter( final RDFNode n ) + { + this.n = n; + } + + @Override + public boolean accept( final Statement o ) + { + return (o.getPredicate().getOrdinal() != 0) + && n.equals(o.getObject()); + } + + } + + /** + * get a SecuredSeq. + * + * @param securedModel + * The secured model that provides the security context + * @param seq + * The Seq to secure. + * @return the SecuredSeq + */ + public static SecuredSeq getInstance( final SecuredModel securedModel, + final Seq seq ) + { + if (securedModel == null) + { + throw new IllegalArgumentException( + "Secured securedModel may not be null"); + } + if (seq == null) + { + throw new IllegalArgumentException("Seq may not be null"); + } + final ItemHolder<Seq, SecuredSeq> holder = new ItemHolder<Seq, SecuredSeq>( + seq); + final SecuredSeqImpl checker = new SecuredSeqImpl(securedModel, holder); + // if we are going to create a duplicate proxy, just return this + // one. + if (seq instanceof SecuredSeq) + { + if (checker.isEquivalent((SecuredSeq) seq)) + { + return (SecuredSeq) seq; + } + } + return holder.setSecuredItem(new SecuredItemInvoker(seq.getClass(), + checker)); + } + + // the item holder that contains this SecuredSeq. + private final ItemHolder<? extends Seq, ? extends SecuredSeq> holder; + + /** + * Constructor. + * + * @param securedModel + * The secured model that provides the security context + * @param holder + * The item holder that will contain this SecuredSeq. + */ + protected SecuredSeqImpl( final SecuredModel securedModel, + final ItemHolder<? extends Seq, ? extends SecuredSeq> holder ) + { + super(securedModel, holder); + this.holder = holder; + } + + @Override + public SecuredSeq add( final int index, final boolean o ) + { + return add( index, asObject( o )); + } + + @Override + public SecuredSeq add( final int index, final char o ) + { + return add( index, asObject( o )); + } + + @Override + public SecuredSeq add( final int index, final double o ) + { + return add( index, asObject( o )); + } + + @Override + public SecuredSeq add( final int index, final float o ) + { + return add( index, asObject( o )); + } + + @Override + public SecuredSeq add( final int index, final long o ) + { + return add( index, asObject( o )); + } + + @Override + public SecuredSeq add( final int index, final Object o ) + { + return add( index, asObject( o )); + } + + @Override + public SecuredSeq add( final int index, final RDFNode o ) + { + checkUpdate(); + final Literal l = holder.getBaseItem().getModel().createTypedLiteral(o); + checkCreate(index, l); + holder.getBaseItem().add(index, o); + return holder.getSecuredItem(); + } + + @Override + public SecuredSeq add( final int index, final String o ) + { + return add( index, o, "" ); + } + + @Override + public SecuredSeq add( final int index, final String o, final String l ) + { + return add( index, holder.getBaseItem().getModel().createLiteral(o, l)); + } + + private void checkCreate( final int index, final Literal l ) + { + checkCreate(new Triple(holder.getBaseItem().asNode(), RDF.li(index) + .asNode(), l.asNode())); + } + + private Statement containerIndexOf( final RDFNode n ) + { + final ExtendedIterator<Statement> iter = listProperties().filterKeep( + new RDFNodeFilter(n)); + try + { + if (iter.hasNext()) + { + return iter.next(); + } + else + { + return null; + } + } + finally + { + iter.close(); + } + } + + @Override + public SecuredAlt getAlt( final int index ) + { + checkRead(); + final Alt a = holder.getBaseItem().getAlt(index); + checkRead(new Triple(holder.getBaseItem().asNode(), RDF.li(index) + .asNode(), a.asNode())); + return SecuredAltImpl.getInstance(getModel(), a); + } + + @Override + public SecuredBag getBag( final int index ) + { + checkRead(); + final Bag b = holder.getBaseItem().getBag(index); + checkRead(new Triple(holder.getBaseItem().asNode(), RDF.li(index) + .asNode(), b.asNode())); + return SecuredBagImpl.getInstance(getModel(), b); + } + + @Override + public boolean getBoolean( final int index ) + { + checkRead(); + final boolean retval = holder.getBaseItem().getBoolean(index); + checkRead(new Triple(holder.getBaseItem().asNode(), RDF.li(index) + .asNode(), asObject(retval).asNode())); + return retval; + } + + @Override + public byte getByte( final int index ) + { + checkRead(); + final byte retval = holder.getBaseItem().getByte(index); + checkRead(new Triple(holder.getBaseItem().asNode(), RDF.li(index) + .asNode(), asObject(retval).asNode())); + return retval; + } + + @Override + public char getChar( final int index ) + { + checkRead(); + final char retval = holder.getBaseItem().getChar(index); + checkRead(new Triple(holder.getBaseItem().asNode(), RDF.li(index) + .asNode(), asObject(retval).asNode())); + return retval; + + } + + @Override + public double getDouble( final int index ) + { + checkRead(); + final double retval = holder.getBaseItem().getDouble(index); + checkRead(new Triple(holder.getBaseItem().asNode(), RDF.li(index) + .asNode(), asObject(retval).asNode())); + return retval; + } + + @Override + public float getFloat( final int index ) + { + checkRead(); + final float retval = holder.getBaseItem().getFloat(index); + checkRead(new Triple(holder.getBaseItem().asNode(), RDF.li(index) + .asNode(), asObject(retval).asNode())); + return retval; + } + + @Override + public int getInt( final int index ) + { + checkRead(); + final int retval = holder.getBaseItem().getInt(index); + checkRead(new Triple(holder.getBaseItem().asNode(), RDF.li(index) + .asNode(), asObject(retval).asNode())); + return retval; + } + + @Override + public String getLanguage( final int index ) + { + checkRead(); + final Literal literal = holder.getBaseItem().getLiteral(index); + checkRead(new Triple(holder.getBaseItem().asNode(), RDF.li(index) + .asNode(), literal.asNode())); + return literal.getLanguage(); + } + + @Override + public SecuredLiteral getLiteral( final int index ) + { + checkRead(); + final Literal literal = holder.getBaseItem().getLiteral(index); + checkRead(new Triple(holder.getBaseItem().asNode(), RDF.li(index) + .asNode(), literal.asNode())); + return SecuredLiteralImpl.getInstance(getModel(), literal); + } + + @Override + public long getLong( final int index ) + { + checkRead(); + final long retval = holder.getBaseItem().getLong(index); + checkRead(new Triple(holder.getBaseItem().asNode(), RDF.li(index) + .asNode(), asObject(retval).asNode())); + return retval; + } + + @Override + public SecuredRDFNode getObject( final int index ) + { + checkRead(); + final RDFNode retval = holder.getBaseItem().getObject(index); + checkRead(new Triple(holder.getBaseItem().asNode(), RDF.li(index) + .asNode(), retval.asNode())); + return SecuredRDFNodeImpl.getInstance(getModel(), retval); + } + + @Override + public SecuredResource getResource( final int index ) + { + checkRead(); + final Resource retval = holder.getBaseItem().getResource(index); + checkRead(new Triple(holder.getBaseItem().asNode(), RDF.li(index) + .asNode(), retval.asNode())); + return SecuredResourceImpl.getInstance(getModel(), retval); + } + + @Override + @Deprecated + public SecuredResource getResource( final int index, final ResourceF f ) + { + checkRead(); + final Resource retval = holder.getBaseItem().getResource(index, f); + checkRead(new Triple(holder.getBaseItem().asNode(), RDF.li(index) + .asNode(), retval.asNode())); + return SecuredResourceImpl.getInstance(getModel(), retval); + } + + @Override + public SecuredSeq getSeq( final int index ) + { + checkRead(); + final Seq retval = holder.getBaseItem().getSeq(index); + checkRead(new Triple(holder.getBaseItem().asNode(), RDF.li(index) + .asNode(), retval.asNode())); + return SecuredSeqImpl.getInstance(getModel(), retval); + } + + @Override + public short getShort( final int index ) + { + checkRead(); + final short retval = holder.getBaseItem().getShort(index); + checkRead(new Triple(holder.getBaseItem().asNode(), RDF.li(index) + .asNode(), ResourceFactory.createTypedLiteral(retval).asNode())); + return retval; + } + + @Override + public String getString( final int index ) + { + checkRead(); + final String retval = holder.getBaseItem().getString(index); + checkRead(new Triple(holder.getBaseItem().asNode(), RDF.li(index) + .asNode(), ResourceFactory.createTypedLiteral(retval).asNode())); + return retval; + } + + @Override + public int indexOf( final boolean o ) + { + return indexOf( asObject( o )); + } + + @Override + public int indexOf( final char o ) + { + return indexOf( asObject( o )); + } + + @Override + public int indexOf( final double o ) + { + return indexOf( asObject( o )); + } + + @Override + public int indexOf( final float o ) + { + return indexOf( asObject( o )); + } + + @Override + public int indexOf( final long o ) + { + return indexOf( asObject( o )); + } + + @Override + public int indexOf( final Object o ) + { + return indexOf( asObject( o )); + } + + @Override + public int indexOf( final RDFNode o ) + { + checkRead(); + final Statement stmt = containerIndexOf(o); + if (stmt == null) + { + return 0; + } + checkRead(stmt); + return stmt.getPredicate().getOrdinal(); + } + + @Override + public int indexOf( final String o ) + { + return indexOf( asLiteral( o, "" )); + } + + @Override + public int indexOf( final String o, final String l ) + { + return indexOf( asLiteral( o, l)); + } + + @Override + public SecuredSeq remove( final int index ) + { + checkUpdate(); + final RDFNode rdfNode = holder.getBaseItem().getObject(index); + if (rdfNode != null) + { + checkDelete(new Triple(holder.getBaseItem().asNode(), RDF.li(index) + .asNode(), rdfNode.asNode())); + holder.getBaseItem().remove(index); + } + return holder.getSecuredItem(); + } + + @Override + public SecuredSeq set( final int index, final boolean o ) + { + return set( index, asObject( o )); + } + + @Override + public SecuredSeq set( final int index, final char o ) + { + return set( index, asObject( o )); + } + + @Override + public SecuredSeq set( final int index, final double o ) + { + return set( index, asObject( o )); + } + + @Override + public SecuredSeq set( final int index, final float o ) + { + return set( index, asObject( o )); + } + + @Override + public SecuredSeq set( final int index, final long o ) + { + return set( index, asObject( o )); + } + + @Override + public SecuredSeq set( final int index, final Object o ) + { + return set( index, asObject( o )); + } + + @Override + public SecuredSeq set( final int index, final RDFNode o ) + { + checkUpdate(); + final Triple t2 = new Triple(holder.getBaseItem().asNode(), RDF.li( + index).asNode(), o.asNode()); + final RDFNode rdfNode = holder.getBaseItem().getObject(index); + if (rdfNode != null) + { + final Triple t1 = new Triple(holder.getBaseItem().asNode(), RDF.li( + index).asNode(), rdfNode.asNode()); + checkUpdate(t1, t2); + } + else + { + checkCreate(t2); + } + holder.getBaseItem().set(index, o); + return holder.getSecuredItem(); + } + + @Override + public SecuredSeq set( final int index, final String o ) + { + return set( index, asLiteral( o, "" )); + } + + @Override + public SecuredSeq set( final int index, final String o, final String l ) + { + return set( index, asLiteral(o, l)); + } +}
