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

org.fcrepo.jena.CopyOfRelation Maven / Gradle / Ivy

Go to download

The Fedora Commons Jena Patch module: Provides temporary patch for RDF 1.0 serialization.

The newest version!
/*
 * 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.fcrepo.jena;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.apache.jena.util.iterator.Map1Iterator ;
import org.apache.jena.util.iterator.WrappedIterator ;

/**
 * A sparse 2 dimensional array of boolean indexed by Object.
 *
 * Complete with transitive closure algorithm.
 */
class CopyOfRelation {
    final private Map> rows;
    final private Map> cols;
    final private Set index;
    /** The empty Relation.
     */
    public CopyOfRelation() {
        rows = new HashMap<>();
        cols = new HashMap<>();
        index = new HashSet<>();
    }
    /** a is now related to b
     *
     */
    synchronized public void set(T a, T b) {
        index.add(a);
        index.add(b);
        innerAdd(rows, a, b);
        innerAdd(cols, b, a);
    }
    /** Uniquely a is now related to uniquely b.
     *
     *  When this is called any other a related to this b is removed.
     *  When this is called any other b related to this a is removed.
     *
     */
    synchronized public void set11(T a, T b) {
        clearX(a, forward(a));
        clearX(backward(b), b);
        set(a, b);
    }
    /** Uniquely a is now related to b.
     *  Many b's can be related to each a.
     *  When this is called any other a related to this b is removed.
     */
    synchronized public void set1N(T a, T b) {
        clearX(backward(b), b);
        set(a, b);
    }
    /** a is now related to uniquely b.
     *  Many a's can be related to each b.
     *  When this is called any other b related to this a is removed.
     */
    synchronized public void setN1(T a, T b) {
        clearX(a, forward(a));
        set(a, b);
    }
    /** a is now related to b
     *
     */
    synchronized public void setNN(T a, T b) {
        set(a, b);
    }
    /** a is now not related to b
     *
     */
    synchronized public void clear(T a, T b) {
        innerClear(rows, a, b);
        innerClear(cols, b, a);
    }
    private void clearX(Set s, T b) {
        if (s == null)
            return;
        for ( T value : s )
        {
            clear( value, b );
        }
    }
    private void clearX(T a, Set s) {
        if (s == null)
            return;
        for ( T value : s )
        {
            clear( a, value );
        }
    }
    static private  void innerAdd(Map> s, T a, T b) {
        Set vals = s.get(a);
        if (vals == null) {
            vals = new HashSet<>();
            s.put(a, vals);
        }
        vals.add(b);
    }
    static private  void innerClear(Map> s, T a, T b) {
        Set vals = s.get(a);
        if (vals != null) {
            vals.remove(b);
        }
    }
    /** Is a related to b?
     *
     */
    public boolean get(T a, T b) {
        Set  vals = rows.get(a);
        return vals != null && vals.contains(b);
    }
    /**
     * Takes this to its transitive closure.
     See B. Roy. Transitivit� et connexit�. C.R. Acad. Sci. Paris 249, 1959 pp 216-218.
     or
     S. Warshall, A theorem on Boolean matrices, Journal of the ACM, 9(1), 1962, pp11-12


     */
    synchronized public void transitiveClosure() {
        for ( T oj : index )
        {
            Set si = cols.get( oj );
            Set sk = rows.get( oj );
            if ( si != null && sk != null )
            {
                Iterator i = si.iterator();
                while ( i.hasNext() )
                {
                    T oi = i.next();
                    if ( oi != oj )
                    {
                        Iterator k = sk.iterator();
                        while ( k.hasNext() )
                        {
                            T ok = k.next();
                            if ( ok != oj )
                            {
                                set( oi, ok );
                            }
                        }
                    }
                }
            }
        }
    }
    /**
     * The set of a such that a is related to a.
     *
     */
    synchronized public Set getDiagonal() {
        Set rslt = new HashSet<>();
        for ( T o : index )
        {
            if ( get( o, o ) )
            {
                rslt.add( o );
            }
        }
        return rslt;
    }

    synchronized public CopyOfRelation copy() {
        CopyOfRelation rslt = new CopyOfRelation<>();
        Iterator> it = iterator();
        while ( it.hasNext() ) {
            Map.Entry e = it.next();
            rslt.set(e.getKey(),e.getValue());
        }
        return rslt;
    }

    /**
     * The set of b such that a is related to b.
     *
     */
    public Set forward(T a) {
        return rows.get(a);
    }
    /**
     * The set of a such that a is related to b.
     *
     */
    public Set backward(T b) {
        return cols.get(b);
    }

    private static  Iterator> pairEntry(Map.Entry> pair)
    {
        final T a = pair.getKey() ;
        Set bs = pair.getValue() ;
        return new Map1Iterator<>(b -> new CopyOfPairEntry<>(a, b), bs.iterator()) ;
    }

    /**
     * An Iterator over the pairs of the Relation.
     * Each pair is returned as a java.util.Map.Entry.
     * The first element is accessed through getKey(),
     * the second through getValue().
     *@see java.util.Map.Entry
     */
    public Iterator> iterator()
    {
        Map1Iterator>,Iterator>> iter1 =
                new Map1Iterator<>( entry -> pairEntry(entry) , rows.entrySet().iterator()) ;
        // And now flatten it.
        Iterator> iter2 = WrappedIterator.createIteratorIterator(iter1) ;
        return iter2 ;
    }
}

// Old version - exactly as original except with the generics.
// Hard(er) to read.
//        return new IteratorIterator>(new Map1Iterator>, Iterator>>(new Map1>, Iterator>>() {
//            // Convert a Map.Entry into an iterator over Map.Entry
//            public Iterator> map1(Map.Entry> pair)
//            {
//                final T a = pair.getKey() ;
//                Set bs = pair.getValue() ;
//                return new Map1Iterator>(
//                // Converts a b into a Map.Entry pair.
//                                                            new Map1>() {
//                                                                public PairEntry map1(T b)
//                                                                {
//                                                                    return new PairEntry(a, b) ;
//                                                                }
//                                                            }, bs.iterator()) ;
//            }
//            //Map>
//        }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy