1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.morph.transform.transformers;
17
18 import net.sf.composite.Defaults;
19 import net.sf.composite.SimpleComposite;
20 import net.sf.composite.StrictlyTypedComposite;
21 import net.sf.composite.validate.ComponentValidator;
22 import net.sf.morph.transform.NodeCopier;
23 import net.sf.morph.transform.Transformer;
24 import net.sf.morph.util.ClassUtils;
25 import net.sf.morph.util.ContainerUtils;
26
27 /**
28 * @author Matt Sgarlata
29 * @since Dec 12, 2004
30 */
31 public abstract class BaseCompositeTransformer extends BaseTransformer implements Transformer, SimpleComposite, StrictlyTypedComposite {
32
33 /** Our component list */
34 protected Object[] components;
35 private ComponentValidator componentValidator;
36
37
38
39
40
41
42 /**
43 * {@inheritDoc}
44 * @see net.sf.morph.transform.transformers.BaseTransformer#initializeImpl()
45 */
46 protected void initializeImpl() throws Exception {
47 super.initializeImpl();
48 getComponentValidator().validate(this);
49 if (isNarrowingComponentArray()) {
50 if (components != null
51 && !getComponentType().isAssignableFrom(
52 components.getClass().getComponentType())) {
53 Object[] newComponents = (Object[]) ClassUtils.createArray(
54 getComponentType(), components.length);
55 System.arraycopy(components, 0, newComponents, 0, components.length);
56 components = newComponents;
57 }
58 }
59 updateNestedTransformerComponents(getNestedTransformer(), null);
60 }
61
62
63
64 /**
65 * Return the component type of this transformer.
66 * @return Class
67 */
68 public Class getComponentType() {
69 return Transformer.class;
70 }
71
72 /**
73 * {@inheritDoc}
74 * @see net.sf.composite.SimpleComposite#getComponents()
75 */
76 public Object[] getComponents() {
77 return components;
78 }
79
80 /**
81 * {@inheritDoc}
82 * @see net.sf.composite.SimpleComposite#setComponents(java.lang.Object[])
83 */
84 public void setComponents(Object[] components) {
85 setInitialized(false);
86 this.components = components;
87 }
88
89 /**
90 * Return the ComponentValidator of this transformer.
91 * @return ComponentValidator
92 */
93 public ComponentValidator getComponentValidator() {
94 if (componentValidator == null) {
95 componentValidator = Defaults.createComponentValidator();
96 }
97 return componentValidator;
98 }
99
100 /**
101 * Set the ComponentValidator for this transformer.
102 * @param componentValidator ComponentValidator
103 */
104 public void setComponentValidator(ComponentValidator componentValidator) {
105 this.componentValidator = componentValidator;
106 }
107
108
109
110
111 protected void setNestedTransformer(Transformer nestedTransformer) {
112 Transformer old = getNestedTransformer();
113 super.setNestedTransformer(nestedTransformer);
114 updateNestedTransformerComponents(nestedTransformer, old);
115 }
116
117 /**
118 * Propagate our nested transformer to any component NodeCopiers.
119 * @param incoming
120 * @param outgoing
121 */
122 protected void updateNestedTransformerComponents(Transformer incoming, Transformer outgoing) {
123 if (incoming == outgoing) {
124 return;
125 }
126 NodeCopier[] nodeCopiers = (NodeCopier[]) ContainerUtils.getElementsOfType(getComponents(), NodeCopier.class);
127 for (int i = 0; nodeCopiers != null && i < nodeCopiers.length; i++) {
128 if (nodeCopiers[i].getNestedTransformer() == outgoing) {
129 nodeCopiers[i].setNestedTransformer(incoming);
130 }
131 }
132 }
133
134 /**
135 * {@inheritDoc}
136 * @see net.sf.morph.transform.transformers.BaseTransformer#isWrappingRuntimeExceptions()
137 */
138 protected boolean isWrappingRuntimeExceptions() {
139
140
141
142
143
144 return false;
145 }
146
147 /**
148 * Learn whether we should automatically narrow the array type of <code>components</code>
149 * to that returned by {@link #getComponentType()} after validating the components.
150 * @return default <code>true</code>
151 */
152 protected boolean isNarrowingComponentArray() {
153 return true;
154 }
155 }