001: package org.jacorb.orb;
002:
003: import java.lang.reflect.*;
004: import java.util.*;
005:
006: import org.omg.IOP.*;
007:
008: /**
009: * Represents a list of tagged components from an IOR, along with some
010: * generic methods to find and access individual components.
011: * <p>
012: * @author Andre Spiegel
013: * @version $Id: TaggedComponentList.java,v 1.8 2006/06/27 10:50:53 alphonse.bendt Exp $
014: */
015: public class TaggedComponentList implements Cloneable {
016: private TaggedComponent[] components = null;
017:
018: /**
019: * Constructs a TaggedComponentList object from a CDR representation
020: * of an array of tagged components.
021: */
022: public TaggedComponentList(org.omg.CORBA.portable.InputStream in) {
023: components = TaggedComponentSeqHelper.read(in);
024: }
025:
026: /**
027: * Constructs a TaggedComponentList from a CDR encapsulation of
028: * an array of tagged components.
029: */
030: public TaggedComponentList(byte[] data) {
031: CDRInputStream in = new CDRInputStream(null, data);
032: in.openEncapsulatedArray();
033: components = TaggedComponentSeqHelper.read(in);
034: }
035:
036: /**
037: * Constructs a new, empty TaggedComponentList.
038: */
039: public TaggedComponentList() {
040: components = new TaggedComponent[0];
041: }
042:
043: public int size() {
044: return components.length;
045: }
046:
047: public boolean isEmpty() {
048: return components.length == 0;
049: }
050:
051: public TaggedComponent get(int index) {
052: return components[index];
053: }
054:
055: public Object clone() throws CloneNotSupportedException {
056: TaggedComponentList result = (TaggedComponentList) super
057: .clone();
058: result.components = new TaggedComponent[this .components.length];
059: for (int i = 0; i < this .components.length; i++) {
060: result.components[i] = new TaggedComponent(
061: this .components[i].tag,
062: new byte[this .components[i].component_data.length]);
063: System.arraycopy(this .components[i].component_data, 0,
064: result.components[i].component_data, 0,
065: this .components[i].component_data.length);
066: }
067: return result;
068: }
069:
070: public TaggedComponent[] asArray() {
071: return components;
072: }
073:
074: /**
075: * Adds a tagged component to this list. The component's data
076: * is created by marshaling the given data Object using the
077: * write() method of the given helper class.
078: */
079: public void addComponent(int tag, Object data, Class helper) {
080: try {
081: Method writeMethod = helper.getMethod("write", new Class[] {
082: org.omg.CORBA.portable.OutputStream.class,
083: data.getClass() });
084:
085: final CDROutputStream out = new CDROutputStream();
086:
087: try {
088: out.beginEncapsulatedArray();
089: writeMethod.invoke(null, new Object[] { out, data });
090: addComponent(tag, out.getBufferCopy());
091: } finally {
092: out.close();
093: }
094: } catch (NoSuchMethodException ex) {
095: throw new RuntimeException("Helper " + helper.getName()
096: + " has no appropriate write() method.");
097: } catch (IllegalAccessException ex) {
098: throw new RuntimeException(
099: "Cannot access write() method of helper "
100: + helper.getName());
101: } catch (InvocationTargetException ex) {
102: throw new RuntimeException(
103: "Exception while marshaling component data: "
104: + ex.getTargetException());
105: }
106: }
107:
108: /**
109: * Adds a tagged component to this list.
110: */
111: public void addComponent(int tag, byte[] data) {
112: addComponent(new TaggedComponent(tag, data));
113: }
114:
115: /**
116: * Adds a tagged component to this list.
117: */
118: public void addComponent(TaggedComponent component) {
119: TaggedComponent[] newComponents = new TaggedComponent[components.length + 1];
120: System.arraycopy(components, 0, newComponents, 0,
121: components.length);
122: newComponents[components.length] = component;
123: components = newComponents;
124: }
125:
126: /**
127: * Adds an entire TaggedComponentList to this list.
128: */
129: public void addAll(TaggedComponentList other) {
130: TaggedComponent[] newComponents = new TaggedComponent[components.length
131: + other.components.length];
132: System.arraycopy(components, 0, newComponents, 0,
133: components.length);
134: System.arraycopy(other.components, 0, newComponents,
135: components.length, other.components.length);
136: components = newComponents;
137: }
138:
139: /**
140: * Searches for a component with the given tag in this component list.
141: * If one is found, this method reads the corresponding data with the given
142: * helper class, and returns the resulting object, otherwise returns
143: * null.
144: */
145: public Object getComponent(int tag, Class helper) {
146: for (int i = 0; i < components.length; i++) {
147: if (components[i].tag == tag) {
148: return getComponentData(components[i].component_data,
149: helper);
150: }
151: }
152: return null;
153: }
154:
155: /**
156: * Returns the first component with the given tag, which is assumed
157: * to be a CDR string. If no component with the given tag exists,
158: * returns null.
159: */
160: public String getStringComponent(int tag) {
161: for (int i = 0; i < components.length; i++) {
162: if (components[i].tag == tag) {
163: final CDRInputStream in = new CDRInputStream(null,
164: components[i].component_data);
165:
166: try {
167: in.openEncapsulatedArray();
168: return in.read_string();
169: } finally {
170: in.close();
171: }
172: }
173: }
174: return null;
175: }
176:
177: /**
178: * Returns a List of all components with the given tag from this
179: * TaggedComponentList. Each individual component is read with
180: * the given helper class. If no components with the given tag
181: * can be found, an empty list is returned.
182: */
183: public List getComponents(int tag, Class helper) {
184: List result = new ArrayList();
185: for (int i = 0; i < components.length; i++) {
186: if (components[i].tag == tag) {
187: result.add(getComponentData(
188: components[i].component_data, helper));
189: }
190: }
191: return result;
192: }
193:
194: /**
195: * Uses the given helper class to read a CDR-encapsulated component_data
196: * field from the given byte array, data.
197: */
198: private Object getComponentData(byte[] data, Class helper) {
199: try {
200: Method readMethod = helper
201: .getMethod(
202: "read",
203: new Class[] { org.omg.CORBA.portable.InputStream.class });
204: final CDRInputStream in = new CDRInputStream(null, data);
205:
206: try {
207: in.openEncapsulatedArray();
208: return readMethod.invoke(null, new Object[] { in });
209: } finally {
210: in.close();
211: }
212: } catch (NoSuchMethodException ex) {
213: throw new RuntimeException("Helper " + helper.getName()
214: + " has no appropriate read() method.");
215: } catch (IllegalAccessException ex) {
216: throw new RuntimeException(
217: "Cannot access read() method of helper "
218: + helper.getName());
219: } catch (InvocationTargetException ex) {
220: throw new RuntimeException(
221: "Exception while reading component data: "
222: + ex.getTargetException());
223: }
224: }
225: }
|