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 import java.util.*;
  64 
  65 /**
  66  * This class represents a reference to an unknown (i.e.,
  67  * application-specific) attribute of a class.  It is instantiated from the
  68  * <em>Attribute.readAttribute()</em> method.  Applications that need to
  69  * read in application-specific attributes should create an <a
  70  * href="./AttributeReader.html">AttributeReader</a> implementation and
  71  * attach it via <a
  72  * href="./Attribute.html#addAttributeReader(java.lang.String,
  73  * com.sun.org.apache.bcel.internal.classfile.AttributeReader)">Attribute.addAttributeReader</a>.
  74 
  75  *
  76  * @see com.sun.org.apache.bcel.internal.classfile.Attribute
  77  * @see com.sun.org.apache.bcel.internal.classfile.AttributeReader
  78  * @author  <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
  79  */
  80 public final class Unknown extends Attribute {
  81   private byte[] bytes;
  82   private String name;
  83 
  84   private static HashMap unknown_attributes = new HashMap();
  85 
  86   /** @return array of unknown attributes, but just one for each kind.
  87    */
  88   static Unknown[] getUnknownAttributes() {
  89     Unknown[] unknowns = new Unknown[unknown_attributes.size()];
  90     Iterator  entries  = unknown_attributes.values().iterator();
  91 
  92     for(int i=0; entries.hasNext(); i++)
  93       unknowns[i] = (Unknown)entries.next();
  94 
  95     unknown_attributes.clear();
  96     return unknowns;
  97   }
  98 
  99   /**
 100    * Initialize from another object. Note that both objects use the same
 101    * references (shallow copy). Use clone() for a physical copy.
 102    */
 103   public Unknown(Unknown c) {
 104     this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool());
 105   }
 106 
 107   /**
 108    * Create a non-standard attribute.
 109    *
 110    * @param name_index Index in constant pool
 111    * @param length Content length in bytes
 112    * @param bytes Attribute contents
 113    * @param constant_pool Array of constants
 114    */
 115   public Unknown(int name_index, int length, byte[] bytes,
 116                  ConstantPool constant_pool)
 117   {
 118     super(Constants.ATTR_UNKNOWN, name_index, length, constant_pool);
 119     this.bytes = bytes;
 120 
 121     name = ((ConstantUtf8)constant_pool.getConstant(name_index,
 122                                                     Constants.CONSTANT_Utf8)).getBytes();
 123     unknown_attributes.put(name, this);
 124   }
 125 
 126   /**
 127    * Construct object from file stream.
 128    * @param name_index Index in constant pool
 129    * @param length Content length in bytes
 130    * @param file Input stream
 131    * @param constant_pool Array of constants
 132    * @throws IOException
 133    */
 134   Unknown(int name_index, int length, DataInputStream file,
 135           ConstantPool constant_pool)
 136        throws IOException
 137   {
 138     this(name_index, length, (byte [])null, constant_pool);
 139 
 140     if(length > 0) {
 141       bytes = new byte[length];
 142       file.readFully(bytes);
 143     }
 144   }
 145 
 146   /**
 147    * Called by objects that are traversing the nodes of the tree implicitely
 148    * defined by the contents of a Java class. I.e., the hierarchy of methods,
 149    * fields, attributes, etc. spawns a tree of objects.
 150    *
 151    * @param v Visitor object
 152    */
 153   public void accept(Visitor v) {
 154     v.visitUnknown(this);
 155   }
 156   /**
 157    * Dump unknown bytes to file stream.
 158    *
 159    * @param file Output file stream
 160    * @throws IOException
 161    */
 162   public final void dump(DataOutputStream file) throws IOException
 163   {
 164     super.dump(file);
 165     if(length > 0)
 166       file.write(bytes, 0, length);
 167   }
 168   /**
 169    * @return data bytes.
 170    */
 171   public final byte[] getBytes() { return bytes; }
 172 
 173   /**
 174    * @return name of attribute.
 175    */
 176   public final String getName() { return name; }
 177 
 178   /**
 179    * @param bytes.
 180    */
 181   public final void setBytes(byte[] bytes) {
 182     this.bytes = bytes;
 183   }
 184 
 185   /**
 186    * @return String representation.
 187    */
 188   public final String toString() {
 189     if(length == 0 || bytes == null)
 190       return "(Unknown attribute " + name + ")";
 191 
 192     String hex;
 193     if(length > 10) {
 194       byte[] tmp = new byte[10];
 195       System.arraycopy(bytes, 0, tmp, 0, 10);
 196       hex = Utility.toHexString(tmp) + "... (truncated)";
 197     }
 198     else
 199       hex = Utility.toHexString(bytes);
 200 
 201     return "(Unknown attribute " + name + ": " + hex + ")";
 202   }
 203 
 204   /**
 205    * @return deep copy of this attribute
 206    */
 207   public Attribute copy(ConstantPool constant_pool) {
 208     Unknown c = (Unknown)clone();
 209 
 210     if(bytes != null)
 211       c.bytes = (byte[])bytes.clone();
 212 
 213     c.constant_pool = constant_pool;
 214     return c;
 215   }
 216 }