/*
* 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.function.Predicate;
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.shared.AddDeniedException;
import org.apache.jena.shared.AuthenticationRequiredException;
import org.apache.jena.shared.DeleteDeniedException;
import org.apache.jena.shared.ReadDeniedException;
import org.apache.jena.shared.UpdateDeniedException;
import org.apache.jena.util.iterator.ExtendedIterator;
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 implements Predicate<Statement> {
private final RDFNode n;
public RDFNodeFilter(final RDFNode n) {
this.n = n;
}
@Override
public boolean test(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)
throws UpdateDeniedException, AddDeniedException,
AuthenticationRequiredException {
return add(index, asObject(o));
}
@Override
public SecuredSeq add(final int index, final char o)
throws UpdateDeniedException, AddDeniedException,
AuthenticationRequiredException {
return add(index, asObject(o));
}
@Override
public SecuredSeq add(final int index, final double o)
throws UpdateDeniedException, AddDeniedException,
AuthenticationRequiredException {
return add(index, asObject(o));
}
@Override
public SecuredSeq add(final int index, final float o)
throws UpdateDeniedException, AddDeniedException,
AuthenticationRequiredException {
return add(index, asObject(o));
}
@Override
public SecuredSeq add(final int index, final long o)
throws UpdateDeniedException, AddDeniedException,
AuthenticationRequiredException {
return add(index, asObject(o));
}
@Override
public SecuredSeq add(final int index, final Object o)
throws UpdateDeniedException, AddDeniedException,
AuthenticationRequiredException {
return add(index, asObject(o));
}
@Override
public SecuredSeq add(final int index, final RDFNode o)
throws UpdateDeniedException, AddDeniedException,
AuthenticationRequiredException {
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)
throws UpdateDeniedException, AddDeniedException,
AuthenticationRequiredException {
return add(index, o, "");
}
@Override
public SecuredSeq add(final int index, final String o, final String l)
throws UpdateDeniedException, AddDeniedException,
AuthenticationRequiredException {
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) throws ReadDeniedException,
AuthenticationRequiredException {
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) throws ReadDeniedException,
AuthenticationRequiredException {
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) throws ReadDeniedException,
AuthenticationRequiredException {
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) throws ReadDeniedException,
AuthenticationRequiredException {
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) throws ReadDeniedException,
AuthenticationRequiredException {
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) throws ReadDeniedException,
AuthenticationRequiredException {
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) throws ReadDeniedException,
AuthenticationRequiredException {
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) throws ReadDeniedException,
AuthenticationRequiredException {
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) throws ReadDeniedException,
AuthenticationRequiredException {
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)
throws ReadDeniedException, AuthenticationRequiredException {
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) throws ReadDeniedException,
AuthenticationRequiredException {
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)
throws ReadDeniedException, AuthenticationRequiredException {
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)
throws ReadDeniedException, AuthenticationRequiredException {
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)
throws ReadDeniedException, AuthenticationRequiredException {
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) throws ReadDeniedException,
AuthenticationRequiredException {
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) throws ReadDeniedException,
AuthenticationRequiredException {
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) throws ReadDeniedException,
AuthenticationRequiredException {
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) throws ReadDeniedException,
AuthenticationRequiredException {
return indexOf(asObject(o));
}
@Override
public int indexOf(final char o) throws ReadDeniedException,
AuthenticationRequiredException {
return indexOf(asObject(o));
}
@Override
public int indexOf(final double o) throws ReadDeniedException,
AuthenticationRequiredException {
return indexOf(asObject(o));
}
@Override
public int indexOf(final float o) throws ReadDeniedException,
AuthenticationRequiredException {
return indexOf(asObject(o));
}
@Override
public int indexOf(final long o) throws ReadDeniedException,
AuthenticationRequiredException {
return indexOf(asObject(o));
}
@Override
public int indexOf(final Object o) throws ReadDeniedException,
AuthenticationRequiredException {
return indexOf(asObject(o));
}
@Override
public int indexOf(final RDFNode o) throws ReadDeniedException,
AuthenticationRequiredException {
checkRead();
final Statement stmt = containerIndexOf(o);
if (stmt == null) {
return 0;
}
checkRead(stmt);
return stmt.getPredicate().getOrdinal();
}
@Override
public int indexOf(final String o) throws ReadDeniedException,
AuthenticationRequiredException {
return indexOf(asLiteral(o, ""));
}
@Override
public int indexOf(final String o, final String l)
throws ReadDeniedException, AuthenticationRequiredException {
return indexOf(asLiteral(o, l));
}
@Override
public SecuredSeq remove(final int index) throws UpdateDeniedException,
DeleteDeniedException, AuthenticationRequiredException {
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)
throws UpdateDeniedException, AddDeniedException,
AuthenticationRequiredException {
return set(index, asObject(o));
}
@Override
public SecuredSeq set(final int index, final char o)
throws UpdateDeniedException, AddDeniedException,
AuthenticationRequiredException {
return set(index, asObject(o));
}
@Override
public SecuredSeq set(final int index, final double o)
throws UpdateDeniedException, AddDeniedException,
AuthenticationRequiredException {
return set(index, asObject(o));
}
@Override
public SecuredSeq set(final int index, final float o)
throws UpdateDeniedException, AddDeniedException,
AuthenticationRequiredException {
return set(index, asObject(o));
}
@Override
public SecuredSeq set(final int index, final long o)
throws UpdateDeniedException, AddDeniedException,
AuthenticationRequiredException {
return set(index, asObject(o));
}
@Override
public SecuredSeq set(final int index, final Object o)
throws UpdateDeniedException, AddDeniedException,
AuthenticationRequiredException {
return set(index, asObject(o));
}
@Override
public SecuredSeq set(final int index, final RDFNode o)
throws UpdateDeniedException, AddDeniedException,
AuthenticationRequiredException {
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)
throws UpdateDeniedException, AddDeniedException,
AuthenticationRequiredException {
return set(index, asLiteral(o, ""));
}
@Override
public SecuredSeq set(final int index, final String o, final String l)
throws UpdateDeniedException, AddDeniedException,
AuthenticationRequiredException {
return set(index, asLiteral(o, l));
}
}