alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (GeneralSubtrees.java)

This example Java source code file (GeneralSubtrees.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

deroutputstream, generalname, generalnameinterface, generalsubtree, generalsubtrees, ioexception, name_diff_type, name_match, name_narrows, name_same_type, name_widens, nullpointerexception, objectidentifier, string, util

The GeneralSubtrees.java Java example source code

/*
 * Copyright (c) 1997, 2003, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package sun.security.x509;

import java.io.*;
import java.util.*;

import sun.security.util.*;

/**
 * Represent the GeneralSubtrees ASN.1 object.
 * <p>
 * The ASN.1 for this is
 * <pre>
 * GeneralSubtrees ::= SEQUENCE SIZE (1..MAX) OF GeneralSubtree
 * </pre>
 * </p>
 *
 *
 * @author Amit Kapoor
 * @author Hemma Prafullchandra
 * @author Andreas Sterbenz
 */
public class GeneralSubtrees implements Cloneable {

    private final List<GeneralSubtree> trees;

    // Private variables
    private static final int NAME_DIFF_TYPE = GeneralNameInterface.NAME_DIFF_TYPE;
    private static final int NAME_MATCH = GeneralNameInterface.NAME_MATCH;
    private static final int NAME_NARROWS = GeneralNameInterface.NAME_NARROWS;
    private static final int NAME_WIDENS = GeneralNameInterface.NAME_WIDENS;
    private static final int NAME_SAME_TYPE = GeneralNameInterface.NAME_SAME_TYPE;

    /**
     * The default constructor for the class.
     */
    public GeneralSubtrees() {
        trees = new ArrayList<GeneralSubtree>();
    }

    private GeneralSubtrees(GeneralSubtrees source) {
        trees = new ArrayList<GeneralSubtree>(source.trees);
    }

    /**
     * Create the object from the passed DER encoded form.
     *
     * @param val the DER encoded form of the same.
     */
    public GeneralSubtrees(DerValue val) throws IOException {
        this();
        if (val.tag != DerValue.tag_Sequence) {
            throw new IOException("Invalid encoding of GeneralSubtrees.");
        }
        while (val.data.available() != 0) {
            DerValue opt = val.data.getDerValue();
            GeneralSubtree tree = new GeneralSubtree(opt);
            add(tree);
        }
    }

    public GeneralSubtree get(int index) {
        return trees.get(index);
    }

    public void remove(int index) {
        trees.remove(index);
    }

    public void add(GeneralSubtree tree) {
        if (tree == null) {
            throw new NullPointerException();
        }
        trees.add(tree);
    }

    public boolean contains(GeneralSubtree tree) {
        if (tree == null) {
            throw new NullPointerException();
        }
        return trees.contains(tree);
    }

    public int size() {
        return trees.size();
    }

    public Iterator<GeneralSubtree> iterator() {
        return trees.iterator();
    }

    public List<GeneralSubtree> trees() {
        return trees;
    }

    public Object clone() {
        return new GeneralSubtrees(this);
    }

    /**
     * Return a printable string of the GeneralSubtree.
     */
    public String toString() {
        String s = "   GeneralSubtrees:\n" + trees.toString() + "\n";
        return s;
    }

    /**
     * Encode the GeneralSubtrees.
     *
     * @params out the DerOutputStrean to encode this object to.
     */
    public void encode(DerOutputStream out) throws IOException {
        DerOutputStream seq = new DerOutputStream();

        for (int i = 0, n = size(); i < n; i++) {
            get(i).encode(seq);
        }
        out.write(DerValue.tag_Sequence, seq);
    }

    /**
     * Compare two general subtrees by comparing the subtrees
     * of each.
     *
     * @param other GeneralSubtrees to compare to this
     * @returns true if match
     */
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof GeneralSubtrees == false) {
            return false;
        }
        GeneralSubtrees other = (GeneralSubtrees)obj;
        return this.trees.equals(other.trees);
    }

    public int hashCode() {
        return trees.hashCode();
    }

    /**
     * Return the GeneralNameInterface form of the GeneralName in one of
     * the GeneralSubtrees.
     *
     * @param ndx index of the GeneralSubtree from which to obtain the name
     */
    private GeneralNameInterface getGeneralNameInterface(int ndx) {
        return getGeneralNameInterface(get(ndx));
    }

    private static GeneralNameInterface getGeneralNameInterface(GeneralSubtree gs) {
        GeneralName gn = gs.getName();
        GeneralNameInterface gni = gn.getName();
        return gni;
    }

    /**
     * minimize this GeneralSubtrees by removing all redundant entries.
     * Internal method used by intersect and reduce.
     */
    private void minimize() {

        // Algorithm: compare each entry n to all subsequent entries in
        // the list: if any subsequent entry matches or widens entry n,
        // remove entry n. If any subsequent entries narrow entry n, remove
        // the subsequent entries.
        for (int i = 0; i < size(); i++) {
            GeneralNameInterface current = getGeneralNameInterface(i);
            boolean remove1 = false;

            /* compare current to subsequent elements */
            for (int j = i + 1; j < size(); j++) {
                GeneralNameInterface subsequent = getGeneralNameInterface(j);
                switch (current.constrains(subsequent)) {
                    case GeneralNameInterface.NAME_DIFF_TYPE:
                        /* not comparable; different name types; keep checking */
                        continue;
                    case GeneralNameInterface.NAME_MATCH:
                        /* delete one of the duplicates */
                        remove1 = true;
                        break;
                    case GeneralNameInterface.NAME_NARROWS:
                        /* subsequent narrows current */
                        /* remove narrower name (subsequent) */
                        remove(j);
                        j--; /* continue check with new subsequent */
                        continue;
                    case GeneralNameInterface.NAME_WIDENS:
                        /* subsequent widens current */
                        /* remove narrower name current */
                        remove1 = true;
                        break;
                    case GeneralNameInterface.NAME_SAME_TYPE:
                        /* keep both for now; keep checking */
                        continue;
                }
                break;
            } /* end of this pass of subsequent elements */

            if (remove1) {
                remove(i);
                i--; /* check the new i value */
            }

        }
    }

    /**
     * create a subtree containing an instance of the input
     * name type that widens all other names of that type.
     *
     * @params name GeneralNameInterface name
     * @returns GeneralSubtree containing widest name of that type
     * @throws RuntimeException on error (should not occur)
     */
    private GeneralSubtree createWidestSubtree(GeneralNameInterface name) {
        try {
            GeneralName newName;
            switch (name.getType()) {
            case GeneralNameInterface.NAME_ANY:
                // Create new OtherName with same OID as baseName, but
                // empty value
                ObjectIdentifier otherOID = ((OtherName)name).getOID();
                newName = new GeneralName(new OtherName(otherOID, null));
                break;
            case GeneralNameInterface.NAME_RFC822:
                newName = new GeneralName(new RFC822Name(""));
                break;
            case GeneralNameInterface.NAME_DNS:
                newName = new GeneralName(new DNSName(""));
                break;
            case GeneralNameInterface.NAME_X400:
                newName = new GeneralName(new X400Address((byte[])null));
                break;
            case GeneralNameInterface.NAME_DIRECTORY:
                newName = new GeneralName(new X500Name(""));
                break;
            case GeneralNameInterface.NAME_EDI:
                newName = new GeneralName(new EDIPartyName(""));
                break;
            case GeneralNameInterface.NAME_URI:
                newName = new GeneralName(new URIName(""));
                break;
            case GeneralNameInterface.NAME_IP:
                newName = new GeneralName(new IPAddressName((byte[])null));
                break;
            case GeneralNameInterface.NAME_OID:
                newName = new GeneralName
                    (new OIDName(new ObjectIdentifier((int[])null)));
                break;
            default:
                throw new IOException
                    ("Unsupported GeneralNameInterface type: " + name.getType());
            }
            return new GeneralSubtree(newName, 0, -1);
        } catch (IOException e) {
            throw new RuntimeException("Unexpected error: " + e, e);
        }
    }

    /**
     * intersect this GeneralSubtrees with other.  This function
     * is used in merging permitted NameConstraints.  The operation
     * is performed as follows:
     * <ul>
     * <li>If a name in other narrows all names of the same type in this,
     *     the result will contain the narrower name and none of the
     *     names it narrows.
     * <li>If a name in other widens all names of the same type in this,
     *     the result will not contain the wider name.
     * <li>If a name in other does not share the same subtree with any name
     *     of the same type in this, then the name is added to the list
     *     of GeneralSubtrees returned.  These names should be added to
     *     the list of names that are specifically excluded.  The reason
     *     is that, if the intersection is empty, then no names of that
     *     type are permitted, and the only way to express this in
     *     NameConstraints is to include the name in excludedNames.
     * <li>If a name in this has no name of the same type in other, then
     *     the result contains the name in this.  No name of a given type
     *     means the name type is completely permitted.
     * <li>If a name in other has no name of the same type in this, then
     *     the result contains the name in other.  This means that
     *     the name is now constrained in some way, whereas before it was
     *     completely permitted.
     * <ul>
     *
     * @param other GeneralSubtrees to be intersected with this
     * @returns GeneralSubtrees to be merged with excluded; these are
     *          empty-valued name types corresponding to entries that were
     *          of the same type but did not share the same subtree between
     *          this and other. Returns null if no such.
     */
    public GeneralSubtrees intersect(GeneralSubtrees other) {

        if (other == null) {
            throw new NullPointerException("other GeneralSubtrees must not be null");
        }

        GeneralSubtrees newThis = new GeneralSubtrees();
        GeneralSubtrees newExcluded = null;

        // Step 1: If this is empty, just add everything in other to this and
        // return no new excluded entries
        if (size() == 0) {
            union(other);
            return null;
        }

        // Step 2: For ease of checking the subtrees, minimize them by
        // constructing versions that contain only the widest instance of
        // each type
        this.minimize();
        other.minimize();

        // Step 3: Check each entry in this to see whether we keep it or
        // remove it, and whether we add anything to newExcluded or newThis.
        // We keep an entry in this unless it is narrowed by all entries in
        // other.  We add an entry to newExcluded if there is at least one
        // entry of the same nameType in other, but this entry does
        // not share the same subtree with any of the entries in other.
        // We add an entry from other to newThis if there is no name of the
        // same type in this.
        for (int i = 0; i < size(); i++) {
            GeneralNameInterface thisEntry = getGeneralNameInterface(i);
            boolean removeThisEntry = false;

            // Step 3a: If the widest name of this type in other narrows
            // thisEntry, remove thisEntry and add widest other to newThis.
            // Simultaneously, check for situation where there is a name of
            // this type in other, but no name in other matches, narrows,
            // or widens thisEntry.
            boolean sameType = false;
            for (int j = 0; j < other.size(); j++) {
                GeneralSubtree otherEntryGS = other.get(j);
                GeneralNameInterface otherEntry =
                    getGeneralNameInterface(otherEntryGS);
                switch (thisEntry.constrains(otherEntry)) {
                    case NAME_NARROWS:
                        remove(i);
                        i--;
                        newThis.add(otherEntryGS);
                        sameType = false;
                        break;
                    case NAME_SAME_TYPE:
                        sameType = true;
                        continue;
                    case NAME_MATCH:
                    case NAME_WIDENS:
                        sameType = false;
                        break;
                    case NAME_DIFF_TYPE:
                    default:
                        continue;
                }
                break;
            }

            // Step 3b: If sameType is still true, we have the situation
            // where there was a name of the same type as thisEntry in
            // other, but no name in other widened, matched, or narrowed
            // thisEntry.
            if (sameType) {

                // Step 3b.1: See if there are any entries in this and other
                // with this type that match, widen, or narrow each other.
                // If not, then we need to add a "widest subtree" of this
                // type to excluded.
                boolean intersection = false;
                for (int j = 0; j < size(); j++) {
                    GeneralNameInterface thisAltEntry = getGeneralNameInterface(j);

                    if (thisAltEntry.getType() == thisEntry.getType()) {
                        for (int k = 0; k < other.size(); k++) {
                            GeneralNameInterface othAltEntry =
                                other.getGeneralNameInterface(k);

                            int constraintType =
                                thisAltEntry.constrains(othAltEntry);
                            if (constraintType == NAME_MATCH ||
                                constraintType == NAME_WIDENS ||
                                constraintType == NAME_NARROWS) {
                                intersection = true;
                                break;
                            }
                        }
                    }
                }
                if (intersection == false) {
                    if (newExcluded == null) {
                        newExcluded = new GeneralSubtrees();
                    }
                    GeneralSubtree widestSubtree =
                         createWidestSubtree(thisEntry);
                    if (!newExcluded.contains(widestSubtree)) {
                        newExcluded.add(widestSubtree);
                    }
                }

                // Step 3b.2: Remove thisEntry from this
                remove(i);
                i--;
            }
        }

        // Step 4: Add all entries in newThis to this
        if (newThis.size() > 0) {
            union(newThis);
        }

        // Step 5: Add all entries in other that do not have any entry of the
        // same type in this to this
        for (int i = 0; i < other.size(); i++) {
            GeneralSubtree otherEntryGS = other.get(i);
            GeneralNameInterface otherEntry = getGeneralNameInterface(otherEntryGS);
            boolean diffType = false;
            for (int j = 0; j < size(); j++) {
                GeneralNameInterface thisEntry = getGeneralNameInterface(j);
                switch (thisEntry.constrains(otherEntry)) {
                    case NAME_DIFF_TYPE:
                        diffType = true;
                        // continue to see if we find something later of the
                        // same type
                        continue;
                    case NAME_NARROWS:
                    case NAME_SAME_TYPE:
                    case NAME_MATCH:
                    case NAME_WIDENS:
                        diffType = false; // we found an entry of the same type
                        // break because we know we won't be adding it to
                        // this now
                        break;
                    default:
                        continue;
                }
                break;
            }
            if (diffType) {
                add(otherEntryGS);
            }
        }

        // Step 6: Return the newExcluded GeneralSubtrees
        return newExcluded;
    }

    /**
     * construct union of this GeneralSubtrees with other.
     *
     * @param other GeneralSubtrees to be united with this
     */
    public void union(GeneralSubtrees other) {
        if (other != null) {
            for (int i = 0, n = other.size(); i < n; i++) {
                add(other.get(i));
            }
            // Minimize this
            minimize();
        }
    }

    /**
     * reduce this GeneralSubtrees by contents of another.  This function
     * is used in merging excluded NameConstraints with permitted NameConstraints
     * to obtain a minimal form of permitted NameConstraints.  It is an
     * optimization, and does not affect correctness of the results.
     *
     * @param excluded GeneralSubtrees
     */
    public void reduce(GeneralSubtrees excluded) {
        if (excluded == null) {
            return;
        }
        for (int i = 0, n = excluded.size(); i < n; i++) {
            GeneralNameInterface excludedName = excluded.getGeneralNameInterface(i);
            for (int j = 0; j < size(); j++) {
                GeneralNameInterface permitted = getGeneralNameInterface(j);
                switch (excludedName.constrains(permitted)) {
                case GeneralNameInterface.NAME_DIFF_TYPE:
                    break;
                case GeneralNameInterface.NAME_MATCH:
                    remove(j);
                    j--;
                    break;
                case GeneralNameInterface.NAME_NARROWS:
                    /* permitted narrows excluded */
                    remove(j);
                    j--;
                    break;
                case GeneralNameInterface.NAME_WIDENS:
                    /* permitted widens excluded */
                    break;
                case GeneralNameInterface.NAME_SAME_TYPE:
                    break;
                }
            } /* end of this pass of permitted */
        } /* end of pass of excluded */
    }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java GeneralSubtrees.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.