1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.apache.commons.betwixt.io.read;
17
18 import java.util.ArrayList;
19 import java.util.Iterator;
20
21 /***
22 * <p>Chain implementation that's backed by a list.
23 * This is the default implementation used by Betwixt.
24 * </p><p>
25 * <strong>Note</strong> this implementation is <em>not</em>
26 * intended to allow multiple threads of execution to perform
27 * modification operations concurrently with traversal of the chain.
28 * Users who require this behaviour are advised to create their own implementation.
29 * </p>
30 *
31 * @author Robert Burrell Donkin
32 * @since 0.5
33 */
34 public class BeanCreationList extends BeanCreationChain {
35
36
37
38 /***
39 * Creates the default <code>BeanCreationChain</code> used when reading beans.
40 * @return a <code>BeanCreationList</code> with the default creators loader in order, not null
41 */
42 public static final BeanCreationList createStandardChain() {
43 BeanCreationList chain = new BeanCreationList();
44 chain.addBeanCreator( ChainedBeanCreatorFactory.createIDREFBeanCreator() );
45 chain.addBeanCreator( ChainedBeanCreatorFactory.createDerivedBeanCreator() );
46 chain.addBeanCreator( ChainedBeanCreatorFactory.createElementTypeBeanCreator() );
47 return chain;
48 }
49
50
51
52
53 /*** The list backing this chain */
54 private ArrayList beanCreators = new ArrayList();
55
56
57
58 /***
59 * Creates an Object based on the given element mapping and read context.
60 * Delegates to chain.
61 *
62 * @param elementMapping the element mapping details
63 * @param readContext create against this context
64 * @return the created bean, possibly null
65 */
66 public Object create( ElementMapping elementMapping, ReadContext readContext ) {
67 ChainWorker worker = new ChainWorker();
68 return worker.create( elementMapping, readContext );
69 }
70
71
72
73 /***
74 * Gets the number of BeanCreators in the wrapped chain.
75 * @return the number of <code>ChainedBeanCreator</code>'s in the current chain
76 */
77 public int getSize() {
78 return beanCreators.size();
79 }
80
81 /***
82 * Inserts a <code>BeanCreator</code> at the given position in the chain.
83 * Shifts the object currently in that position - and any subsequent elements -
84 * to the right.
85 *
86 * @param index index at which the creator should be inserted
87 * @param beanCreator the <code>BeanCreator</code> to be inserted, not null
88 * @throws IndexOutOfBoundsException if the index is out of the range
89 * <code>(index < 0 || index > getSize())
90 */
91 public void insertBeanCreator(
92 int index,
93 ChainedBeanCreator beanCreator )
94 throws IndexOutOfBoundsException {
95 beanCreators.add( index, beanCreator );
96 }
97
98 /***
99 * Adds a <code>BeanCreator</code> to the end of the chain.
100 * @param beanCreator the <code>BeanCreator</code> to be inserted, not null
101 */
102 public void addBeanCreator( ChainedBeanCreator beanCreator ) {
103 beanCreators.add( beanCreator );
104 }
105
106 /***
107 * Clears the creator chain.
108 */
109 public void clearBeanCreators() {
110 beanCreators.clear();
111 }
112
113 /*** Worker class walks a chain */
114 private class ChainWorker extends BeanCreationChain {
115 /*** Iterator for the creator list */
116 private Iterator iterator;
117 /*** Creates the iterator */
118 ChainWorker() {
119 iterator = beanCreators.iterator();
120 }
121
122 /***
123 * @see BeanCreationChain#create
124 */
125 public Object create( ElementMapping elementMapping, ReadContext readContext ) {
126 if ( iterator.hasNext() ) {
127 ChainedBeanCreator beanCreator = (ChainedBeanCreator) iterator.next();
128 return beanCreator.create( elementMapping, readContext, this );
129 }
130
131 return null;
132 }
133 }
134 }