On Mon, Apr 21, 2014 at 11:55 AM, Andy Seaborne <[email protected]> wrote:
> On 21/04/14 11:00, Claude Warren wrote:
>
>> There were a couple of reasons to go with SecNode and SecTriple separate
>> from Jena's Node and Triple. First the original design was to be
>> implementation agnostic so it could be implemented against Jena or any
>> other RDF data store.
>>
>
> Thanks for the explanation. I can see that the results of e.g. Graph.find
> are Triple, not SecTriple.
>
Since the Triple class is really just a bean that wraps 3 nodes the
SecTriple does not need to be exposed, this in contrast to the Statement
interface that defines a number of methods that modify the model.
>
> (Triple security with labelled triples looks really quite complicated when
> two triples, same fact, different security labels, meet).
Indeed there has been a fair amount of work done in this area. The
security framework solution is to delegate the resolution to the
integrator/developers choice. We just ask the SecurityEvaluator
implementation if the user can (Create,Read,Update,Delete) the Graph/Model
and Triple(s)/Statement(s) in question. Basically, if you can dream up a
restriction scheme you can probably implement it with the Security package.
>
>
>
>> Second, I needed to create a couple of "new" node types. Specifically:
>>
>> FUTURE: which I suspect is similar to your ex2 above, in that I needed to
>> be able to say that a node in a triple would be created during the
>> execution of the method. For example the request to reifiy the triple
>> <A,B,C> requires the security system to make the following requests
>> evaluate if the user can create the triples <FUTURE, rdf:type
>> rdf:Statement>, <FUTURE, rdf:subject, A>, <FUTURE, rdf:predicate, B> and,
>> <FUTURE, rdf:object C>. We don't know what the value of FUTURE will be,
>> but we do know that it will be a new anonymous node.
>>
>
> Yes - sounds similar and is a high "want" from my side.
>
>
>
>> and
>>
>> VARIABLE: which is in some sense the inverse of ANY. In the security
>> system if you evaluate if the user can read <ANY, rdf:subject, A> you are
>> testing to ensure that there are no restrictions on the user reading any
>> triple that has predicate=rdf:subject and object=A. If you evaluate if
>> the
>> user can read <VARIABLE, rdf:subject, A> you are asking if there are any
>> constraints on the user reading triples with predicate=rdf:subject and
>> object=A.
>>
>
> Does that have the same characteristics as FUTURE, from the POV of Node
> design? It's a specific new node type with one instance.
> Seems like there is a "Node_Symbol" which generalizes that and covers ANY,
> FUTURE, VARIABLE ... and a symbol is equals to one with the same label -
> maybe even intern the string label.
>
> Or c.f. Node_Variable and ARQ's extension Var for named variables.
>
>
Yes, I think the Node_Symbol is a good analysis. FUTURE and VARIABLE are
both singletons. I classified nodes into 4 catagories: Any (Node_Symbol),
Anonymus (blank), URI and Literal. FUTURE is an Anonymous type and
VARIABLE is an Any type. I think I did that because I knew the FUTURE
would be an anonymous node when it was created, but otherwise I don't think
it makes much difference.
> example: If the user may only see triples that have
>>
> > < ?x , rdf:subject, A >
>
>> where ?x i in the namspace foo then <ANY, rdf:subject, A> must return
>> false as there are restrictions, but <VARIABLE, rdf:subject, A> must
>> return true as there are some triples that can be read. (VARIABLE is a bad
>> name but it comes from the fact that I encountered the requirement while
>> working with variables in queries).
>>
>> for ex3 above, would not the cache contain only the specialized node
>> implementation and the class would have to ensure that it had a proper
>> instance of the specialized node? I do this in the compressed graph
>> implementation where I keep a weak reference to the base node
>> implementation, and rebuild it if necessary.
>>
>> As for ex1: yeah messy.
>>
>> however, suppose we add a method to Node that gets the node type as a URI.
>> The node factory would register factories for each type. The basic node
>> equality would be something like:
>>
>> public boolean equals( Object o)
>> {
>> if (O instanceof Node)
>> {
>> if this.getType().equals( that.getType() )
>> {
>> return this.isExactMatch( that )
>> }
>> }
>> return false;
>> }
>>
>> There might be a better way to do this with generics and something like
>>
>> Interface Node<T> {
>> Class<T> getType();
>> boolean isExactMatch( Node<T> );
>> }
>>
>>
> Is that necessary? It's equality if it's the same type so would it not be
> possible to implement Node and your own equals:
>
> class Node_Additional {
>
> // Uses Eclipse .equals generator:
> @Override
> public boolean equals(Object obj) {
> if ( this == obj ) return true ;
> if ( obj == null ) return false ;
> if ( !(obj instanceof Node_Additional) ) return false ;
> Node_Additional other = (Node_Additional)obj ;
> ... specific tests ... e.g.
> return this.isExactMatch(other) ;
> }
>
If it is to overlap with an existing Node type, then the testing in both
> cases is more complicated.
>
>
> I think your example breaks in the case where Node_Additional2 extends
Node_Additional and provides an equals implementation similar to the one
above but checking for instanceof Node_Additional2.
Node_Additional2 na2 = new Node_Additional2(....);
Node_Additional na = new Node_Additional(....);
it may be that na.equals( na2 ) is true
and
na2.equals( na ) is false.
This is one of those tricky spaces. I am never sure how to solve this one.
Claude