Java tutorial
package org.apache.ojb.broker.metadata; /* Copyright 2002-2005 The Apache Software Foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.io.Serializable; import java.util.Comparator; import org.apache.commons.lang.SerializationUtils; import org.apache.commons.lang.SystemUtils; import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.commons.lang.builder.ToStringStyle; import org.apache.ojb.broker.OJBRuntimeException; import org.apache.ojb.broker.metadata.fieldaccess.AnonymousPersistentField; import org.apache.ojb.broker.accesslayer.conversions.FieldConversion; import org.apache.ojb.broker.accesslayer.conversions.FieldConversionDefaultImpl; import org.apache.ojb.broker.util.ClassHelper; /** * A FieldDescriptor holds the mapping information for a specific member-variable * of a persistent object. * <br> * Note: Be careful when use references of this class or caching instances of this class, * because instances could become invalid (see {@link MetadataManager}). * * @author <a href="mailto:thma@apache.org">Thomas Mahler<a> * @version $Id: FieldDescriptor.java,v 1.36.2.3 2005/12/21 22:26:10 tomdz Exp $ */ public class FieldDescriptor extends AttributeDescriptorBase implements XmlCapable, Serializable { private static final long serialVersionUID = 7865777758296851949L; public static final String ACCESS_ANONYMOUS = RepositoryElements.TAG_ACCESS_ANONYMOUS; public static final String ACCESS_READONLY = RepositoryElements.TAG_ACCESS_READONLY; public static final String ACCESS_READWRITE = RepositoryElements.TAG_ACCESS_READWRITE; private int m_ColNo; private String m_ColumnName; private String m_ColumnType; private boolean m_IsKeyField = false; private boolean indexed = false; private boolean m_autoIncrement = false; private String m_sequenceName; private JdbcType m_jdbcType; private int length = 0; private int precision = 0; private int scale = 0; private boolean required = false; private boolean scaleSpecified = false; private boolean precisionSpecified = false; private boolean lengthSpecified = false; private FieldConversion fieldConversion = null; // true if field is used for optimistic locking BRJ private boolean m_locking = false; // if locking is true and updateLock is true then // on save lock columns will be updated. // if false then it is the responsibility of the // dbms to update all lock columns eg using triggers private boolean updateLock = true; private String m_access; /** * returns a comparator that allows to sort a Vector of FieldMappingDecriptors * according to their m_Order entries. */ public static Comparator getComparator() { return new Comparator() { public int compare(Object o1, Object o2) { FieldDescriptor fmd1 = (FieldDescriptor) o1; FieldDescriptor fmd2 = (FieldDescriptor) o2; if (fmd1.getColNo() < fmd2.getColNo()) { return -1; } else if (fmd1.getColNo() > fmd2.getColNo()) { return 1; } else { return 0; } } }; } /** * Constructor declaration * * @param cld The parent {@link ClassDescriptor} * @param id A field id - unique against all other fields in the {@link ClassDescriptor} */ public FieldDescriptor(ClassDescriptor cld, int id) { super(cld); m_ColNo = id; } /** * */ public String getColumnName() { return m_ColumnName; } /** * Answer the qualified ColumnName<br> * ie: myTab.name * * @return */ public String getFullColumnName() // BRJ { return getClassDescriptor().getFullTableName() + "." + getColumnName(); } public void setColumnName(String str) { m_ColumnName = str; } public String getColumnType() { return m_ColumnType; } public void setColumnType(String str) { m_ColumnType = str; m_jdbcType = lookupJdbcType(); } /** * Returns the corresponding database {@link JdbcType}) of this field, * defined by the JDBC 3.0 specification, e.g. <em>VARCHAR</em>, <em>VARBINARY</em> ... * <p/> * The complement class is {@link FieldType}) which manage the java field * type, e.g. a <em>String</em>, <em>byte[]</em> ... * * Returns the mapped jdbc type of this field (see complement {@link FieldType}), defined by * the JDBC specification. * @return The jdbc database type of this field. */ public JdbcType getJdbcType() { // check if jdbcType is assigned if (m_jdbcType == null) { m_jdbcType = lookupJdbcType(); } return m_jdbcType; } /** * determines the JDBC type (represented as an int value as specified * by java.sql.Types) of a FIELDDESCRIPTOR. * * @return int the int value representing the Type according to * java.sql.Types. */ private JdbcType lookupJdbcType() { JdbcType result = null; String columnType = getColumnType(); // if sql type was not set in metadata we use reflection // to determine sql type by reflection if (columnType == null) { try { result = JdbcTypesHelper.getJdbcTypeByReflection(m_PersistentField.getType().getName()); } catch (Exception e) { String eol = SystemUtils.LINE_SEPARATOR; throw new OJBRuntimeException("Can't automatically assign a jdbc field-type for field: " + eol + this.toXML() + eol + "in class: " + eol + getClassDescriptor(), e); } } else { try { result = JdbcTypesHelper.getJdbcTypeByName(columnType); } catch (Exception e) { String eol = SystemUtils.LINE_SEPARATOR; throw new OJBRuntimeException("Can't assign the specified jdbc field-type '" + columnType + "' for field: " + eol + this.toXML() + eol + "in class: " + eol + getClassDescriptor(), e); } } return result; } /** * Returns a string representation of this class. */ public String toString() { ToStringBuilder buf = new ToStringBuilder(this, ToStringStyle.DEFAULT_STYLE); buf.append("columnName", m_ColumnName); buf.append("columnType", m_ColumnType); buf.append("isPrimaryKey", m_IsKeyField); buf.append("isLocking", m_locking); buf.append("isAutoincrement", m_autoIncrement); buf.append("access", m_access); buf.append("sequenceName", m_sequenceName); buf.append("jdbcType", m_jdbcType); buf.append("super_class_fields ", "=> " + super.toString()); buf.append(SystemUtils.LINE_SEPARATOR); return buf.toString(); } /** * Gets the fieldConversion. * @return Returns a FieldConversion */ public FieldConversion getFieldConversion() { // if no conversion is specified use the default conversion if (fieldConversion == null) { fieldConversion = new FieldConversionDefaultImpl(); } return fieldConversion; } /** * Sets the fieldConversion. * @param fieldConversion The fieldConversion to set * @deprecated use setFieldConversionClassName instead */ public void setFieldConversion(FieldConversion fieldConversion) { this.fieldConversion = fieldConversion; } /** * Sets the fieldConversion. * @param fieldConversionClassName The fieldConversion to set */ public void setFieldConversionClassName(String fieldConversionClassName) { try { this.fieldConversion = (FieldConversion) ClassHelper.newInstance(fieldConversionClassName); } catch (Exception e) { throw new MetadataException("Could not instantiate FieldConversion class using default constructor", e); } } public boolean isIndexed() { return indexed; } public void setIndexed(boolean indexed) { this.indexed = indexed; } public boolean isAutoIncrement() { return m_autoIncrement; } public void setAutoIncrement(boolean autoIncrement) { m_autoIncrement = autoIncrement; } public String getSequenceName() { return m_sequenceName; } public void setSequenceName(String sequenceName) { m_sequenceName = sequenceName; } public boolean isPrimaryKey() { return m_IsKeyField; } public void setPrimaryKey(boolean b) { m_IsKeyField = b; } public int getColNo() { return m_ColNo; } /** * Gets the locking. * @return Returns a boolean */ public boolean isLocking() { return m_locking; } /** * Sets the locking. * @param locking The locking to set */ public void setLocking(boolean locking) { m_locking = locking; } /** * Gets the updateLock * updateLock controls whether the lock fields should be * updated by OJB when a row is saved * If false then the dbms needs to update the lock fields. * The default is true * @return Returns a boolean */ public boolean isUpdateLock() { return updateLock; } /** * Sets the updateLock * updateLock controls whether the lock fields should be * updated by OJB when a row is saved. * If false then the dbms needs to update the lock fields. * The default is true * @param updateLock The updateLock to set */ public void setUpdateLock(boolean updateLock) { this.updateLock = updateLock; } public void setLength(int length) { this.length = length; } public int getLength() { return this.length; } public void setPrecision(int precision) { this.precision = precision; } public int getPrecision() { return this.precision; } public void setScale(int scale) { this.scale = scale; } public int getScale() { return this.scale; } public boolean isRequired() { return required; } public void setRequired(boolean required) { this.required = required; } public boolean isScaleSpecified() { return scaleSpecified; } public void setScaleSpecified(boolean scaleSpecified) { this.scaleSpecified = scaleSpecified; } public boolean isPrecisionSpecified() { return precisionSpecified; } public void setPrecisionSpecified(boolean precisionSpecified) { this.precisionSpecified = precisionSpecified; } public boolean isLengthSpecified() { return lengthSpecified; } public void setLengthSpecified(boolean lengthSpecified) { this.lengthSpecified = lengthSpecified; } public String getAccess() { return m_access; } public void setAccess(String access) { if (access == null) { access = ACCESS_READWRITE; } if (ACCESS_ANONYMOUS.equals(access) || ACCESS_READONLY.equals(access) || ACCESS_READWRITE.equals(access)) { m_access = access; } else { throw new OJBRuntimeException("Try to set unkown field 'access' value: " + access); } } public boolean isAccessReadOnly() { return ACCESS_READONLY.equals(getAccess()); } /** * Returns <em>true</em> if this field is declared as anonymous field. */ public boolean isAnonymous() { return AnonymousPersistentField.class.isAssignableFrom(getPersistentField().getClass()) ? true : false; } /* * @see XmlCapable#toXML() */ public String toXML() { RepositoryTags tags = RepositoryTags.getInstance(); String eol = SystemUtils.LINE_SEPARATOR; //opening tag + attributes StringBuffer result = new StringBuffer(1024); result.append(" "); result.append(tags.getOpeningTagNonClosingById(FIELD_DESCRIPTOR)); result.append(" "); result.append(eol); // // id // String id = new Integer(getColNo()).toString(); // result += /*" " +*/ tags.getAttribute(ID, id) + eol; // name result.append(" "); result.append(tags.getAttribute(FIELD_NAME, this.getAttributeName())); result.append(eol); // table not yet implemented // column result.append(" "); result.append(tags.getAttribute(COLUMN_NAME, this.getColumnName())); result.append(eol); // jdbc-type result.append(" "); result.append(tags.getAttribute(JDBC_TYPE, this.getColumnType())); result.append(eol); // primarykey if (this.isPrimaryKey()) { result.append(" "); result.append(tags.getAttribute(PRIMARY_KEY, "true")); result.append(eol); } // nullable if (this.isRequired()) { result.append(" "); result.append(tags.getAttribute(NULLABLE, "false")); result.append(eol); } // indexed not yet implemented // autoincrement if (this.isAutoIncrement()) { result.append(" "); result.append(tags.getAttribute(AUTO_INCREMENT, "true")); result.append(eol); } // locking if (this.isLocking()) { result.append(" "); result.append(tags.getAttribute(LOCKING, "true")); result.append(eol); } // updateLock // default is true so only write if false if (!this.isUpdateLock()) { result.append(" "); result.append(tags.getAttribute(UPDATE_LOCK, "false")); result.append(eol); } // default-fetch not yet implemented // conversion if (this.getFieldConversion().getClass() != FieldConversionDefaultImpl.class) { result.append(" "); result.append(tags.getAttribute(FIELD_CONVERSION, getFieldConversion().getClass().getName())); result.append(eol); } // length if (this.isLengthSpecified()) { result.append(" "); result.append(tags.getAttribute(LENGTH, "" + getLength())); result.append(eol); } // precision if (this.isPrecisionSpecified()) { result.append(" "); result.append(tags.getAttribute(PRECISION, "" + getPrecision())); result.append(eol); } // scale if (this.isScaleSpecified()) { result.append(" "); result.append(tags.getAttribute(SCALE, "" + getScale())); result.append(eol); } // access result.append(" "); result.append(tags.getAttribute(ACCESS, this.getAccess())); result.append(eol); result.append(" />"); result.append(eol); return result.toString(); } public Object clone() { return SerializationUtils.deserialize(SerializationUtils.serialize(this)); } }