001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017
018 package org.apache.geronimo.util.asn1;
019
020 import java.io.IOException;
021
022 /**
023 * ASN.1 TaggedObject - in ASN.1 nottation this is any object proceeded by
024 * a [n] where n is some number - these are assume to follow the construction
025 * rules (as with sequences).
026 */
027 public abstract class ASN1TaggedObject
028 extends DERObject
029 {
030 int tagNo;
031 boolean empty = false;
032 boolean explicit = true;
033 DEREncodable obj = null;
034
035 static public ASN1TaggedObject getInstance(
036 ASN1TaggedObject obj,
037 boolean explicit)
038 {
039 if (explicit)
040 {
041 return (ASN1TaggedObject)obj.getObject();
042 }
043
044 throw new IllegalArgumentException("implicitly tagged tagged object");
045 }
046
047 /**
048 * Create a tagged object in the explicit style.
049 *
050 * @param tagNo the tag number for this object.
051 * @param obj the tagged object.
052 */
053 public ASN1TaggedObject(
054 int tagNo,
055 DEREncodable obj)
056 {
057 this.explicit = true;
058 this.tagNo = tagNo;
059 this.obj = obj;
060 }
061
062 /**
063 * Create a tagged object with the style given by the value of explicit.
064 * <p>
065 * If the object implements ASN1Choice the tag style will always be changed
066 * to explicit in accordance with the ASN.1 encoding rules.
067 * </p>
068 * @param explicit true if the object is explicitly tagged.
069 * @param tagNo the tag number for this object.
070 * @param obj the tagged object.
071 */
072 public ASN1TaggedObject(
073 boolean explicit,
074 int tagNo,
075 DEREncodable obj)
076 {
077 if (obj instanceof ASN1Choice)
078 {
079 this.explicit = true;
080 }
081 else
082 {
083 this.explicit = explicit;
084 }
085
086 this.tagNo = tagNo;
087 this.obj = obj;
088 }
089
090 public boolean equals(
091 Object o)
092 {
093 if (o == null || !(o instanceof ASN1TaggedObject))
094 {
095 return false;
096 }
097
098 ASN1TaggedObject other = (ASN1TaggedObject)o;
099
100 if (tagNo != other.tagNo || empty != other.empty || explicit != other.explicit)
101 {
102 return false;
103 }
104
105 if(obj == null)
106 {
107 if(other.obj != null)
108 {
109 return false;
110 }
111 }
112 else
113 {
114 if(!(obj.equals(other.obj)))
115 {
116 return false;
117 }
118 }
119
120 return true;
121 }
122
123 public int hashCode()
124 {
125 int code = tagNo;
126
127 if (obj != null)
128 {
129 code ^= obj.hashCode();
130 }
131
132 return code;
133 }
134
135 public int getTagNo()
136 {
137 return tagNo;
138 }
139
140 /**
141 * return whether or not the object may be explicitly tagged.
142 * <p>
143 * Note: if the object has been read from an input stream, the only
144 * time you can be sure if isExplicit is returning the true state of
145 * affairs is if it returns false. An implicitly tagged object may appear
146 * to be explicitly tagged, so you need to understand the context under
147 * which the reading was done as well, see getObject below.
148 */
149 public boolean isExplicit()
150 {
151 return explicit;
152 }
153
154 public boolean isEmpty()
155 {
156 return empty;
157 }
158
159 /**
160 * return whatever was following the tag.
161 * <p>
162 * Note: tagged objects are generally context dependent if you're
163 * trying to extract a tagged object you should be going via the
164 * appropriate getInstance method.
165 */
166 public DERObject getObject()
167 {
168 if (obj != null)
169 {
170 return obj.getDERObject();
171 }
172
173 return null;
174 }
175
176 abstract void encode(DEROutputStream out)
177 throws IOException;
178 }