001: //$Id: SimpleValue.java 8046 2005-08-30 20:11:43Z oneovthafew $
002: package org.hibernate.mapping;
003:
004: import java.util.ArrayList;
005: import java.util.Iterator;
006: import java.util.List;
007: import java.util.Properties;
008:
009: import org.hibernate.FetchMode;
010: import org.hibernate.MappingException;
011: import org.hibernate.dialect.Dialect;
012: import org.hibernate.engine.Mapping;
013: import org.hibernate.id.IdentifierGenerator;
014: import org.hibernate.id.IdentifierGeneratorFactory;
015: import org.hibernate.id.IdentityGenerator;
016: import org.hibernate.id.PersistentIdentifierGenerator;
017: import org.hibernate.type.Type;
018: import org.hibernate.type.TypeFactory;
019: import org.hibernate.util.ReflectHelper;
020:
021: /**
022: * Any value that maps to columns.
023: * @author Gavin King
024: */
025: public class SimpleValue implements KeyValue {
026:
027: private final List columns = new ArrayList();
028: private String typeName;
029: private Properties identifierGeneratorProperties;
030: private String identifierGeneratorStrategy = "assigned";
031: private String nullValue;
032: private Table table;
033: private String foreignKeyName;
034: private boolean alternateUniqueKey;
035: private Properties typeParameters;
036: private boolean cascadeDeleteEnabled;
037:
038: public boolean isCascadeDeleteEnabled() {
039: return cascadeDeleteEnabled;
040: }
041:
042: public void setCascadeDeleteEnabled(boolean cascadeDeleteEnabled) {
043: this .cascadeDeleteEnabled = cascadeDeleteEnabled;
044: }
045:
046: public void addColumn(Column column) {
047: if (!columns.contains(column))
048: columns.add(column);
049: column.setValue(this );
050: column.setTypeIndex(columns.size() - 1);
051: }
052:
053: public void addFormula(Formula formula) {
054: columns.add(formula);
055: }
056:
057: public boolean hasFormula() {
058: Iterator iter = getColumnIterator();
059: while (iter.hasNext()) {
060: Object o = iter.next();
061: if (o instanceof Formula)
062: return true;
063: }
064: return false;
065: }
066:
067: public int getColumnSpan() {
068: return columns.size();
069: }
070:
071: public Iterator getColumnIterator() {
072: return columns.iterator();
073: }
074:
075: public List getConstraintColumns() {
076: return columns;
077: }
078:
079: public String getTypeName() {
080: return typeName;
081: }
082:
083: public void setTypeName(String type) {
084: this .typeName = type;
085: }
086:
087: public void setTable(Table table) {
088: this .table = table;
089: }
090:
091: public SimpleValue(Table table) {
092: this .table = table;
093: }
094:
095: public SimpleValue() {
096: }
097:
098: public void createForeignKey() throws MappingException {
099: }
100:
101: public void createForeignKeyOfEntity(String entityName) {
102: if (!hasFormula() && !"none".equals(getForeignKeyName())) {
103: ForeignKey fk = table.createForeignKey(getForeignKeyName(),
104: getConstraintColumns(), entityName);
105: fk.setCascadeDeleteEnabled(cascadeDeleteEnabled);
106: }
107: }
108:
109: public IdentifierGenerator createIdentifierGenerator(
110: Dialect dialect, String defaultCatalog,
111: String defaultSchema, RootClass rootClass)
112: throws MappingException {
113:
114: Properties params = new Properties();
115:
116: //if the hibernate-mapping did not specify a schema/catalog, use the defaults
117: //specified by properties - but note that if the schema/catalog were specified
118: //in hibernate-mapping, or as params, they will already be initialized and
119: //will override the values set here (they are in identifierGeneratorProperties)
120: if (defaultSchema != null) {
121: params.setProperty(PersistentIdentifierGenerator.SCHEMA,
122: defaultSchema);
123: }
124: if (defaultCatalog != null) {
125: params.setProperty(PersistentIdentifierGenerator.CATALOG,
126: defaultCatalog);
127: }
128:
129: //pass the entity-name, if not a collection-id
130: if (rootClass != null) {
131: params.setProperty(IdentifierGenerator.ENTITY_NAME,
132: rootClass.getEntityName());
133: }
134:
135: //init the table here instead of earlier, so that we can get a quoted table name
136: //TODO: would it be better to simply pass the qualified table name, instead of
137: // splitting it up into schema/catalog/table names
138: String tableName = getTable().getQuotedName(dialect);
139: params.setProperty(PersistentIdentifierGenerator.TABLE,
140: tableName);
141:
142: //pass the column name (a generated id almost always has a single column)
143: String columnName = ((Column) getColumnIterator().next())
144: .getQuotedName(dialect);
145: params
146: .setProperty(PersistentIdentifierGenerator.PK,
147: columnName);
148:
149: if (rootClass != null) {
150: StringBuffer tables = new StringBuffer();
151: Iterator iter = rootClass.getIdentityTables().iterator();
152: while (iter.hasNext()) {
153: Table table = (Table) iter.next();
154: tables.append(table.getQuotedName(dialect));
155: if (iter.hasNext())
156: tables.append(", ");
157: }
158: params.setProperty(PersistentIdentifierGenerator.TABLES,
159: tables.toString());
160: } else {
161: params.setProperty(PersistentIdentifierGenerator.TABLES,
162: tableName);
163: }
164:
165: if (identifierGeneratorProperties != null) {
166: params.putAll(identifierGeneratorProperties);
167: }
168:
169: return IdentifierGeneratorFactory
170: .create(identifierGeneratorStrategy, getType(), params,
171: dialect);
172:
173: }
174:
175: public boolean isUpdateable() {
176: //needed to satisfy KeyValue
177: return true;
178: }
179:
180: public FetchMode getFetchMode() {
181: return FetchMode.SELECT;
182: }
183:
184: public Properties getIdentifierGeneratorProperties() {
185: return identifierGeneratorProperties;
186: }
187:
188: public String getNullValue() {
189: return nullValue;
190: }
191:
192: public Table getTable() {
193: return table;
194: }
195:
196: /**
197: * Returns the identifierGeneratorStrategy.
198: * @return String
199: */
200: public String getIdentifierGeneratorStrategy() {
201: return identifierGeneratorStrategy;
202: }
203:
204: public boolean isIdentityColumn(Dialect dialect) {
205: return IdentifierGeneratorFactory.getIdentifierGeneratorClass(
206: identifierGeneratorStrategy, dialect).equals(
207: IdentityGenerator.class);
208: }
209:
210: /**
211: * Sets the identifierGeneratorProperties.
212: * @param identifierGeneratorProperties The identifierGeneratorProperties to set
213: */
214: public void setIdentifierGeneratorProperties(
215: Properties identifierGeneratorProperties) {
216: this .identifierGeneratorProperties = identifierGeneratorProperties;
217: }
218:
219: /**
220: * Sets the identifierGeneratorStrategy.
221: * @param identifierGeneratorStrategy The identifierGeneratorStrategy to set
222: */
223: public void setIdentifierGeneratorStrategy(
224: String identifierGeneratorStrategy) {
225: this .identifierGeneratorStrategy = identifierGeneratorStrategy;
226: }
227:
228: /**
229: * Sets the nullValue.
230: * @param nullValue The nullValue to set
231: */
232: public void setNullValue(String nullValue) {
233: this .nullValue = nullValue;
234: }
235:
236: public String getForeignKeyName() {
237: return foreignKeyName;
238: }
239:
240: public void setForeignKeyName(String foreignKeyName) {
241: this .foreignKeyName = foreignKeyName;
242: }
243:
244: public boolean isAlternateUniqueKey() {
245: return alternateUniqueKey;
246: }
247:
248: public void setAlternateUniqueKey(boolean unique) {
249: this .alternateUniqueKey = unique;
250: }
251:
252: public boolean isNullable() {
253: if (hasFormula())
254: return true;
255: boolean nullable = true;
256: Iterator iter = getColumnIterator();
257: while (iter.hasNext()) {
258: if (!((Column) iter.next()).isNullable()) {
259: nullable = false;
260: return nullable; //shortcut
261: }
262: }
263: return nullable;
264: }
265:
266: public boolean isSimpleValue() {
267: return true;
268: }
269:
270: public boolean isValid(Mapping mapping) throws MappingException {
271: return getColumnSpan() == getType().getColumnSpan(mapping);
272: }
273:
274: public Type getType() throws MappingException {
275: if (typeName == null) {
276: throw new MappingException("No type name");
277: }
278: Type result = TypeFactory.heuristicType(typeName,
279: typeParameters);
280: if (result == null) {
281: String msg = "Could not determine type for: " + typeName;
282: if (columns != null && columns.size() > 0) {
283: msg += ", for columns: " + columns;
284: }
285: throw new MappingException(msg);
286: }
287: return result;
288: }
289:
290: public void setTypeUsingReflection(String className,
291: String propertyName) throws MappingException {
292: if (typeName == null) {
293: if (className == null) {
294: throw new MappingException(
295: "you must specify types for a dynamic entity: "
296: + propertyName);
297: }
298: typeName = ReflectHelper.reflectedPropertyClass(className,
299: propertyName).getName();
300: }
301: }
302:
303: public boolean isTypeSpecified() {
304: return typeName != null;
305: }
306:
307: public void setTypeParameters(Properties parameterMap) {
308: this .typeParameters = parameterMap;
309: }
310:
311: public Properties getTypeParameters() {
312: return typeParameters;
313: }
314:
315: public String toString() {
316: return getClass().getName() + '(' + columns.toString() + ')';
317: }
318:
319: public Object accept(ValueVisitor visitor) {
320: return visitor.accept(this );
321: }
322:
323: public boolean[] getColumnInsertability() {
324: boolean[] result = new boolean[getColumnSpan()];
325: int i = 0;
326: Iterator iter = getColumnIterator();
327: while (iter.hasNext()) {
328: Selectable s = (Selectable) iter.next();
329: result[i++] = !s.isFormula();
330: }
331: return result;
332: }
333:
334: public boolean[] getColumnUpdateability() {
335: return getColumnInsertability();
336: }
337: }
|