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    
019    package org.apache.geronimo.crypto.asn1.x509;
020    
021    import org.apache.geronimo.crypto.asn1.ASN1Choice;
022    import org.apache.geronimo.crypto.asn1.ASN1Encodable;
023    import org.apache.geronimo.crypto.asn1.ASN1TaggedObject;
024    import org.apache.geronimo.crypto.asn1.DERObject;
025    import org.apache.geronimo.crypto.asn1.DERBMPString;
026    import org.apache.geronimo.crypto.asn1.DERIA5String;
027    import org.apache.geronimo.crypto.asn1.DERUTF8String;
028    import org.apache.geronimo.crypto.asn1.DERVisibleString;
029    import org.apache.geronimo.crypto.asn1.DERString;
030    
031    /**
032     * <code>DisplayText</code> class, used in
033     * <code>CertificatePolicies</code> X509 V3 extensions (in policy qualifiers).
034     *
035     * <p>It stores a string in a chosen encoding.
036     * <pre>
037     * DisplayText ::= CHOICE {
038     *      ia5String        IA5String      (SIZE (1..200)),
039     *      visibleString    VisibleString  (SIZE (1..200)),
040     *      bmpString        BMPString      (SIZE (1..200)),
041     *      utf8String       UTF8String     (SIZE (1..200)) }
042     * </pre>
043     * @see PolicyQualifierInfo
044     * @see PolicyInformation
045     */
046    public class DisplayText
047        extends ASN1Encodable
048        implements ASN1Choice
049    {
050       /**
051        * Constant corresponding to ia5String encoding.
052        *
053        */
054       public static final int CONTENT_TYPE_IA5STRING = 0;
055       /**
056        * Constant corresponding to bmpString encoding.
057        *
058        */
059       public static final int CONTENT_TYPE_BMPSTRING = 1;
060       /**
061        * Constant corresponding to utf8String encoding.
062        *
063        */
064       public static final int CONTENT_TYPE_UTF8STRING = 2;
065       /**
066        * Constant corresponding to visibleString encoding.
067        *
068        */
069       public static final int CONTENT_TYPE_VISIBLESTRING = 3;
070    
071       /**
072        * Describe constant <code>DISPLAY_TEXT_MAXIMUM_SIZE</code> here.
073        *
074        */
075       public static final int DISPLAY_TEXT_MAXIMUM_SIZE = 200;
076    
077       int contentType;
078       DERString contents;
079    
080       /**
081        * Creates a new <code>DisplayText</code> instance.
082        *
083        * @param type the desired encoding type for the text.
084        * @param text the text to store. Strings longer than 200
085        * characters are truncated.
086        */
087       public DisplayText (int type, String text)
088       {
089          if (text.length() > DISPLAY_TEXT_MAXIMUM_SIZE) {
090             // RFC3280 limits these strings to 200 chars
091             // truncate the string
092             text = text.substring (0, DISPLAY_TEXT_MAXIMUM_SIZE);
093          }
094    
095          contentType = type;
096          switch (type) {
097             case CONTENT_TYPE_IA5STRING:
098                contents = (DERString)new DERIA5String (text);
099                break;
100             case CONTENT_TYPE_UTF8STRING:
101                contents = (DERString)new DERUTF8String(text);
102                break;
103             case CONTENT_TYPE_VISIBLESTRING:
104                contents = (DERString)new DERVisibleString(text);
105                break;
106             case CONTENT_TYPE_BMPSTRING:
107                contents = (DERString)new DERBMPString(text);
108                break;
109             default:
110                contents = (DERString)new DERUTF8String(text);
111                break;
112          }
113       }
114    
115       /**
116        * return true if the passed in String can be represented without
117        * loss as a UTF8String, false otherwise.
118        */
119       private boolean canBeUTF8(
120           String  str)
121       {
122           for (int i = str.length() - 1; i >= 0; i--)
123           {
124               if (str.charAt(i) > 0x00ff)
125               {
126                   return false;
127               }
128           }
129    
130           return true;
131       }
132    
133       /**
134        * Creates a new <code>DisplayText</code> instance.
135        *
136        * @param text the text to encapsulate. Strings longer than 200
137        * characters are truncated.
138        */
139       public DisplayText (String text)
140       {
141          // by default use UTF8String
142          if (text.length() > DISPLAY_TEXT_MAXIMUM_SIZE) {
143             text = text.substring(0, DISPLAY_TEXT_MAXIMUM_SIZE);
144          }
145    
146          if (canBeUTF8(text))
147          {
148              contentType = CONTENT_TYPE_UTF8STRING;
149              contents = new DERUTF8String(text);
150          }
151          else
152          {
153              contentType = CONTENT_TYPE_BMPSTRING;
154              contents = new DERBMPString(text);
155          }
156       }
157    
158       /**
159        * Creates a new <code>DisplayText</code> instance.
160        * <p>Useful when reading back a <code>DisplayText</code> class
161        * from it's ASN1Encodable/DEREncodable form.
162        *
163        * @param de a <code>DEREncodable</code> instance.
164        */
165       public DisplayText(DERString de)
166       {
167          contents = de;
168       }
169    
170       public static DisplayText getInstance(Object de)
171       {
172          if (de instanceof DERString)
173          {
174              return new DisplayText((DERString)de);
175          }
176          else if (de instanceof DisplayText)
177          {
178              return (DisplayText)de;
179          }
180    
181          throw new IllegalArgumentException("illegal object in getInstance");
182       }
183    
184       public static DisplayText getInstance(
185           ASN1TaggedObject obj,
186           boolean          explicit)
187       {
188           return getInstance(obj.getObject()); // must be explicitly tagged
189       }
190    
191       public DERObject toASN1Object()
192       {
193          return (DERObject)contents;
194       }
195    
196       /**
197        * Returns the stored <code>String</code> object.
198        *
199        * @return the stored text as a <code>String</code>.
200        */
201       public String getString()
202       {
203          return contents.getString();
204       }
205    }