jaxp/src/java.xml/share/classes/com/sun/org/apache/bcel/internal/classfile/Signature.java
changeset 25868 686eef1e7a79
parent 12457 c348e06f0e82
child 44797 8b3b3b911b8a
equal deleted inserted replaced
25867:3d364c870c90 25868:686eef1e7a79
       
     1 /*
       
     2  * reserved comment block
       
     3  * DO NOT REMOVE OR ALTER!
       
     4  */
       
     5 package com.sun.org.apache.bcel.internal.classfile;
       
     6 
       
     7 /* ====================================================================
       
     8  * The Apache Software License, Version 1.1
       
     9  *
       
    10  * Copyright (c) 2001 The Apache Software Foundation.  All rights
       
    11  * reserved.
       
    12  *
       
    13  * Redistribution and use in source and binary forms, with or without
       
    14  * modification, are permitted provided that the following conditions
       
    15  * are met:
       
    16  *
       
    17  * 1. Redistributions of source code must retain the above copyright
       
    18  *    notice, this list of conditions and the following disclaimer.
       
    19  *
       
    20  * 2. Redistributions in binary form must reproduce the above copyright
       
    21  *    notice, this list of conditions and the following disclaimer in
       
    22  *    the documentation and/or other materials provided with the
       
    23  *    distribution.
       
    24  *
       
    25  * 3. The end-user documentation included with the redistribution,
       
    26  *    if any, must include the following acknowledgment:
       
    27  *       "This product includes software developed by the
       
    28  *        Apache Software Foundation (http://www.apache.org/)."
       
    29  *    Alternately, this acknowledgment may appear in the software itself,
       
    30  *    if and wherever such third-party acknowledgments normally appear.
       
    31  *
       
    32  * 4. The names "Apache" and "Apache Software Foundation" and
       
    33  *    "Apache BCEL" must not be used to endorse or promote products
       
    34  *    derived from this software without prior written permission. For
       
    35  *    written permission, please contact apache@apache.org.
       
    36  *
       
    37  * 5. Products derived from this software may not be called "Apache",
       
    38  *    "Apache BCEL", nor may "Apache" appear in their name, without
       
    39  *    prior written permission of the Apache Software Foundation.
       
    40  *
       
    41  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
       
    42  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
       
    43  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
       
    44  * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
       
    45  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
       
    46  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
       
    47  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
       
    48  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
       
    49  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
       
    50  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
       
    51  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
       
    52  * SUCH DAMAGE.
       
    53  * ====================================================================
       
    54  *
       
    55  * This software consists of voluntary contributions made by many
       
    56  * individuals on behalf of the Apache Software Foundation.  For more
       
    57  * information on the Apache Software Foundation, please see
       
    58  * <http://www.apache.org/>.
       
    59  */
       
    60 
       
    61 import  com.sun.org.apache.bcel.internal.Constants;
       
    62 import  java.io.*;
       
    63 
       
    64 /**
       
    65  * This class is derived from <em>Attribute</em> and represents a reference
       
    66  * to a <href="http://wwwipd.ira.uka.de/~pizza/gj/">GJ</a> attribute.
       
    67  *
       
    68  * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
       
    69  * @see     Attribute
       
    70  */
       
    71 public final class Signature extends Attribute {
       
    72   private int signature_index;
       
    73 
       
    74   /**
       
    75    * Initialize from another object. Note that both objects use the same
       
    76    * references (shallow copy). Use clone() for a physical copy.
       
    77    */
       
    78   public Signature(Signature c) {
       
    79     this(c.getNameIndex(), c.getLength(), c.getSignatureIndex(), c.getConstantPool());
       
    80   }
       
    81 
       
    82   /**
       
    83    * Construct object from file stream.
       
    84    * @param name_index Index in constant pool to CONSTANT_Utf8
       
    85    * @param length Content length in bytes
       
    86    * @param file Input stream
       
    87    * @param constant_pool Array of constants
       
    88    * @throws IOException
       
    89    */
       
    90   Signature(int name_index, int length, DataInputStream file,
       
    91            ConstantPool constant_pool) throws IOException
       
    92   {
       
    93     this(name_index, length, file.readUnsignedShort(), constant_pool);
       
    94   }
       
    95 
       
    96   /**
       
    97    * @param name_index Index in constant pool to CONSTANT_Utf8
       
    98    * @param length Content length in bytes
       
    99    * @param constant_pool Array of constants
       
   100    * @param Signature_index Index in constant pool to CONSTANT_Utf8
       
   101    */
       
   102   public Signature(int name_index, int length, int signature_index,
       
   103                   ConstantPool constant_pool)
       
   104   {
       
   105     super(Constants.ATTR_SIGNATURE, name_index, length, constant_pool);
       
   106     this.signature_index = signature_index;
       
   107   }
       
   108 
       
   109   /**
       
   110    * Called by objects that are traversing the nodes of the tree implicitely
       
   111    * defined by the contents of a Java class. I.e., the hierarchy of methods,
       
   112    * fields, attributes, etc. spawns a tree of objects.
       
   113    *
       
   114    * @param v Visitor object
       
   115    */
       
   116    public void accept(Visitor v) {
       
   117      System.err.println("Visiting non-standard Signature object");
       
   118      v.visitSignature(this);
       
   119    }
       
   120 
       
   121   /**
       
   122    * Dump source file attribute to file stream in binary format.
       
   123    *
       
   124    * @param file Output file stream
       
   125    * @throws IOException
       
   126    */
       
   127   public final void dump(DataOutputStream file) throws IOException
       
   128   {
       
   129     super.dump(file);
       
   130     file.writeShort(signature_index);
       
   131   }
       
   132 
       
   133   /**
       
   134    * @return Index in constant pool of source file name.
       
   135    */
       
   136   public final int getSignatureIndex() { return signature_index; }
       
   137 
       
   138   /**
       
   139    * @param Signature_index.
       
   140    */
       
   141   public final void setSignatureIndex(int signature_index) {
       
   142     this.signature_index = signature_index;
       
   143   }
       
   144 
       
   145   /**
       
   146    * @return GJ signature.
       
   147    */
       
   148   public final String getSignature() {
       
   149     ConstantUtf8 c = (ConstantUtf8)constant_pool.getConstant(signature_index,
       
   150                                                              Constants.CONSTANT_Utf8);
       
   151     return c.getBytes();
       
   152   }
       
   153 
       
   154   /**
       
   155    * Extends ByteArrayInputStream to make 'unreading' chars possible.
       
   156    */
       
   157   private static final class MyByteArrayInputStream extends ByteArrayInputStream {
       
   158     MyByteArrayInputStream(String data) { super(data.getBytes()); }
       
   159     final int  mark()                   { return pos; }
       
   160     final String getData()              { return new String(buf); }
       
   161     final void reset(int p)             { pos = p; }
       
   162     final void unread()                 { if(pos > 0) pos--; }
       
   163   }
       
   164 
       
   165   private static boolean identStart(int ch) {
       
   166     return ch == 'T' || ch == 'L';
       
   167   }
       
   168 
       
   169   private static boolean identPart(int ch) {
       
   170     return ch == '/' || ch == ';';
       
   171   }
       
   172 
       
   173   private static final void matchIdent(MyByteArrayInputStream in, StringBuffer buf) {
       
   174     int ch;
       
   175 
       
   176     if((ch = in.read()) == -1)
       
   177       throw new RuntimeException("Illegal signature: " + in.getData() +
       
   178                                  " no ident, reaching EOF");
       
   179 
       
   180     //System.out.println("return from ident:" + (char)ch);
       
   181 
       
   182     if(!identStart(ch)) {
       
   183       StringBuffer buf2 = new StringBuffer();
       
   184 
       
   185       int count = 1;
       
   186       while(Character.isJavaIdentifierPart((char)ch)) {
       
   187         buf2.append((char)ch);
       
   188         count++;
       
   189         ch = in.read();
       
   190       }
       
   191 
       
   192       if(ch == ':') { // Ok, formal parameter
       
   193         in.skip("Ljava/lang/Object".length());
       
   194         buf.append(buf2);
       
   195 
       
   196         ch = in.read();
       
   197         in.unread();
       
   198         //System.out.println("so far:" + buf2 + ":next:" +(char)ch);
       
   199       } else {
       
   200         for(int i=0; i < count; i++)
       
   201           in.unread();
       
   202       }
       
   203 
       
   204       return;
       
   205     }
       
   206 
       
   207     StringBuffer buf2 = new StringBuffer();
       
   208     ch = in.read();
       
   209 
       
   210     do {
       
   211       buf2.append((char)ch);
       
   212       ch = in.read();
       
   213       //System.out.println("within ident:"+ (char)ch);
       
   214 
       
   215     } while((ch != -1) && (Character.isJavaIdentifierPart((char)ch) || (ch == '/')));
       
   216 
       
   217     buf.append(buf2.toString().replace('/', '.'));
       
   218 
       
   219     //System.out.println("regular return ident:"+ (char)ch + ":" + buf2);
       
   220 
       
   221     if(ch != -1)
       
   222       in.unread();
       
   223   }
       
   224 
       
   225   private static final void matchGJIdent(MyByteArrayInputStream in,
       
   226                                          StringBuffer buf)
       
   227   {
       
   228     int ch;
       
   229 
       
   230     matchIdent(in, buf);
       
   231 
       
   232     ch = in.read();
       
   233     if((ch == '<') || ch == '(') { // Parameterized or method
       
   234       //System.out.println("Enter <");
       
   235       buf.append((char)ch);
       
   236       matchGJIdent(in, buf);
       
   237 
       
   238       while(((ch = in.read()) != '>') && (ch != ')')) { // List of parameters
       
   239         if(ch == -1)
       
   240           throw new RuntimeException("Illegal signature: " + in.getData() +
       
   241                                      " reaching EOF");
       
   242 
       
   243         //System.out.println("Still no >");
       
   244         buf.append(", ");
       
   245         in.unread();
       
   246         matchGJIdent(in, buf); // Recursive call
       
   247       }
       
   248 
       
   249       //System.out.println("Exit >");
       
   250 
       
   251       buf.append((char)ch);
       
   252     } else
       
   253       in.unread();
       
   254 
       
   255     ch = in.read();
       
   256     if(identStart(ch)) {
       
   257       in.unread();
       
   258       matchGJIdent(in, buf);
       
   259     } else if(ch == ')') {
       
   260       in.unread();
       
   261       return;
       
   262     } else if(ch != ';')
       
   263       throw new RuntimeException("Illegal signature: " + in.getData() + " read " +
       
   264                                  (char)ch);
       
   265   }
       
   266 
       
   267   public static String translate(String s) {
       
   268     //System.out.println("Sig:" + s);
       
   269     StringBuffer buf = new StringBuffer();
       
   270 
       
   271     matchGJIdent(new MyByteArrayInputStream(s), buf);
       
   272 
       
   273     return buf.toString();
       
   274   }
       
   275 
       
   276   public static final boolean isFormalParameterList(String s) {
       
   277     return s.startsWith("<") && (s.indexOf(':') > 0);
       
   278   }
       
   279 
       
   280   public static final boolean isActualParameterList(String s) {
       
   281     return s.startsWith("L") && s.endsWith(">;");
       
   282   }
       
   283 
       
   284   /**
       
   285    * @return String representation
       
   286    */
       
   287   public final String toString() {
       
   288     String s = getSignature();
       
   289 
       
   290     return "Signature(" + s + ")";
       
   291   }
       
   292 
       
   293   /**
       
   294    * @return deep copy of this attribute
       
   295    */
       
   296   public Attribute copy(ConstantPool constant_pool) {
       
   297     return (Signature)clone();
       
   298   }
       
   299 }