001    /**
002     *
003     *  Licensed to the Apache Software Foundation (ASF) under one or more
004     *  contributor license agreements.  See the NOTICE file distributed with
005     *  this work for additional information regarding copyright ownership.
006     *  The ASF licenses this file to You under the Apache License, Version 2.0
007     *  (the "License"); you may not use this file except in compliance with
008     *  the License.  You may obtain a copy of the License at
009     *
010     *     http://www.apache.org/licenses/LICENSE-2.0
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    
019    
020    package org.apache.geronimo.util.asn1.x509;
021    
022    import org.apache.geronimo.util.asn1.ASN1Choice;
023    import org.apache.geronimo.util.asn1.ASN1Encodable;
024    import org.apache.geronimo.util.asn1.ASN1TaggedObject;
025    import org.apache.geronimo.util.asn1.DERObject;
026    import org.apache.geronimo.util.asn1.DERBMPString;
027    import org.apache.geronimo.util.asn1.DERIA5String;
028    import org.apache.geronimo.util.asn1.DERUTF8String;
029    import org.apache.geronimo.util.asn1.DERVisibleString;
030    import org.apache.geronimo.util.asn1.DERString;
031    
032    /**
033     * <code>DisplayText</code> class, used in
034     * <code>CertificatePolicies</code> X509 V3 extensions (in policy qualifiers).
035     *
036     * <p>It stores a string in a chosen encoding.
037     * <pre>
038     * DisplayText ::= CHOICE {
039     *      ia5String        IA5String      (SIZE (1..200)),
040     *      visibleString    VisibleString  (SIZE (1..200)),
041     *      bmpString        BMPString      (SIZE (1..200)),
042     *      utf8String       UTF8String     (SIZE (1..200)) }
043     * </pre>
044     * @see PolicyQualifierInfo
045     * @see PolicyInformation
046     */
047    public class DisplayText
048        extends ASN1Encodable
049        implements ASN1Choice
050    {
051       /**
052        * Constant corresponding to ia5String encoding.
053        *
054        */
055       public static final int CONTENT_TYPE_IA5STRING = 0;
056       /**
057        * Constant corresponding to bmpString encoding.
058        *
059        */
060       public static final int CONTENT_TYPE_BMPSTRING = 1;
061       /**
062        * Constant corresponding to utf8String encoding.
063        *
064        */
065       public static final int CONTENT_TYPE_UTF8STRING = 2;
066       /**
067        * Constant corresponding to visibleString encoding.
068        *
069        */
070       public static final int CONTENT_TYPE_VISIBLESTRING = 3;
071    
072       /**
073        * Describe constant <code>DISPLAY_TEXT_MAXIMUM_SIZE</code> here.
074        *
075        */
076       public static final int DISPLAY_TEXT_MAXIMUM_SIZE = 200;
077    
078       int contentType;
079       DERString contents;
080    
081       /**
082        * Creates a new <code>DisplayText</code> instance.
083        *
084        * @param type the desired encoding type for the text.
085        * @param text the text to store. Strings longer than 200
086        * characters are truncated.
087        */
088       public DisplayText (int type, String text)
089       {
090          if (text.length() > DISPLAY_TEXT_MAXIMUM_SIZE) {
091             // RFC3280 limits these strings to 200 chars
092             // truncate the string
093             text = text.substring (0, DISPLAY_TEXT_MAXIMUM_SIZE);
094          }
095    
096          contentType = type;
097          switch (type) {
098             case CONTENT_TYPE_IA5STRING:
099                contents = (DERString)new DERIA5String (text);
100                break;
101             case CONTENT_TYPE_UTF8STRING:
102                contents = (DERString)new DERUTF8String(text);
103                break;
104             case CONTENT_TYPE_VISIBLESTRING:
105                contents = (DERString)new DERVisibleString(text);
106                break;
107             case CONTENT_TYPE_BMPSTRING:
108                contents = (DERString)new DERBMPString(text);
109                break;
110             default:
111                contents = (DERString)new DERUTF8String(text);
112                break;
113          }
114       }
115    
116       /**
117        * return true if the passed in String can be represented without
118        * loss as a UTF8String, false otherwise.
119        */
120       private boolean canBeUTF8(
121           String  str)
122       {
123           for (int i = str.length() - 1; i >= 0; i--)
124           {
125               if (str.charAt(i) > 0x00ff)
126               {
127                   return false;
128               }
129           }
130    
131           return true;
132       }
133    
134       /**
135        * Creates a new <code>DisplayText</code> instance.
136        *
137        * @param text the text to encapsulate. Strings longer than 200
138        * characters are truncated.
139        */
140       public DisplayText (String text)
141       {
142          // by default use UTF8String
143          if (text.length() > DISPLAY_TEXT_MAXIMUM_SIZE) {
144             text = text.substring(0, DISPLAY_TEXT_MAXIMUM_SIZE);
145          }
146    
147          if (canBeUTF8(text))
148          {
149              contentType = CONTENT_TYPE_UTF8STRING;
150              contents = new DERUTF8String(text);
151          }
152          else
153          {
154              contentType = CONTENT_TYPE_BMPSTRING;
155              contents = new DERBMPString(text);
156          }
157       }
158    
159       /**
160        * Creates a new <code>DisplayText</code> instance.
161        * <p>Useful when reading back a <code>DisplayText</code> class
162        * from it's ASN1Encodable/DEREncodable form.
163        *
164        * @param de a <code>DEREncodable</code> instance.
165        */
166       public DisplayText(DERString de)
167       {
168          contents = de;
169       }
170    
171       public static DisplayText getInstance(Object de)
172       {
173          if (de instanceof DERString)
174          {
175              return new DisplayText((DERString)de);
176          }
177          else if (de instanceof DisplayText)
178          {
179              return (DisplayText)de;
180          }
181    
182          throw new IllegalArgumentException("illegal object in getInstance");
183       }
184    
185       public static DisplayText getInstance(
186           ASN1TaggedObject obj,
187           boolean          explicit)
188       {
189           return getInstance(obj.getObject()); // must be explicitly tagged
190       }
191    
192       public DERObject toASN1Object()
193       {
194          return (DERObject)contents;
195       }
196    
197       /**
198        * Returns the stored <code>String</code> object.
199        *
200        * @return the stored text as a <code>String</code>.
201        */
202       public String getString()
203       {
204          return contents.getString();
205       }
206    }