/*
* 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.
*/
/**
* @author Alexander V. Esin, Stepan M. Mishura
*/
package org.apache.harmony.security.utils;
import java.util.Arrays;
import org.apache.harmony.security.internal.nls.Messages;
/**
* Instance of this class represents ObjectIdentifier (OID).
*
* OID is represented as a sequence of subidentifier.
* Each subidentifier is represented as non negative integer value.
* There are at least 2 subidentifiers in the sequence.
*
* Valid values for first subidentifier are 0, 1 and 2.
* If the first subidentifier has 0 or 1 value the second
* subidentifier MUST be less then 40.
*
* @see http://asn1.elibel.tm.fr/en/standards/index.htm
*/
public final class ObjectIdentifier {
//OID as array of integers
private final int[] oid;
//hash code
private int hash = -1;
//OID as string
private String soid;
// stores the following: "OID." + soid
private String sOID;
// OID alias name
private String name;
// OID's group
private Object group;
/**
* Creates ObjectIdentifier(OID) from array of integers.
*
* @param oid - array of integers
* @return - OID object
* @throws NullPointerException - if oid is null
* @throws IllegalArgumentException - if oid is invalid
*/
public ObjectIdentifier(int[] oid) {
validateOid(oid);
this.oid = oid;
}
/**
* Creates ObjectIdentifier(OID) from array of integers.
*
* @param oid - array of integers
* @param name - name of OID
* @param oidGroup - OID's group. Is used to separate different OID's
* @return - OID object
* @throws NullPointerException - if oid is null
* @throws IllegalArgumentException - if oid is invalid
*/
public ObjectIdentifier(int[] oid, String name, Object oidGroup) {
this(oid);
if (oidGroup == null) {
throw new NullPointerException(Messages.getString("security.172")); //$NON-NLS-1$
}
this.group = oidGroup;
this.name = name;
toOIDString(); // init soid & sOID
}
/**
* Gets OID.
*
* @return oid
*/
public int[] getOid() {
return oid;
}
/**
* Gets OID's name.
*
* @return name
*/
public String getName() {
return name;
}
/**
* Gets OID's group.
*
* @return group
*/
public Object getGroup() {
return group;
}
/**
* Compares object with OID for equality.
*
* @return true if object is ObjectIdentifier and it has the same
* representation as array of integers, otherwise false
*/
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || this.getClass() != o.getClass()) {
return false;
}
return Arrays.equals(oid, ((ObjectIdentifier) o).oid);
}
/**
* Add "OID." to the beginning of string representation.
*
* @return oid as string
*/
public String toOIDString() {
if (sOID == null) {
sOID = "OID." + toString(); //$NON-NLS-1$
}
return sOID;
}
/**
* Overrides Object.toString()
*
* @return oid as string
*/
public String toString() {
if (soid == null) {
StringBuilder sb = new StringBuilder(4 * oid.length);
for (int i = 0; i < oid.length - 1; ++i) {
sb.append(oid[i]);
sb.append('.');
}
sb.append(oid[oid.length - 1]);
soid = sb.toString();
}
return soid;
}
/**
* @see Object#hashCode()
*/
public int hashCode() {
if (hash == -1) {
hash = hashIntArray(oid);
}
return hash;
}
/**
* Validates ObjectIdentifier (OID).
*
* @param oid - oid as array of integers
* @throws NullPointerException - if oid is null
* @throws IllegalArgumentException - if oid is invalid
*/
public static void validateOid(int[] oid) {
if (oid == null) {
throw new NullPointerException(Messages.getString("security.98")); //$NON-NLS-1$
}
if (oid.length < 2) {
throw new IllegalArgumentException(
Messages.getString("security.99")); //$NON-NLS-1$
}
if (oid[0] > 2) {
throw new IllegalArgumentException(
Messages.getString("security.9A")); //$NON-NLS-1$
} else if (oid[0] != 2 && oid[1] > 39) {
throw new IllegalArgumentException(
Messages.getString("security.9B")); //$NON-NLS-1$
}
}
/**
* Returns hash code for array of integers
*
* @param oid - array of integers
*/
public static int hashIntArray(int[] array) {
int intHash = 0;
for (int i = 0; i < array.length && i < 4; i++) {
intHash += array[i] << (8 * i); //TODO what about to find better one?
}
return intHash & 0x7FFFFFFF; // only positive
}
}