All Downloads are FREE. Search and download functionalities are using the official Maven repository.

io.telicent.jena.abac.Hierarchy Maven / Gradle / Ivy

/*
 *  Copyright (c) Telicent Ltd.
 *
 *  Licensed 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 io.telicent.jena.abac;

import java.util.*;

import io.telicent.jena.abac.attributes.Attribute;
import io.telicent.jena.abac.attributes.ValueTerm;
import io.telicent.jena.abac.attributes.syntax.tokens.Words;
import io.telicent.jena.abac.core.HierarchyGetter;
import org.apache.jena.atlas.lib.InternalErrorException;

/**
 * A hierarchy is a controlled set of values for an attribute where a user request
 * with one attribute value implies other values for the same attribute.
 * 

* Hierarchies are written low to high. For example, suppose there is an attribute * 'clearance' which has the hierarchy: "ordinary" < "secret" < "top secret". *

* A user request with attribute value 'clearance=secret' will * give visibility to data items with 'clearance=ordinary'. */ public class Hierarchy { /** Hierarchy getter function that always return null (no hierarchy). */ public static final HierarchyGetter noHierarchy = a->null; // Low (index 0) to high private final Attribute attribute; private final List hierarchy; public static Hierarchy create(String attrName, String ... strings) { Attribute attr = Attribute.create(attrName); return create(attr, strings); } public static Hierarchy create(Attribute attr, String ... strings) { ValueTerm[] a = new ValueTerm[strings.length]; for (int i = 0 ; i < strings.length ; i ++) { if ( strings[i] == null ) throw new IllegalArgumentException("Null in attribute value hierarchy: "+Arrays.asList(strings)); a[i] = ValueTerm.value(strings[i]); } return new Hierarchy(attr, Arrays.asList(a)); } public static Hierarchy create(Attribute attr, List strings) { ValueTerm[] a = new ValueTerm[strings.size()]; for (int i = 0 ; i < strings.size() ; i ++) { if ( strings.get(i) == null ) throw new IllegalArgumentException("Null in attribute value hierarchy: "+ List.of(strings)); a[i] = ValueTerm.value(strings.get(i)); } return new Hierarchy(attr, Arrays.asList(a)); } public Hierarchy(Attribute attr, List values) { this.attribute = attr; this.hierarchy = values; checkName(); checkNoNulls(); checkNoDuplicates(); } private Hierarchy(Attribute attr, ValueTerm...values) { this.attribute = attr; this.hierarchy = List.of(values); // No nulls. checkName(); checkNoDuplicates(); } private void checkName() { String name = attribute.name(); if ( name.isEmpty() ) throw new IllegalArgumentException("Hierarchy name is empty"); if ( name.contains(" ") ) throw new IllegalArgumentException("Hierarchy name must not contain spaces: "+attribute); if ( name.contains(":") ) throw new IllegalArgumentException("Hierarchy name must not contain colon: "+attribute); } private void checkNoNulls() { // ArrayList supports null. for (int i = 0; i < hierarchy.size(); i++) if (hierarchy.get(i) == null ) throw new IllegalArgumentException("Null in attribute value hierarchy: "+hierarchy); } private void checkNoDuplicates() { Set setOf = new HashSet<>(hierarchy); if ( setOf.size() != hierarchy.size() ) throw new IllegalArgumentException("Duplicate in attribute value hierarchy: "+hierarchy); } public Attribute attribute() { return attribute; } public List values() { return hierarchy; } /** Format: "name: a,b,c" - syntactically valid comma separated list */ public String asString() { StringJoiner sj = new StringJoiner(", "); hierarchy.forEach(valueTerm-> sj.add(valueTerm.asString()) ); return Words.wordStr(attribute.name())+": "+sj.toString(); } /** From a valid comma separated list */ public static Hierarchy fromString(String string) { return AE.parseHierarchy(string); } public enum Comparison { LT, EQ, GT, NONE, } /** * Compare two AttrValues. *

* Cost is linear in the number of attribute values in the hierarchy. *

* Returns: Comparison; v1 CMP v2. * Hierarchy list are stored "low to high" *

    *
  • LT, EQ, GT if both elements are in the hierarchy. *
  • NONE if either of v1 and v2 is not in the hierarchy. *
*/ public Comparison compareTo(ValueTerm v1, ValueTerm v2) { Objects.requireNonNull(v1); Objects.requireNonNull(v2); if ( v1.equals(v2) ) { if ( hierarchy.contains(v1) ) return Comparison.EQ; return Comparison.NONE; } int idx1 = -1; int idx2 = -1; for (int i = 0; i < hierarchy.size(); i++) { ValueTerm v = hierarchy.get(i); if ( idx1 == -1 && v1.equals(v) ) idx1 = i; else if ( idx2 == -1 && v2.equals(v) ) idx2 = i; if ( idx1 != -1 && idx2 != -1 ) { if ( idx1 < idx2 ) return Comparison.LT; if ( idx1 > idx2 ) return Comparison.GT; throw new InternalErrorException(); } } return Comparison.NONE; } @Override public String toString() { return attribute.name()+": "+hierarchy.toString(); } @Override public int hashCode() { return Objects.hash(hierarchy, attribute); } @Override public boolean equals(Object obj) { if ( this == obj ) return true; if ( obj == null ) return false; if ( getClass() != obj.getClass() ) return false; Hierarchy other = (Hierarchy)obj; return Objects.equals(hierarchy, other.hierarchy) && Objects.equals(attribute, other.attribute); } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy