Return-Path: Delivered-To: apmail-db-ojb-dev-archive@www.apache.org Received: (qmail 35423 invoked from network); 7 Feb 2006 21:53:58 -0000 Received: from hermes.apache.org (HELO mail.apache.org) (209.237.227.199) by minotaur.apache.org with SMTP; 7 Feb 2006 21:53:58 -0000 Received: (qmail 17223 invoked by uid 500); 7 Feb 2006 21:53:58 -0000 Delivered-To: apmail-db-ojb-dev-archive@db.apache.org Received: (qmail 17063 invoked by uid 500); 7 Feb 2006 21:53:56 -0000 Mailing-List: contact ojb-dev-help@db.apache.org; run by ezmlm Precedence: bulk List-Unsubscribe: List-Help: List-Post: List-Id: "OJB Developers List" Reply-To: "OJB Developers List" Delivered-To: mailing list ojb-dev@db.apache.org Received: (qmail 17052 invoked by uid 500); 7 Feb 2006 21:53:56 -0000 Received: (qmail 17048 invoked by uid 99); 7 Feb 2006 21:53:56 -0000 Received: from asf.osuosl.org (HELO asf.osuosl.org) (140.211.166.49) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 07 Feb 2006 13:53:56 -0800 X-ASF-Spam-Status: No, hits=-9.4 required=10.0 tests=ALL_TRUSTED,NO_REAL_NAME X-Spam-Check-By: apache.org Received: from [209.237.227.194] (HELO minotaur.apache.org) (209.237.227.194) by apache.org (qpsmtpd/0.29) with SMTP; Tue, 07 Feb 2006 13:53:55 -0800 Received: (qmail 35059 invoked by uid 65534); 7 Feb 2006 21:53:34 -0000 Message-ID: <20060207215334.35057.qmail@minotaur.apache.org> Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r375730 - /db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/metadata/SuperReferenceDescriptor.java Date: Tue, 07 Feb 2006 21:53:34 -0000 To: ojb-commits@db.apache.org From: arminw@apache.org X-Mailer: svnmailer-1.0.6 X-Virus-Checked: Checked by ClamAV on apache.org X-Spam-Rating: minotaur.apache.org 1.6.2 0/1000/N Author: arminw Date: Tue Feb 7 13:53:33 2006 New Revision: 375730 URL: http://svn.apache.org/viewcvs?rev=375730&view=rev Log: improve definiton of table-per-subclass inheritance, cleanup code, comment out experimental code Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/metadata/SuperReferenceDescriptor.java Modified: db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/metadata/SuperReferenceDescriptor.java URL: http://svn.apache.org/viewcvs/db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/metadata/SuperReferenceDescriptor.java?rev=375730&r1=375729&r2=375730&view=diff ============================================================================== --- db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/metadata/SuperReferenceDescriptor.java (original) +++ db/ojb/branches/OJB_1_0_RELEASE/src/java/org/apache/ojb/broker/metadata/SuperReferenceDescriptor.java Tue Feb 7 13:53:33 2006 @@ -15,15 +15,17 @@ * limitations under the License. */ +import java.util.HashMap; import java.util.List; import java.util.Map; -import java.util.HashMap; +import java.util.Vector; +import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.SystemUtils; +import org.apache.commons.lang.builder.ToStringBuilder; import org.apache.ojb.broker.metadata.fieldaccess.AnonymousPersistentField; import org.apache.ojb.broker.metadata.fieldaccess.PersistentField; import org.apache.ojb.broker.metadata.fieldaccess.PersistentFieldFactory; -import org.apache.ojb.broker.util.ClassHelper; import org.apache.ojb.broker.util.logging.Logger; import org.apache.ojb.broker.util.logging.LoggerFactory; @@ -66,6 +68,29 @@ getClassDescriptor().setBaseClass(c.getName()); } + public Vector getForeignKeyFields() + { + Vector result = super.getForeignKeyFields(); + /* + if no FK field-ref is defined in metadata mapping + OJB simply use the PK fields as FK to the super-class + */ + if(result == null || result.size() == 0) + { + FieldDescriptor[] pks = getClassDescriptor().getPkFields(); + if(getLog().isDebugEnabled()) + { + getLog().debug("Automatically assign FK's for this super-reference, used fields will be: " + ArrayUtils.toString(pks)); + } + for(int i = 0; i < pks.length; i++) + { + FieldDescriptor pk = pks[i]; + addForeignKeyField(pk.getPersistentField().getName()); + } + } + return result; + } + /** * Noop, a specific {@link org.apache.ojb.broker.metadata.fieldaccess.PersistentField} is * used internal - {@link org.apache.ojb.broker.metadata.SuperReferenceDescriptor.SuperReferenceField}. @@ -86,42 +111,42 @@ public void setLazy(boolean lazy) { - getLog().info("Not allowed to change this property, will ignore setting"); + getLog().debug("Property 'lazy' is immutable, will ignore setting"); } public void setCascadeRetrieve(boolean b) { - getLog().info("Not allowed to change this property, will ignore setting"); + getLog().debug("Property 'CascadeRetrieve' is immutable, will ignore setting"); } public void setCascadingStore(int cascade) { - getLog().info("Not allowed to change this property, will ignore setting"); + getLog().debug("Property 'CascadingStore' is immutable, will ignore setting"); } public void setCascadingStore(String value) { - getLog().info("Not allowed to change this property, will ignore setting"); + getLog().debug("Property 'CascadingStore' is immutable, will ignore setting"); } public void setCascadingDelete(int cascade) { - getLog().info("Not allowed to change this property, will ignore setting"); + getLog().debug("Property 'CascadingDelete' is immutable, will ignore setting"); } public void setCascadingDelete(String value) { - getLog().info("Not allowed to change this property, will ignore setting"); + getLog().debug("Property 'CascadingDelete' is immutable, will ignore setting"); } public void setCascadeStore(boolean cascade) { - getLog().info("Not allowed to change this property, will ignore setting"); + getLog().debug("Property 'CascadeStore' is immutable, will ignore setting"); } public void setCascadeDelete(boolean cascade) { - getLog().info("Not allowed to change this property, will ignore setting"); + getLog().debug("Property 'CascadeDelete' is immutable, will ignore setting"); } public SuperReferenceField getInheritanceField() @@ -167,7 +192,7 @@ { if(log == null) { - log = LoggerFactory.getLogger(SuperReferenceField.class); + log = LoggerFactory.getLogger(SuperReferenceDescriptor.class); } return log; } @@ -212,11 +237,13 @@ ClassDescriptor superCld = superRef.getClassDescriptor().getSuperClassDescriptor(); if(superRef.isJavaInheritance()) { - copyFields(superCld, target, superCld, value, true, true); + copyFields(superCld, target, superCld, value); } else { - copyFields(superRef.getClassDescriptor(), target, superCld, value, false, false); + throw new MetadataException("Declared super class '" + superRef.getClassDescriptor() + + "'is not assignable from " + target.getClass() + ". Reference: " + toString()); + // copyFields(superRef.getClassDescriptor(), target, superCld, value, false, false); } } @@ -240,33 +267,14 @@ } else { - return getObjectWithDeclaredSuperClass(obj); - } - } - - private Object getObjectWithDeclaredSuperClass(Object obj) - { - Object value = getFromFieldCache(obj); - if(value == null) - { - ClassDescriptor baseCld = null; - try - { - baseCld = superRef.getClassDescriptor().getSuperClassDescriptor(); - value = ClassHelper.buildNewObjectInstance(baseCld); - } - catch(Exception e) - { - throw new MetadataException("Can't create new base class object for '" - + (baseCld != null ? baseCld.getClassNameOfObject() : null) + "'", e); - } - copyFields(baseCld, value, superRef.getClassDescriptor(), obj, true, false); - putToFieldCache(obj, value); + throw new MetadataException("Declared super class '" + superRef.getClassDescriptor() + + "'is not assignable from " + obj.getClass() + ". Reference: " + toString()); + // return getObjectWithDeclaredSuperClass(obj); } - return value; } - void copyFields(ClassDescriptor targetCld, Object target, ClassDescriptor sourceCld, Object source, boolean targetIsSuper, boolean javaInheritance) + void copyFields(final ClassDescriptor targetCld, final Object target, final ClassDescriptor sourceCld, + final Object source) { if(getLog().isDebugEnabled()) { @@ -275,76 +283,164 @@ + "using source fields declared in '" + sourceCld.getClassNameOfObject() + "'" + SystemUtils.LINE_SEPARATOR + "to target object '" + (target != null ? target.getClass().getName() : null) + "'" + SystemUtils.LINE_SEPARATOR + "using target fields declared in '" + targetCld.getClassNameOfObject() + "'" + SystemUtils.LINE_SEPARATOR - + "the fields to copy are declared in '" + (targetIsSuper ? targetCld.getClassNameOfObject() : sourceCld.getClassNameOfObject()) + "' class" + SystemUtils.LINE_SEPARATOR - + "the used classes are associated by java inheritance: " + javaInheritance + SystemUtils.LINE_SEPARATOR); + + "the fields to copy are declared in '" + targetCld.getClassNameOfObject()); getLog().debug(msg); } /* arminw: If the target object is a super object of the source object, iterate all target object fields. - If the source object is a super object of the target object, iterate all source object fields - If java inheritance is used (target is super class of source or vice versa) we can use the same FieldDescriptor to copy the fields. - If only a "declarative inheritance" is used (no class inheritance, only identical field names of the super class) - we have to use the associated FieldDescriptor of target and source ClassDescriptor */ - FieldDescriptor[] fields = targetIsSuper ? targetCld.getFieldDescriptions() : sourceCld.getFieldDescriptions(); + FieldDescriptor[] fields = targetCld.getFieldDescriptions(); for(int i = 0; i < fields.length; i++) { FieldDescriptor field = fields[i]; if(!field.isAnonymous()) { - performFieldCopy(target, targetCld, source, sourceCld, - field.getPersistentField(), targetIsSuper, javaInheritance); + performFieldCopy(target, source, field.getPersistentField()); } } - List refs = targetIsSuper ? targetCld.getCollectionDescriptors() : sourceCld.getCollectionDescriptors(); + List refs = targetCld.getCollectionDescriptors(); for(int i = 0; i < refs.size(); i++) { CollectionDescriptor col = (CollectionDescriptor) refs.get(i); PersistentField pf = col.getPersistentField(); - performFieldCopy(target, targetCld, source, sourceCld, pf, targetIsSuper, javaInheritance); + performFieldCopy(target, source, pf); } - refs = targetIsSuper ? targetCld.getObjectReferenceDescriptors() : sourceCld.getObjectReferenceDescriptors(); + refs = targetCld.getObjectReferenceDescriptors(); for(int i = 0; i < refs.size(); i++) { ObjectReferenceDescriptor ord = (ObjectReferenceDescriptor) refs.get(i); PersistentField pf = ord.getPersistentField(); - performFieldCopy(target, targetCld, source, sourceCld, pf, targetIsSuper, javaInheritance); + performFieldCopy(target, source, pf); } } - private void performFieldCopy(Object target, ClassDescriptor targetCld, Object source, - ClassDescriptor sourceCld, PersistentField pf, boolean targetIsSuper, boolean javaInheritance) + private void performFieldCopy(final Object target, final Object source, final PersistentField pf) { - if(javaInheritance) - { - pf.set(target, pf.get(source)); - } - else - { - if(targetIsSuper) - { - if(pf instanceof SuperReferenceField) - { - log.error("Declared inheritance doesn't support nested super references, target '" - + targetCld.getClassNameOfObject() + "' has super reference"); - } - else - { - PersistentField tmp = superRef.getDeclaredInheritanceField(sourceCld.getClassOfObject(), pf.getName()); - pf.set(target, tmp.get(source)); - } - } - else - { - PersistentField tmp = superRef.getDeclaredInheritanceField(targetCld.getClassOfObject(), pf.getName()); - tmp.set(target, pf.get(source)); - } - } + pf.set(target, pf.get(source)); } + + public String toString() + { + return new ToStringBuilder(this) + .append("name", getName()) + .append("type", getType()) + .append("super-reference", superRef) + .toString(); + } + +// arminw: the code below is a first attempt to support "table-per-subclass"-inheritance +// for objects without java-subclass inheritance. But it's only possible for simple single-level +// inheritance of "declared" objects +// void copyFields(final ClassDescriptor targetCld, final Object target, final ClassDescriptor sourceCld, +// final Object source, final boolean targetIsSuper, final boolean javaInheritance) +// { +// if(getLog().isDebugEnabled()) +// { +// String msg = ("Copy fields from " + SystemUtils.LINE_SEPARATOR +// + "source object '" + (source != null ? source.getClass().getName() : null) + "'" + SystemUtils.LINE_SEPARATOR +// + "using source fields declared in '" + sourceCld.getClassNameOfObject() + "'" + SystemUtils.LINE_SEPARATOR +// + "to target object '" + (target != null ? target.getClass().getName() : null) + "'" + SystemUtils.LINE_SEPARATOR +// + "using target fields declared in '" + targetCld.getClassNameOfObject() + "'" + SystemUtils.LINE_SEPARATOR +// + "the fields to copy are declared in '" + (targetIsSuper ? targetCld.getClassNameOfObject() : sourceCld.getClassNameOfObject()) + "' class" + SystemUtils.LINE_SEPARATOR +// + "the used classes are associated by java inheritance: " + javaInheritance + SystemUtils.LINE_SEPARATOR); +// getLog().debug(msg); +// } +// /* +// arminw: +// If the target object is a super object of the source object, iterate all target object fields. +// If the source object is a super object of the target object, iterate all source object fields +// +// If java inheritance is used (target is super class of source or vice versa) we can use the same +// FieldDescriptor to copy the fields. +// If only a "declarative inheritance" is used (no class inheritance, only identical field names of the super class) +// we have to use the associated FieldDescriptor of target and source ClassDescriptor +// */ +// FieldDescriptor[] fields = targetIsSuper ? targetCld.getFieldDescriptions() : sourceCld.getFieldDescriptions(); +// for(int i = 0; i < fields.length; i++) +// { +// FieldDescriptor field = fields[i]; +// if(!field.isAnonymous()) +// { +//// performFieldCopy(target, targetCld, source, sourceCld, +//// field.getPersistentField(), targetIsSuper, javaInheritance); +// performFieldCopy(target, source, field.getPersistentField()); +// } +// } +// List refs = targetIsSuper ? targetCld.getCollectionDescriptors() : sourceCld.getCollectionDescriptors(); +// for(int i = 0; i < refs.size(); i++) +// { +// CollectionDescriptor col = (CollectionDescriptor) refs.get(i); +// PersistentField pf = col.getPersistentField(); +// //performFieldCopy(target, targetCld, source, sourceCld, pf, targetIsSuper, javaInheritance); +// performFieldCopy(target, source, pf); +// } +// +// refs = targetIsSuper ? targetCld.getObjectReferenceDescriptors() : sourceCld.getObjectReferenceDescriptors(); +// for(int i = 0; i < refs.size(); i++) +// { +// ObjectReferenceDescriptor ord = (ObjectReferenceDescriptor) refs.get(i); +// PersistentField pf = ord.getPersistentField(); +// //performFieldCopy(target, targetCld, source, sourceCld, pf, targetIsSuper, javaInheritance); +// performFieldCopy(target, source, pf); +// } +// } +// +// +// private void performFieldCopy(Object target, ClassDescriptor targetCld, Object source, +// ClassDescriptor sourceCld, PersistentField pf, boolean targetIsSuper, boolean javaInheritance) +// { +// if(javaInheritance) +// { +// pf.set(target, pf.get(source)); +// } +// else +// { +// if(targetIsSuper) +// { +// if(pf instanceof SuperReferenceField) +// { +// log.error("Declared inheritance doesn't support nested super references, target '" +// + targetCld.getClassNameOfObject() + "' has super reference"); +// } +// else +// { +// PersistentField tmp = superRef.getDeclaredInheritanceField(sourceCld.getClassOfObject(), pf.getName()); +// pf.set(target, tmp.get(source)); +// } +// } +// else +// { +// PersistentField tmp = superRef.getDeclaredInheritanceField(targetCld.getClassOfObject(), pf.getName()); +// tmp.set(target, pf.get(source)); +// } +// } +// } +// +// private Object getObjectWithDeclaredSuperClass(Object obj) +// { +// Object value = getFromFieldCache(obj); +// if(value == null) +// { +// ClassDescriptor baseCld = null; +// try +// { +// baseCld = superRef.getClassDescriptor().getSuperClassDescriptor(); +// value = ClassHelper.buildNewObjectInstance(baseCld); +// } +// catch(Exception e) +// { +// throw new MetadataException("Can't create new base class object for '" +// + (baseCld != null ? baseCld.getClassNameOfObject() : null) + "'", e); +// } +// copyFields(baseCld, value, superRef.getClassDescriptor(), obj, true, false); +// putToFieldCache(obj, value); +// } +// return value; +// } } } --------------------------------------------------------------------- To unsubscribe, e-mail: ojb-dev-unsubscribe@db.apache.org For additional commands, e-mail: ojb-dev-help@db.apache.org