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.bcel.classfile;
019    
020    import java.io.DataInputStream;
021    import java.io.DataOutputStream;
022    import java.io.IOException;
023    import org.apache.bcel.Constants;
024    
025    /**
026     * This class is derived from <em>Attribute</em> and declares this class as
027     * `synthetic', i.e., it needs special handling.  The JVM specification
028     * states "A class member that does not appear in the source code must be
029     * marked using a Synthetic attribute."  It may appear in the ClassFile
030     * attribute table, a field_info table or a method_info table.  This class
031     * is intended to be instantiated from the
032     * <em>Attribute.readAttribute()</em> method.
033     *
034     * @version $Id: Synthetic.java 1152077 2011-07-29 02:29:42Z dbrosius $
035     * @author  <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
036     * @see     Attribute
037     */
038    public final class Synthetic extends Attribute {
039    
040        private static final long serialVersionUID = -123334426995458366L;
041        private byte[] bytes;
042    
043    
044        /**
045         * Initialize from another object. Note that both objects use the same
046         * references (shallow copy). Use copy() for a physical copy.
047         */
048        public Synthetic(Synthetic c) {
049            this(c.getNameIndex(), c.getLength(), c.getBytes(), c.getConstantPool());
050        }
051    
052    
053        /**
054         * @param name_index Index in constant pool to CONSTANT_Utf8, which
055         * should represent the string "Synthetic".
056         * @param length Content length in bytes - should be zero.
057         * @param bytes Attribute contents
058         * @param constant_pool The constant pool this attribute is associated
059         * with.
060         */
061        public Synthetic(int name_index, int length, byte[] bytes, ConstantPool constant_pool) {
062            super(Constants.ATTR_SYNTHETIC, name_index, length, constant_pool);
063            this.bytes = bytes;
064        }
065    
066    
067        /**
068         * Construct object from file stream.
069         * @param name_index Index in constant pool to CONSTANT_Utf8
070         * @param length Content length in bytes
071         * @param file Input stream
072         * @param constant_pool Array of constants
073         * @throws IOException
074         */
075        Synthetic(int name_index, int length, DataInputStream file, ConstantPool constant_pool)
076                throws IOException {
077            this(name_index, length, (byte[]) null, constant_pool);
078            if (length > 0) {
079                bytes = new byte[length];
080                file.readFully(bytes);
081                System.err.println("Synthetic attribute with length > 0");
082            }
083        }
084    
085    
086        /**
087         * Called by objects that are traversing the nodes of the tree implicitely
088         * defined by the contents of a Java class. I.e., the hierarchy of methods,
089         * fields, attributes, etc. spawns a tree of objects.
090         *
091         * @param v Visitor object
092         */
093        @Override
094        public void accept( Visitor v ) {
095            v.visitSynthetic(this);
096        }
097    
098    
099        /**
100         * Dump source file attribute to file stream in binary format.
101         *
102         * @param file Output file stream
103         * @throws IOException
104         */
105        @Override
106        public final void dump( DataOutputStream file ) throws IOException {
107            super.dump(file);
108            if (length > 0) {
109                file.write(bytes, 0, length);
110            }
111        }
112    
113    
114        /**
115         * @return data bytes.
116         */
117        public final byte[] getBytes() {
118            return bytes;
119        }
120    
121    
122        /**
123         * @param bytes
124         */
125        public final void setBytes( byte[] bytes ) {
126            this.bytes = bytes;
127        }
128    
129    
130        /**
131         * @return String representation.
132         */
133        @Override
134        public final String toString() {
135            StringBuilder buf = new StringBuilder("Synthetic");
136            if (length > 0) {
137                buf.append(" ").append(Utility.toHexString(bytes));
138            }
139            return buf.toString();
140        }
141    
142    
143        /**
144         * @return deep copy of this attribute
145         */
146        @Override
147        public Attribute copy( ConstantPool _constant_pool ) {
148            Synthetic c = (Synthetic) clone();
149            if (bytes != null) {
150                c.bytes = new byte[bytes.length];
151                System.arraycopy(bytes, 0, c.bytes, 0, bytes.length);
152            }
153            c.constant_pool = _constant_pool;
154            return c;
155        }
156    }