KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > tc > config > schema > repository > StandardBeanRepository


1 /*
2  * All content copyright (c) 2003-2006 Terracotta, Inc., except as may otherwise be noted in a separate copyright notice. All rights reserved.
3  */

4 package com.tc.config.schema.repository;
5
6 import org.apache.commons.lang.ClassUtils;
7 import org.apache.xmlbeans.SchemaType;
8 import org.apache.xmlbeans.XmlException;
9 import org.apache.xmlbeans.XmlObject;
10 import org.apache.xmlbeans.XmlOptions;
11
12 import com.tc.config.schema.listen.ConfigurationChangeListener;
13 import com.tc.config.schema.listen.ConfigurationChangeListenerSet;
14 import com.tc.config.schema.validate.ConfigurationValidator;
15 import com.tc.util.Assert;
16
17 import java.lang.reflect.Field JavaDoc;
18 import java.lang.reflect.Modifier JavaDoc;
19 import java.util.ArrayList JavaDoc;
20 import java.util.HashSet JavaDoc;
21 import java.util.Iterator JavaDoc;
22 import java.util.List JavaDoc;
23 import java.util.Set JavaDoc;
24
25 /**
26  * The standard implementation of {@link MutableBeanRepository}.
27  */

28 public class StandardBeanRepository implements MutableBeanRepository {
29
30   private final Class JavaDoc requiredClass;
31   private final ConfigurationChangeListenerSet listenerSet;
32   private final Set validators;
33   private XmlObject bean;
34
35   private XmlObject preMutateCopy;
36
37   public StandardBeanRepository(Class JavaDoc requiredClass) {
38     Assert.assertNotNull(requiredClass);
39
40     this.requiredClass = requiredClass;
41     this.listenerSet = new ConfigurationChangeListenerSet();
42     this.validators = new HashSet JavaDoc();
43     this.bean = null;
44   }
45
46   public void ensureBeanIsOfClass(Class JavaDoc theClass) {
47     if (!theClass.isAssignableFrom(this.requiredClass)) {
48       // formatting
49
throw Assert.failure("You're making sure this repository requires at least " + theClass + ", but it requires "
50                            + this.requiredClass + ", which isn't that class or a subclass thereof.");
51     }
52   }
53
54   public void saveCopyOfBeanInAnticipationOfFutureMutation() {
55     Assert.eval(this.preMutateCopy == null);
56     this.preMutateCopy = this.bean.copy();
57   }
58
59   public void didMutateBean() {
60     Assert.eval(this.preMutateCopy != null);
61     this.listenerSet.configurationChanged(this.preMutateCopy, this.bean);
62     this.preMutateCopy = null;
63   }
64
65   public synchronized XmlObject bean() {
66     return this.bean;
67   }
68
69   static SchemaType getTypeFieldFrom(Class JavaDoc theClass) {
70     try {
71       Field JavaDoc typeField = theClass.getField("type");
72
73       Assert.eval(typeField.getType().equals(SchemaType.class));
74
75       int modifiers = typeField.getModifiers();
76       Assert.eval(Modifier.isPublic(modifiers));
77       Assert.eval(Modifier.isStatic(modifiers));
78       Assert.eval(Modifier.isFinal(modifiers));
79
80       return (SchemaType) typeField.get(null);
81     } catch (NoSuchFieldException JavaDoc nsfe) {
82       throw Assert.failure("Class " + theClass.getName()
83                            + ", doesn't have a 'public static final SchemaType type' field?", nsfe);
84     } catch (IllegalArgumentException JavaDoc iae) {
85       throw Assert.failure("Unable to get 'public static final SchemaType type' from class " + theClass.getName(), iae);
86     } catch (IllegalAccessException JavaDoc iae) {
87       throw Assert.failure("Unable to get 'public static final SchemaType type' from class " + theClass.getName(), iae);
88     }
89   }
90
91   public SchemaType rootBeanSchemaType() {
92     return getTypeFieldFrom(this.requiredClass);
93   }
94
95   public synchronized void setBean(XmlObject bean, String JavaDoc sourceDescription) throws XmlException {
96     Assert.assertNotBlank(sourceDescription);
97     Assert.eval(bean == null || this.requiredClass.isInstance(bean));
98
99     if (this.bean == bean) return;
100
101     if (bean != null) {
102       throwExceptionIfSchemaValidationFails(bean, sourceDescription);
103
104       Iterator JavaDoc iter = this.validators.iterator();
105       while (iter.hasNext()) {
106         ((ConfigurationValidator) iter.next()).validate(bean);
107       }
108     }
109
110     XmlObject oldBean = this.bean;
111     this.bean = bean;
112     this.listenerSet.configurationChanged(oldBean, bean);
113   }
114
115   private void throwExceptionIfSchemaValidationFails(XmlObject theBean, String JavaDoc sourceDescription) throws XmlException {
116     List JavaDoc errors = new ArrayList JavaDoc();
117     XmlOptions options = new XmlOptions();
118     options = options.setLoadLineNumbers();
119     options = options.setErrorListener(errors);
120     options = options.setDocumentSourceName(sourceDescription);
121
122     boolean validated = theBean.validate(options);
123
124     if (errors.size() > 0 || (!validated)) {
125       StringBuffer JavaDoc descrip = new StringBuffer JavaDoc();
126
127       descrip.append("The configuration from '" + sourceDescription + "' is invalid; it has " + errors.size()
128                      + " error" + (errors.size() == 1 ? "" : "s") + ":\n");
129
130       int pos = 1;
131       Iterator JavaDoc iter = errors.iterator();
132       while (iter.hasNext()) {
133         descrip.append(" " + pos + ": " + iter.next().toString() + "\n");
134         pos++;
135       }
136
137       throw new XmlException(descrip.toString());
138     }
139   }
140
141   public void addListener(ConfigurationChangeListener listener) {
142     Assert.assertNotNull(listener);
143     this.listenerSet.addListener(listener);
144   }
145
146   public void addValidator(ConfigurationValidator validator) {
147     Assert.assertNotNull(validator);
148     this.validators.add(validator);
149   }
150
151   public String JavaDoc toString() {
152     return "<Repository for bean of class " + ClassUtils.getShortClassName(this.requiredClass) + "; have bean? "
153            + (this.bean != null) + ">";
154   }
155
156 }
157
Popular Tags