KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > vladium > jcd > cls > AttributeCollection


1 /* Copyright (C) 2003 Vladimir Roubtsov. All rights reserved.
2  *
3  * This program and the accompanying materials are made available under
4  * the terms of the Common Public License v1.0 which accompanies this distribution,
5  * and is available at http://www.eclipse.org/legal/cpl-v10.html
6  *
7  * $Id: AttributeCollection.java,v 1.1.1.1 2004/05/09 16:57:44 vlad_r Exp $
8  */

9 package com.vladium.jcd.cls;
10
11 import java.io.IOException JavaDoc;
12 import java.util.ArrayList JavaDoc;
13 import java.util.List JavaDoc;
14
15 import com.vladium.jcd.cls.attribute.*;
16 import com.vladium.jcd.lib.UDataOutputStream;
17 import com.vladium.util.asserts.$assert;
18
19 // ----------------------------------------------------------------------------
20
/**
21  * @author (C) 2001, Vlad Roubtsov
22  */

23 final class AttributeCollection implements IAttributeCollection
24 {
25     // public: ................................................................
26

27     // TODO: extend ItemCollection into all XXXCollection classes ?
28

29
30     // ACCESSORS:
31

32     public final Attribute_info get (final int offset)
33     {
34         return (Attribute_info) m_attributes.get (offset);
35     }
36     
37     public final boolean hasSynthetic ()
38     {
39         return m_syntheticRefCount > 0;
40     }
41     
42     public final boolean hasBridge ()
43     {
44         return m_bridgeRefCount > 0;
45     }
46     
47     public final InnerClassesAttribute_info getInnerClassesAttribute ()
48     {
49         final int innerClassesAttributeOffset = m_innerClassesAttributeOffset;
50         if (innerClassesAttributeOffset < 0)
51             return null;
52         else
53             return (InnerClassesAttribute_info) get (innerClassesAttributeOffset);
54     }
55     
56     public final int size ()
57     {
58         return m_attributes.size ();
59     }
60     
61     public final long length ()
62     {
63         // TODO: cache?
64

65         long result = 2;
66         
67         int _attributes_count = m_attributes.size (); // use size() if this class becomes non-final
68
for (int i = 0; i < _attributes_count; i++) result += get (i).length ();
69         
70         return result;
71     }
72     
73     // Cloneable:
74

75     /**
76      * Performs a deep copy.
77      */

78     public Object JavaDoc clone ()
79     {
80         try
81         {
82             final AttributeCollection _clone = (AttributeCollection) super.clone ();
83             
84             // deep clone:
85

86             final int attributes_count = m_attributes.size (); // use size() if this class becomes non-final
87
_clone.m_attributes = new ArrayList JavaDoc (attributes_count);
88             for (int a = 0; a < attributes_count; ++ a)
89             {
90                 _clone.m_attributes.add (((Attribute_info) m_attributes.get (a)).clone ());
91             }
92             
93             return _clone;
94         }
95         catch (CloneNotSupportedException JavaDoc e)
96         {
97             throw new InternalError JavaDoc (e.toString ());
98         }
99     }
100     
101     // IClassFormatOutput:
102

103     public void writeInClassFormat (final UDataOutputStream out) throws IOException JavaDoc
104     {
105         int attributes_count = size ();
106         out.writeU2 (attributes_count);
107         
108         for (int i = 0; i < attributes_count; i++)
109         {
110             get (i).writeInClassFormat (out);
111         }
112     }
113
114     // Visitor:
115

116     public void accept (final IClassDefVisitor visitor, final Object JavaDoc ctx)
117     {
118         visitor.visit (this, ctx);
119     }
120
121
122     // MUTATORS:
123

124     public int add (final Attribute_info attribute)
125     {
126         final List JavaDoc/* Attribute_info */ attributes = m_attributes;
127         
128         final int result = attributes.size ();
129         attributes.add (attribute);
130         
131         if (attribute instanceof SyntheticAttribute_info)
132             ++ m_syntheticRefCount;
133         else if (attribute instanceof InnerClassesAttribute_info)
134         {
135             if (m_innerClassesAttributeOffset >= 0)
136                 throw new IllegalArgumentException JavaDoc ("this attribute collection already has an InnerClasses attribute");
137             
138             m_innerClassesAttributeOffset = result;
139         }
140         else if (attribute instanceof BridgeAttribute_info)
141             ++ m_bridgeRefCount;
142             
143         if (DISALLOW_MULTIPLE_SYNTHETIC_ATTRIBUTES && $assert.ENABLED)
144             $assert.ASSERT (m_syntheticRefCount >= 0 && m_syntheticRefCount <= 1,
145             "bad synthetic attribute count: " + m_syntheticRefCount);
146         
147         return result;
148     }
149     
150     public Attribute_info set (final int offset, final Attribute_info attribute)
151     {
152         final Attribute_info result = (Attribute_info) m_attributes.set (offset, attribute);
153          
154         if (result instanceof SyntheticAttribute_info)
155             -- m_syntheticRefCount;
156         else if (result instanceof InnerClassesAttribute_info)
157             m_innerClassesAttributeOffset = -1;
158         else if (result instanceof BridgeAttribute_info)
159             -- m_bridgeRefCount;
160             
161         if (attribute instanceof SyntheticAttribute_info)
162             ++ m_syntheticRefCount;
163         else if (attribute instanceof InnerClassesAttribute_info)
164             m_innerClassesAttributeOffset = offset;
165         else if (attribute instanceof BridgeAttribute_info)
166             ++ m_bridgeRefCount;
167             
168         if (DISALLOW_MULTIPLE_SYNTHETIC_ATTRIBUTES && $assert.ENABLED)
169             $assert.ASSERT (m_syntheticRefCount >= 0 && m_syntheticRefCount <= 1,
170             "bad synthetic attribute count: " + m_syntheticRefCount);
171             
172         return result;
173     }
174     
175     public Attribute_info remove (final int offset)
176     {
177         final Attribute_info result = (Attribute_info) m_attributes.remove (offset);
178         
179         if (result instanceof SyntheticAttribute_info)
180             -- m_syntheticRefCount;
181         else if (result instanceof InnerClassesAttribute_info)
182             m_innerClassesAttributeOffset = -1;
183         else if (result instanceof BridgeAttribute_info)
184             -- m_bridgeRefCount;
185             
186         if (DISALLOW_MULTIPLE_SYNTHETIC_ATTRIBUTES && $assert.ENABLED)
187             $assert.ASSERT (m_syntheticRefCount >= 0 && m_syntheticRefCount <= 1,
188             "bad synthetic attribute count: " + m_syntheticRefCount);
189             
190         return result;
191     }
192     
193     // protected: .............................................................
194

195     // package: ...............................................................
196

197
198     AttributeCollection (final int capacity)
199     {
200         m_attributes = capacity < 0 ? new ArrayList JavaDoc () : new ArrayList JavaDoc (capacity);
201         m_innerClassesAttributeOffset = -1;
202     }
203
204     // private: ...............................................................
205

206     
207     private List JavaDoc/* Attribute_info */ m_attributes; // never null
208
private transient int m_syntheticRefCount, m_bridgeRefCount;
209     private transient int m_innerClassesAttributeOffset;
210     
211     // note: the spec does not disallow multiple synthetic attributes
212
private static final boolean DISALLOW_MULTIPLE_SYNTHETIC_ATTRIBUTES = false;
213     
214     // note: the spec disallows multiple inner classes attributes
215

216 } // end of class
217
// ----------------------------------------------------------------------------
218
Popular Tags