001: //$Id: Property.java 10247 2006-08-11 18:49:33Z steve.ebersole@jboss.com $
002: package org.hibernate.mapping;
003:
004: import java.io.Serializable;
005: import java.util.HashMap;
006: import java.util.Iterator;
007: import java.util.StringTokenizer;
008:
009: import org.hibernate.MappingException;
010: import org.hibernate.PropertyNotFoundException;
011: import org.hibernate.EntityMode;
012: import org.hibernate.engine.CascadeStyle;
013: import org.hibernate.engine.Mapping;
014: import org.hibernate.property.Getter;
015: import org.hibernate.property.PropertyAccessor;
016: import org.hibernate.property.PropertyAccessorFactory;
017: import org.hibernate.property.Setter;
018: import org.hibernate.type.AbstractComponentType;
019: import org.hibernate.type.Type;
020: import org.hibernate.util.ArrayHelper;
021:
022: /**
023: * Represents a property as part of an entity or a component.
024: *
025: * @author Gavin King
026: */
027: public class Property implements Serializable, MetaAttributable {
028:
029: private String name;
030: private Value value;
031: private String cascade;
032: private boolean updateable = true;
033: private boolean insertable = true;
034: private boolean selectable = true;
035: private boolean optimisticLocked = true;
036: private PropertyGeneration generation = PropertyGeneration.NEVER;
037: private String propertyAccessorName;
038: private boolean lazy;
039: private boolean optional;
040: private String nodeName;
041: private java.util.Map metaAttributes;
042: private PersistentClass persistentClass;
043: private boolean naturalIdentifier;
044:
045: public boolean isBackRef() {
046: return false;
047: }
048:
049: public Type getType() throws MappingException {
050: return value.getType();
051: }
052:
053: public int getColumnSpan() {
054: return value.getColumnSpan();
055: }
056:
057: public Iterator getColumnIterator() {
058: return value.getColumnIterator();
059: }
060:
061: public String getName() {
062: return name;
063: }
064:
065: public boolean isComposite() {
066: return value instanceof Component;
067: }
068:
069: public Value getValue() {
070: return value;
071: }
072:
073: public boolean isPrimitive(Class clazz) {
074: return getGetter(clazz).getReturnType().isPrimitive();
075: }
076:
077: public CascadeStyle getCascadeStyle() throws MappingException {
078: Type type = value.getType();
079: if (type.isComponentType() && !type.isAnyType()) {
080: AbstractComponentType actype = (AbstractComponentType) type;
081: int length = actype.getSubtypes().length;
082: for (int i = 0; i < length; i++) {
083: if (actype.getCascadeStyle(i) != CascadeStyle.NONE)
084: return CascadeStyle.ALL;
085: }
086: return CascadeStyle.NONE;
087: } else if (cascade == null || cascade.equals("none")) {
088: return CascadeStyle.NONE;
089: } else {
090: StringTokenizer tokens = new StringTokenizer(cascade, ", ");
091: CascadeStyle[] styles = new CascadeStyle[tokens
092: .countTokens()];
093: int i = 0;
094: while (tokens.hasMoreTokens()) {
095: styles[i++] = CascadeStyle.getCascadeStyle(tokens
096: .nextToken());
097: }
098: return new CascadeStyle.MultipleCascadeStyle(styles);
099: }
100: }
101:
102: public String getCascade() {
103: return cascade;
104: }
105:
106: public void setCascade(String cascade) {
107: this .cascade = cascade;
108: }
109:
110: public void setName(String name) {
111: this .name = name == null ? null : name.intern();
112: }
113:
114: public void setValue(Value value) {
115: this .value = value;
116: }
117:
118: public boolean isUpdateable() {
119: // if the property mapping consists of all formulas,
120: // make it non-updateable
121: final boolean[] columnUpdateability = value
122: .getColumnUpdateability();
123: return updateable && (
124: //columnUpdateability.length==0 ||
125: !ArrayHelper.isAllFalse(columnUpdateability));
126: }
127:
128: public boolean isInsertable() {
129: // if the property mapping consists of all formulas,
130: // make it insertable
131: final boolean[] columnInsertability = value
132: .getColumnInsertability();
133: return insertable
134: && (columnInsertability.length == 0 || !ArrayHelper
135: .isAllFalse(columnInsertability));
136: }
137:
138: public PropertyGeneration getGeneration() {
139: return generation;
140: }
141:
142: public void setGeneration(PropertyGeneration generation) {
143: this .generation = generation;
144: }
145:
146: public void setUpdateable(boolean mutable) {
147: this .updateable = mutable;
148: }
149:
150: public void setInsertable(boolean insertable) {
151: this .insertable = insertable;
152: }
153:
154: public String getPropertyAccessorName() {
155: return propertyAccessorName;
156: }
157:
158: public void setPropertyAccessorName(String string) {
159: propertyAccessorName = string;
160: }
161:
162: /**
163: * Approximate!
164: */
165: boolean isNullable() {
166: return value == null || value.isNullable();
167: }
168:
169: public boolean isBasicPropertyAccessor() {
170: return propertyAccessorName == null
171: || "property".equals(propertyAccessorName);
172: }
173:
174: public java.util.Map getMetaAttributes() {
175: return metaAttributes;
176: }
177:
178: public MetaAttribute getMetaAttribute(String attributeName) {
179: return metaAttributes == null ? null
180: : (MetaAttribute) metaAttributes.get(attributeName);
181: }
182:
183: public void setMetaAttributes(java.util.Map metas) {
184: this .metaAttributes = metas;
185: }
186:
187: public boolean isValid(Mapping mapping) throws MappingException {
188: return getValue().isValid(mapping);
189: }
190:
191: public String toString() {
192: return getClass().getName() + '(' + name + ')';
193: }
194:
195: public void setLazy(boolean lazy) {
196: this .lazy = lazy;
197: }
198:
199: public boolean isLazy() {
200: if (value instanceof ToOne) {
201: // both many-to-one and one-to-one are represented as a
202: // Property. EntityPersister is relying on this value to
203: // determine "lazy fetch groups" in terms of field-level
204: // interception. So we need to make sure that we return
205: // true here for the case of many-to-one and one-to-one
206: // with lazy="no-proxy"
207: //
208: // * impl note - lazy="no-proxy" currently forces both
209: // lazy and unwrap to be set to true. The other case we
210: // are extremely interested in here is that of lazy="proxy"
211: // where lazy is set to true, but unwrap is set to false.
212: // thus we use both here under the assumption that this
213: // return is really only ever used during persister
214: // construction to determine the lazy property/field fetch
215: // groupings. If that assertion changes then this check
216: // needs to change as well. Partially, this is an issue with
217: // the overloading of the term "lazy" here...
218: ToOne toOneValue = (ToOne) value;
219: return toOneValue.isLazy() && toOneValue.isUnwrapProxy();
220: }
221: return lazy;
222: }
223:
224: public boolean isOptimisticLocked() {
225: return optimisticLocked;
226: }
227:
228: public void setOptimisticLocked(boolean optimisticLocked) {
229: this .optimisticLocked = optimisticLocked;
230: }
231:
232: public boolean isOptional() {
233: return optional || isNullable();
234: }
235:
236: public void setOptional(boolean optional) {
237: this .optional = optional;
238: }
239:
240: public PersistentClass getPersistentClass() {
241: return persistentClass;
242: }
243:
244: public void setPersistentClass(PersistentClass persistentClass) {
245: this .persistentClass = persistentClass;
246: }
247:
248: public boolean isSelectable() {
249: return selectable;
250: }
251:
252: public void setSelectable(boolean selectable) {
253: this .selectable = selectable;
254: }
255:
256: public String getNodeName() {
257: return nodeName;
258: }
259:
260: public void setNodeName(String nodeName) {
261: this .nodeName = nodeName;
262: }
263:
264: public String getAccessorPropertyName(EntityMode mode) {
265: if (mode == EntityMode.DOM4J) {
266: return nodeName;
267: } else {
268: return getName();
269: }
270: }
271:
272: // todo : remove
273: public Getter getGetter(Class clazz)
274: throws PropertyNotFoundException, MappingException {
275: return getPropertyAccessor(clazz).getGetter(clazz, name);
276: }
277:
278: // todo : remove
279: public Setter getSetter(Class clazz)
280: throws PropertyNotFoundException, MappingException {
281: return getPropertyAccessor(clazz).getSetter(clazz, name);
282: }
283:
284: // todo : remove
285: public PropertyAccessor getPropertyAccessor(Class clazz)
286: throws MappingException {
287: return PropertyAccessorFactory.getPropertyAccessor(clazz,
288: getPropertyAccessorName());
289: }
290:
291: public boolean isNaturalIdentifier() {
292: return naturalIdentifier;
293: }
294:
295: public void setNaturalIdentifier(boolean naturalIdentifier) {
296: this.naturalIdentifier = naturalIdentifier;
297: }
298: }
|