1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package net.sf.composite.specialize.specializers;
17
18 import net.sf.composite.Defaults;
19 import net.sf.composite.extract.ComponentAccessor;
20 import net.sf.composite.specialize.SpecializationException;
21 import net.sf.composite.specialize.Specializer;
22 import net.sf.composite.util.Assert;
23 import net.sf.composite.util.ObjectUtils;
24
25 import org.apache.commons.logging.Log;
26 import org.apache.commons.logging.LogFactory;
27
28 /***
29 * A convenient base class for specializers. This base class takes care
30 * of exception handling, argument validation and logging.
31 *
32 * @author Matt Sgarlata
33 * @since Mar 11, 2005
34 */
35 public abstract class BaseSpecializer implements Specializer {
36
37 protected final Log log = LogFactory.getLog(getClass());
38
39 private ComponentAccessor componentAccessor;
40
41 /***
42 * Implementation template method.
43 * @param composite
44 * @param specializedType
45 * @return boolean
46 * @throws Exception
47 */
48 protected abstract boolean isSpecializableImpl(Object composite, Class specializedType) throws Exception;
49
50 private boolean isSpecializableInternal(Object composite,
51 Class specializedType) {
52
53 try {
54 return isSpecializableImpl(composite, specializedType);
55 }
56 catch (SpecializationException e) {
57 throw e;
58 }
59 catch (Exception e) {
60 throw new SpecializationException(
61 "Unable to determine if composite "
62 + ObjectUtils.getObjectDescription(composite)
63 + " is specializable to type "
64 + ObjectUtils.getObjectDescription(specializedType));
65 }
66 }
67
68 public final boolean isSpecializable(Object composite, Class specializedType) throws SpecializationException {
69 Assert.notNull(composite, "composite");
70
71 boolean isSpecializable = isSpecializableInternal(composite,
72 specializedType);
73
74 if (log.isTraceEnabled()) {
75 log.trace("composite "
76 + ObjectUtils.getObjectDescription(composite)
77 + (isSpecializable ? "is" : "is not")
78 + " specializable to type "
79 + ObjectUtils.getObjectDescription(specializedType));
80 }
81 return isSpecializable;
82 }
83
84 protected abstract Object specializeImpl(Object composite, Class specializedType) throws Exception;
85
86 public final Object specialize(Object composite, Class specializedType) throws SpecializationException {
87 Assert.notNull(composite, "composite");
88
89 try {
90 if (!isSpecializableInternal(composite, specializedType)) {
91 throw new SpecializationException("composite "
92 + ObjectUtils.getObjectDescription(composite)
93 + " is not specializable to type "
94 + ObjectUtils.getObjectDescription(specializedType));
95 }
96
97 if (ObjectUtils.isEmpty(getComponentAccessor().getComponents(composite))) {
98 throw new SpecializationException(
99 "Unable to specialize composite "
100 + ObjectUtils.getObjectDescription(composite)
101 + " because it contains no components of type "
102 + ObjectUtils.getObjectDescription(specializedType));
103 }
104
105 Object specialized = specializeImpl(composite, specializedType);
106
107 if (log.isTraceEnabled()) {
108 log.trace("Created specialized composite "
109 + ObjectUtils.getObjectDescription(specialized)
110 + " of type "
111 + ObjectUtils.getObjectDescription(specializedType)
112 + " from composite "
113 + ObjectUtils.getObjectDescription(composite));
114 }
115 return specialized;
116 }
117 catch (SpecializationException e) {
118 throw e;
119 }
120 catch (Exception e) {
121 throw new SpecializationException(
122 "Unable to specialize composite "
123 + ObjectUtils.getObjectDescription(composite)
124 + " to type "
125 + ObjectUtils.getObjectDescription(specializedType), e);
126 }
127 }
128
129 public synchronized ComponentAccessor getComponentAccessor() {
130 if (componentAccessor == null) {
131 setComponentAccessor(Defaults.createComponentAccessor());
132 }
133 return componentAccessor;
134 }
135
136 public synchronized void setComponentAccessor(ComponentAccessor componentExtractor) {
137 this.componentAccessor = componentExtractor;
138 }
139
140 }