001: package org.conform;
002:
003: import java.util.*;
004: import java.beans.*;
005: import java.lang.reflect.Method;
006:
007: import org.conform.format.Format;
008:
009: /**
010: * Holds meta information of a bean class.
011: */
012: public class BeanMeta implements Meta {
013: // the name of the property (field name)
014: protected String name;
015: // the type of the property (e.g. String, Long...)
016: protected Class type;
017: // specifies if the bean is applicable
018: protected boolean applicable = true;
019: // any additional attributes, if any
020: protected Map attributes;
021: // a collection of validators for the field (e.g. max length of a string 20)
022: protected DomainProvider domainProvider;
023: protected Collection validators;
024: // the format which must be suported by the field
025: protected Format format;
026:
027: // the localized label for this field (localization takes place in a modifier)
028: private String label;
029: // the localized micro helper for this field (localization takes place in a modifier)
030: private String microHelp;
031:
032: private PropertyMeta[] properties;
033: private transient Map propertyByName;
034:
035: public BeanMeta(Class type) {
036: this .type = type;
037: this .name = type.getName();
038:
039: try {
040: BeanInfo info = Introspector
041: .getBeanInfo(type, Object.class);
042: PropertyDescriptor[] descriptors = info
043: .getPropertyDescriptors();
044: List propertyList = new LinkedList();
045: for (int i = 0; i < descriptors.length; i++) {
046: PropertyDescriptor descriptor = descriptors[i];
047: Method getter = descriptor.getReadMethod();
048: Method setter = descriptor.getWriteMethod();
049:
050: if (getter == null)
051: continue;
052:
053: PropertyMeta property = new PropertyMeta(this ,
054: descriptor.getName(), descriptor
055: .getPropertyType());
056: property.setWritable(setter != null);
057: propertyList.add(property);
058: }
059: setProperties((PropertyMeta[]) propertyList
060: .toArray(new PropertyMeta[propertyList.size()]));
061: } catch (IntrospectionException e) {
062: throw new RuntimeException(e);
063: }
064: }
065:
066: public String getName() {
067: return name;
068: }
069:
070: public void setName(String name) {
071: this .name = name;
072: }
073:
074: public Class getType() {
075: return type;
076: }
077:
078: public void setType(Class type) {
079: this .type = type;
080: }
081:
082: public boolean isApplicable() {
083: return applicable;
084: }
085:
086: public void setApplicable(boolean applicable) {
087: this .applicable = applicable;
088: }
089:
090: public DomainProvider getDomainProvider() {
091: return domainProvider;
092: }
093:
094: public void setDomainProvider(DomainProvider domainProvider) {
095: this .domainProvider = domainProvider;
096: }
097:
098: public Collection getValidators() {
099: return validators;
100: }
101:
102: public void setValidators(Collection validators) {
103: this .validators = validators;
104: }
105:
106: public void addValidator(BeanValidator validator) {
107: if (validators == null) {
108: validators = new ArrayList();
109: }
110: validators.add(validator);
111: }
112:
113: public Format getFormat() {
114: return format;
115: }
116:
117: public void setFormat(Format format) {
118: this .format = format;
119: }
120:
121: public void setAttribute(String name, Object value) {
122: if (attributes == null)
123: attributes = new HashMap();
124:
125: attributes.put(name, value);
126: }
127:
128: public Object getAttribute(String name) {
129: if (attributes == null)
130: return null;
131:
132: return attributes.get(name);
133: }
134:
135: public Map getAttributes() {
136: return attributes;
137: }
138:
139: public void setAttributes(Map attributes) {
140: this .attributes = attributes;
141: }
142:
143: public PropertyMeta getProperty(String name) {
144: if (name == null)
145: return null;
146:
147: if (propertyByName == null) {
148: propertyByName = new HashMap();
149: for (int i = 0; i < properties.length; i++) {
150: PropertyMeta property = properties[i];
151: propertyByName.put(property.getName(), property);
152: }
153: }
154: return (PropertyMeta) propertyByName.get(name);
155: }
156:
157: public PropertyMeta[] getProperties() {
158: return properties;
159: }
160:
161: public void setProperties(PropertyMeta[] properties) {
162: this .properties = properties;
163: this .propertyByName = null;
164: }
165:
166: public String getMicroHelp() {
167: return microHelp;
168: }
169:
170: public void setMicroHelp(String microHelp) {
171: this .microHelp = microHelp;
172: }
173:
174: public String getLabel() {
175: return label;
176: }
177:
178: public void setLabel(String label) {
179: this .label = label;
180: }
181:
182: public String parameterString() {
183: StringBuffer buffer = new StringBuffer(name.length() + 10);
184: buffer.append(name);
185: buffer.append(": ");
186: buffer.append(format);
187: buffer.append(' ');
188: buffer.append('\n');
189: for (Iterator iter = validators.iterator(); iter.hasNext();) {
190: Validator validator = (Validator) iter.next();
191: buffer.append(" ");
192: buffer.append(validator);
193: }
194: buffer.append('\n');
195: for (int i = 0; i < properties.length; i++) {
196: PropertyMeta propertyMeta = properties[i];
197: buffer.append(" ");
198: buffer.append(propertyMeta.parameterString());
199: buffer.append('\n');
200: }
201: return buffer.toString();
202: }
203:
204: public Object clone() {
205: try {
206: BeanMeta beanMeta = (BeanMeta) super .clone();
207: if (attributes != null)
208: beanMeta.attributes = new HashMap(attributes);
209:
210: if (format != null)
211: beanMeta.format = (Format) format.clone();
212:
213: beanMeta.properties = new PropertyMeta[properties.length];
214: beanMeta.propertyByName = new HashMap();
215: for (int i = 0; i < beanMeta.properties.length; i++) {
216: PropertyMeta propertyMeta = (PropertyMeta) properties[i]
217: .clone();
218: beanMeta.properties[i] = propertyMeta;
219: propertyMeta.beanMeta = beanMeta;
220: beanMeta.propertyByName.put(propertyMeta.name,
221: propertyMeta);
222: }
223:
224: return beanMeta;
225: } catch (CloneNotSupportedException e) {
226: throw new RuntimeException(e);
227: }
228: }
229:
230: public boolean equals(Object o) {
231: if (this == o)
232: return true;
233: if (o == null || getClass() != o.getClass())
234: return false;
235:
236: final BeanMeta beanMeta = (BeanMeta) o;
237:
238: if (!name.equals(beanMeta.name))
239: return false;
240: if (!type.equals(beanMeta.type))
241: return false;
242:
243: return true;
244: }
245:
246: public int hashCode() {
247: int result;
248: result = name.hashCode();
249: result = 29 * result + type.hashCode();
250: return result;
251: }
252:
253: public String toString() {
254: return name;
255: }
256: }
|