You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@jena.apache.org by cl...@apache.org on 2013/08/01 23:47:47 UTC

svn commit: r1509440 [6/8] - in /jena/Experimental/jena-security: ./ src/ src/example/ src/example/org/ src/example/org/apache/ src/example/org/apache/jena/ src/example/org/apache/jena/security/ src/example/org/apache/jena/security/example/ src/main/ s...

Added: jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredRDFListImpl.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredRDFListImpl.java?rev=1509440&view=auto
==============================================================================
--- jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredRDFListImpl.java (added)
+++ jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredRDFListImpl.java Thu Aug  1 21:47:45 2013
@@ -0,0 +1,1068 @@
+/*
+ * 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.security.model.impl;
+
+import com.hp.hpl.jena.graph.Node;
+import com.hp.hpl.jena.graph.Triple;
+import com.hp.hpl.jena.rdf.model.EmptyListException;
+import com.hp.hpl.jena.rdf.model.EmptyListUpdateException;
+import com.hp.hpl.jena.rdf.model.InvalidListException;
+import com.hp.hpl.jena.rdf.model.ListIndexException;
+import com.hp.hpl.jena.rdf.model.ModelFactory;
+import com.hp.hpl.jena.rdf.model.Property;
+import com.hp.hpl.jena.rdf.model.RDFList;
+import com.hp.hpl.jena.rdf.model.RDFNode;
+import com.hp.hpl.jena.rdf.model.Resource;
+import com.hp.hpl.jena.rdf.model.Statement;
+import com.hp.hpl.jena.util.iterator.ExtendedIterator;
+import com.hp.hpl.jena.util.iterator.Map1;
+import com.hp.hpl.jena.util.iterator.WrappedIterator;
+import com.hp.hpl.jena.vocabulary.RDF;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.jena.security.AccessDeniedException;
+import org.apache.jena.security.SecurityEvaluator;
+import org.apache.jena.security.SecurityEvaluator.Action;
+import org.apache.jena.security.impl.ItemHolder;
+import org.apache.jena.security.impl.SecuredItemImpl;
+import org.apache.jena.security.impl.SecuredItemInvoker;
+import org.apache.jena.security.model.SecuredModel;
+import org.apache.jena.security.model.SecuredRDFList;
+import org.apache.jena.security.model.SecuredRDFNode;
+import org.apache.jena.security.utils.RDFListIterator;
+import org.apache.jena.security.utils.RDFListSecFilter;
+
+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.security.SecurityEvaluator.SecNode p = SecuredItemImpl
+					.convert(listFirst().asNode());
+			org.apache.jena.security.SecurityEvaluator.SecTriple t = new org.apache.jena.security.SecurityEvaluator.SecTriple(
+					org.apache.jena.security.SecurityEvaluator.SecNode.FUTURE,
+					p, org.apache.jena.security.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.security.SecurityEvaluator.SecTriple(
+							org.apache.jena.security.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.security.SecurityEvaluator.SecNode p = SecuredItemImpl
+					.convert(listFirst().asNode());
+			org.apache.jena.security.SecurityEvaluator.SecTriple t = new org.apache.jena.security.SecurityEvaluator.SecTriple(
+					org.apache.jena.security.SecurityEvaluator.SecNode.FUTURE,
+					p, org.apache.jena.security.SecurityEvaluator.SecNode.ANY);
+			if (!canCreate(t))
+			{
+				final ExtendedIterator<RDFNode> iter = list.iterator();
+				try
+				{
+					while (iter.hasNext())
+					{
+						t = new org.apache.jena.security.SecurityEvaluator.SecTriple(
+								org.apache.jena.security.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(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));
+	}
+}

Propchange: jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredRDFListImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredRDFNodeImpl.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredRDFNodeImpl.java?rev=1509440&view=auto
==============================================================================
--- jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredRDFNodeImpl.java (added)
+++ jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredRDFNodeImpl.java Thu Aug  1 21:47:45 2013
@@ -0,0 +1,254 @@
+/*
+ * 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.security.model.impl;
+
+import com.hp.hpl.jena.enhanced.UnsupportedPolymorphismException;
+import com.hp.hpl.jena.graph.FrontsNode;
+import com.hp.hpl.jena.graph.Node;
+import com.hp.hpl.jena.rdf.model.Literal;
+import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.rdf.model.RDFNode;
+import com.hp.hpl.jena.rdf.model.Resource;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+
+import org.apache.jena.security.impl.ItemHolder;
+import org.apache.jena.security.impl.SecuredItemImpl;
+import org.apache.jena.security.model.SecuredModel;
+import org.apache.jena.security.model.SecuredRDFNode;
+import org.apache.jena.security.model.SecuredUnsupportedPolymorphismException;
+
+/**
+ * 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();
+    }
+}

Propchange: jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredRDFNodeImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredRSIterator.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredRSIterator.java?rev=1509440&view=auto
==============================================================================
--- jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredRSIterator.java (added)
+++ jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredRSIterator.java Thu Aug  1 21:47:45 2013
@@ -0,0 +1,175 @@
+/*
+ * 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.security.model.impl;
+
+import com.hp.hpl.jena.rdf.model.RSIterator;
+import com.hp.hpl.jena.rdf.model.ReifiedStatement;
+import com.hp.hpl.jena.util.iterator.ExtendedIterator;
+import com.hp.hpl.jena.util.iterator.Filter;
+import com.hp.hpl.jena.util.iterator.Map1;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.jena.security.SecurityEvaluator;
+import org.apache.jena.security.SecurityEvaluator.Action;
+import org.apache.jena.security.SecurityEvaluator.SecNode;
+import org.apache.jena.security.impl.SecuredItemImpl;
+import org.apache.jena.security.model.SecuredModel;
+
+/**
+ * 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(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();
+	}
+}

Propchange: jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredRSIterator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredReifiedStatementImpl.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredReifiedStatementImpl.java?rev=1509440&view=auto
==============================================================================
--- jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredReifiedStatementImpl.java (added)
+++ jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredReifiedStatementImpl.java Thu Aug  1 21:47:45 2013
@@ -0,0 +1,100 @@
+/*
+ * 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.security.model.impl;
+
+import com.hp.hpl.jena.rdf.model.ReifiedStatement;
+
+import org.apache.jena.security.impl.ItemHolder;
+import org.apache.jena.security.impl.SecuredItemInvoker;
+import org.apache.jena.security.model.SecuredModel;
+import org.apache.jena.security.model.SecuredReifiedStatement;
+import org.apache.jena.security.model.SecuredStatement;
+
+/**
+ * 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());
+	}
+
+}

Propchange: jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredReifiedStatementImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredResIterator.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredResIterator.java?rev=1509440&view=auto
==============================================================================
--- jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredResIterator.java (added)
+++ jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredResIterator.java Thu Aug  1 21:47:45 2013
@@ -0,0 +1,134 @@
+/*
+ * 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.security.model.impl;
+
+import com.hp.hpl.jena.rdf.model.ResIterator;
+import com.hp.hpl.jena.rdf.model.Resource;
+import com.hp.hpl.jena.util.iterator.ExtendedIterator;
+import com.hp.hpl.jena.util.iterator.Filter;
+import com.hp.hpl.jena.util.iterator.Map1;
+
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.jena.security.model.SecuredModel;
+import org.apache.jena.security.model.SecuredResource;
+
+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();
+	}
+}

Propchange: jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredResIterator.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredResourceImpl.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredResourceImpl.java?rev=1509440&view=auto
==============================================================================
--- jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredResourceImpl.java (added)
+++ jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredResourceImpl.java Thu Aug  1 21:47:45 2013
@@ -0,0 +1,903 @@
+/*
+ * 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.security.model.impl;
+
+import com.hp.hpl.jena.datatypes.RDFDatatype;
+import com.hp.hpl.jena.graph.Node;
+import com.hp.hpl.jena.graph.Triple;
+import com.hp.hpl.jena.rdf.model.AnonId;
+import com.hp.hpl.jena.rdf.model.Literal;
+import com.hp.hpl.jena.rdf.model.LiteralRequiredException;
+import com.hp.hpl.jena.rdf.model.Model;
+import com.hp.hpl.jena.rdf.model.Property;
+import com.hp.hpl.jena.rdf.model.RDFNode;
+import com.hp.hpl.jena.rdf.model.RDFVisitor;
+import com.hp.hpl.jena.rdf.model.Resource;
+import com.hp.hpl.jena.rdf.model.ResourceFactory;
+import com.hp.hpl.jena.rdf.model.Statement;
+import com.hp.hpl.jena.rdf.model.StmtIterator;
+import com.hp.hpl.jena.shared.PropertyNotFoundException;
+import com.hp.hpl.jena.util.iterator.ExtendedIterator;
+
+import org.apache.jena.security.AccessDeniedException;
+import org.apache.jena.security.SecurityEvaluator.Action;
+import org.apache.jena.security.impl.ItemHolder;
+import org.apache.jena.security.impl.SecuredItemImpl;
+import org.apache.jena.security.impl.SecuredItemInvoker;
+import org.apache.jena.security.model.SecuredModel;
+import org.apache.jena.security.model.SecuredResource;
+import org.apache.jena.security.model.SecuredStatement;
+import org.apache.jena.security.utils.PermStatementFilter;
+
+/**
+ * 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(),
+				Node.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.security.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.security.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());
+	}
+
+}

Propchange: jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredResourceImpl.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredSelector.java
URL: http://svn.apache.org/viewvc/jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredSelector.java?rev=1509440&view=auto
==============================================================================
--- jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredSelector.java (added)
+++ jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredSelector.java Thu Aug  1 21:47:45 2013
@@ -0,0 +1,100 @@
+/*
+ * 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.security.model.impl;
+
+import com.hp.hpl.jena.rdf.model.Property;
+import com.hp.hpl.jena.rdf.model.RDFNode;
+import com.hp.hpl.jena.rdf.model.Resource;
+import com.hp.hpl.jena.rdf.model.Selector;
+import com.hp.hpl.jena.rdf.model.SimpleSelector;
+import com.hp.hpl.jena.rdf.model.Statement;
+
+import org.apache.jena.security.SecurityEvaluator.SecNode;
+import org.apache.jena.security.SecurityEvaluator.SecTriple;
+import org.apache.jena.security.impl.SecuredItem;
+import org.apache.jena.security.impl.SecuredItemImpl;
+
+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;
+	}
+
+}

Propchange: jena/Experimental/jena-security/src/main/java/org/apache/jena/security/model/impl/SecuredSelector.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain