/** * INTERNAL: * This method is used to turn the a raw database field value classFieldValue into a Class object. Used to determine * which class objects to build from database results, and for class type expression */ public Class classFromValue(Object classFieldValue, AbstractSession session) throws DescriptorException { Class concreteClass; if (!shouldUseClassNameAsIndicator()) { concreteClass = (Class)getClassIndicatorMapping().get(classFieldValue); if (concreteClass == null) { throw DescriptorException.missingClassForIndicatorFieldValue(classFieldValue, getDescriptor()); } } else { try { String className = (String)classFieldValue; //PWK 2.5.1.7 can not use class for name, must go through conversion manager. //Should use the root ClassDescriptor's classloader to avoid loading from a loader other //than the one that loaded the project concreteClass = getDescriptor().getJavaClass().getClassLoader().loadClass(className); if (concreteClass == null) { throw DescriptorException.missingClassForIndicatorFieldValue(classFieldValue, getDescriptor()); } } catch (ClassNotFoundException e) { throw DescriptorException.missingClassForIndicatorFieldValue(classFieldValue, getDescriptor()); } catch (ClassCastException e) { throw DescriptorException.missingClassForIndicatorFieldValue(classFieldValue, getDescriptor()); } } return concreteClass; }
/** * INTERNAL: * Initialize the expression to use for queries to the class and its subclasses. */ protected void initializeWithAllSubclassesExpression() throws DescriptorException { if (getWithAllSubclassesExpression() == null) { if (hasClassExtractor()) { return; } if (isChildDescriptor() && shouldReadSubclasses()) { setWithAllSubclassesExpression(new ExpressionBuilder().getField(getClassIndicatorField()).in(getAllChildClassIndicators())); } } }
/** * INTERNAL: * This initialized method is used exclusively for inheritance. It passes in * true if the child descriptor is isolated. * * This is needed by regular aggregate descriptors (because they require review); * but not by SDK aggregate descriptors. */ public void initializeAggregateInheritancePolicy(AbstractSession session) { ClassDescriptor parentDescriptor = session.getDescriptor(getInheritancePolicy().getParentClass()); parentDescriptor.getInheritancePolicy().addChildDescriptor(this); }
/** * INTERNAL: * call addChildTableJoinExpression on all parents */ public void addChildTableJoinExpressionToAllParents(DatabaseTable table, Expression expression) { ClassDescriptor parentDescriptor = getParentDescriptor(); while(parentDescriptor != null) { InheritancePolicy parentPolicy = parentDescriptor.getInheritancePolicy(); parentPolicy.addChildTableJoinExpression(table, expression); parentDescriptor = parentPolicy.getParentDescriptor(); } }
/** * INTERNAL: * Return the root parent descriptor */ public ClassDescriptor getRootParentDescriptor() { if (this.rootParentDescriptor == null) { if (isRootParentDescriptor()) { this.rootParentDescriptor = getDescriptor(); } else { this.rootParentDescriptor = getParentDescriptor().getInheritancePolicy().getRootParentDescriptor(); } } return rootParentDescriptor; }
/** * INTERNAL: * Setup the default classExtractionMethod, or if one was specified by the user make sure it is valid. */ protected void initializeClassExtractor(AbstractSession session) throws DescriptorException { if (getClassExtractor() == null) { if (isChildDescriptor()) { setClassExtractor(getParentDescriptor().getInheritancePolicy().getClassExtractor()); } } else { getClassExtractor().initialize(getDescriptor(), session); } }
public ClassDescriptor buildLogConfigDescriptor() { XMLDescriptor descriptor = new XMLDescriptor(); descriptor.setJavaClass(LogConfig.class); descriptor.getInheritancePolicy().setClassIndicatorField(new XMLField("@xsi:type")); descriptor.getInheritancePolicy().addClassIndicator(DefaultSessionLogConfig.class, "eclipselink-log"); descriptor.getInheritancePolicy().addClassIndicator(JavaLogConfig.class, "java-log"); descriptor.getInheritancePolicy().addClassIndicator(ServerLogConfig.class, "server-log"); return descriptor; }
/** * INTERNAL: * Used to initialize a remote descriptor. */ public void remoteInitialization(DistributedSession session) { if (isChildDescriptor()) { if (session.hasCorrespondingDescriptor(getParentDescriptor())) { setParentDescriptor(session.getDescriptor(getParentClass())); } else { session.privilegedAddDescriptor(getParentDescriptor()); getParentDescriptor().remoteInitialization(session); } } Vector tempChildren = new Vector(getChildDescriptors().size()); for (ClassDescriptor childDescriptor : getChildDescriptors()) { if (session.hasCorrespondingDescriptor(childDescriptor)) { tempChildren.addElement(session.getDescriptor(childDescriptor.getJavaClass())); } else { session.privilegedAddDescriptor(childDescriptor); childDescriptor.remoteInitialization(session); tempChildren.addElement(childDescriptor); } } setChildDescriptors(tempChildren); }
/** * Hook together the inheritance policy tree. */ protected void preInitializeInheritancePolicy(AbstractSession session) throws DescriptorException { if (isChildDescriptor() && (requiresInitialization())) { if (getInheritancePolicy().getParentClass().equals(getJavaClass())) { setInterfaceInitializationStage(ERROR); throw DescriptorException.parentClassIsSelf(this); } ClassDescriptor parentDescriptor = session.getDescriptor(getInheritancePolicy().getParentClass()); parentDescriptor.getInheritancePolicy().addChildDescriptor(this); getInheritancePolicy().setParentDescriptor(parentDescriptor); parentDescriptor.preInitialize(session); } }
/** * INTERNAL * This method returns the inheritance field value for an object to conform in an in-memory query. * Similar to getFieldValue, but deals with an instance rather than a Class object directly */ public Object typeValueFromObject(Object object, AbstractSession session) { // get the descriptor directly from the object, and use it to find the Java class ClassDescriptor objectDescriptor = session.getClassDescriptor(object); if (!objectDescriptor.hasInheritance() || objectDescriptor.getInheritancePolicy().shouldUseClassNameAsIndicator() || objectDescriptor.getInheritancePolicy().hasClassExtractor() ) { return (objectDescriptor.getJavaClassName()); } else { return objectDescriptor.getInheritancePolicy().getClassIndicatorMapping().get(objectDescriptor.getJavaClass()); } }
/** * INTERNAL: * Potentially override the optimistic locking behavior */ protected void initializeOptimisticLocking(){ // CR#3214106, do not override if specified in subclass. if (!getDescriptor().usesOptimisticLocking() && getParentDescriptor().usesOptimisticLocking()) { getDescriptor().setOptimisticLockingPolicy((OptimisticLockingPolicy)getParentDescriptor().getOptimisticLockingPolicy().clone()); getDescriptor().getOptimisticLockingPolicy().setDescriptor(getDescriptor()); } }
protected ClassDescriptor buildIgnoreNewElementsOrderingPolicyConfigDescriptor() { XMLDescriptor descriptor = new XMLDescriptor(); descriptor.setJavaClass(IgnoreNewElementsOrderingPolicyConfig.class); descriptor.getInheritancePolicy().setParentClass(NodeOrderingPolicyConfig.class); return descriptor; }
/** * INTERNAL: * Add abstract class indicator information to the database row. This is * required when building a row for an insert or an update of a concrete child * descriptor. * This is only used to build a template row. */ public void addClassIndicatorFieldToInsertRow(AbstractRecord databaseRow) { if (hasClassExtractor()) { return; } DatabaseField field = getClassIndicatorField(); databaseRow.put(field, null); }
/** * INTERNAL: * Returns the indicator field value for the given class * If no abstract indicator mapping is specified, use the class name. */ protected Object getClassIndicatorValue(Class javaClass) { if (shouldUseClassNameAsIndicator()) { return javaClass.getName(); } else { return getClassIndicatorMapping().get(javaClass); } }
/** * INTERNAL: * Add abstract class indicator information to the database row. This is * required when building a row for an insert or an update of a concrete child * descriptor. */ public void addClassIndicatorFieldToRow(AbstractRecord databaseRow) { if (hasClassExtractor()) { return; } DatabaseField field = getClassIndicatorField(); Object value = getClassIndicatorValue(); databaseRow.put(field, value); }
/** * PUBLIC: * This method returns the root descriptor for for this descriptor's class heirarchy. * If the user is not using inheritance then the root class will be this class. */ public ClassDescriptor getRootDescriptor(){ if (this.hasInheritance()){ return this.getInheritancePolicy().getRootParentDescriptor(); } return this; }
/** * INTERNAL: * Select one row of any concrete subclass, * This must use two selects, the first retrieves the type field only. */ protected AbstractRecord selectOneRowUsingDefaultMultipleTableSubclassRead(ReadObjectQuery query) throws DatabaseException, QueryException { // Get the row for the given class indicator field // The indicator select is prepared in the original query, so can just be executed. AbstractRecord typeRow = ((ExpressionQueryMechanism)query.getQueryMechanism()).selectOneRowFromTable(); if (typeRow == null) { return null; } Class concreteClass = classFromRow(typeRow, query.getSession()); ClassDescriptor concreteDescriptor = getDescriptor(concreteClass); if (concreteDescriptor == null) { throw QueryException.noDescriptorForClassFromInheritancePolicy(query, concreteClass); } ReadObjectQuery concreteQuery = (ReadObjectQuery)query.clone(); concreteQuery.setReferenceClass(concreteClass); concreteQuery.setDescriptor(concreteDescriptor); AbstractRecord resultRow = ((ExpressionQueryMechanism)concreteQuery.getQueryMechanism()).selectOneRowFromConcreteTable(); return resultRow; }
/** * INTERNAL: * Checks if the class is involved in inheritance */ public boolean hasClassIndicator() { return getClassIndicatorField() != null; }
/** * INTERNAL: * Return a sub-partition of the row starting at the index. */ public AbstractRecord trimRowForJoin(AbstractRecord row, Object value, AbstractSession executionSession) { // CR #... the field for many objects may be in the row, // so build the subpartion of the row through the computed values in the query, // this also helps the field indexing match. int fieldStartIndex; if (value instanceof Integer) { fieldStartIndex = ((Integer)value).intValue(); } else { // must be Map of classes to Integers Map map = (Map)value; Class cls; if (getDescriptor().hasInheritance() && getDescriptor().getInheritancePolicy().shouldReadSubclasses()) { cls = getDescriptor().getInheritancePolicy().classFromRow(row, executionSession); } else { cls = getDescriptor().getJavaClass(); } fieldStartIndex = ((Integer)map.get(cls)).intValue(); } Vector trimedFields = new NonSynchronizedSubVector(row.getFields(), fieldStartIndex, row.size()); Vector trimedValues = new NonSynchronizedSubVector(row.getValues(), fieldStartIndex, row.size()); return new DatabaseRecord(trimedFields, trimedValues); }
/** * PUBLIC: * Add a class indicator for the root classes subclass. * The indicator is used to determine the class to use for a row read from the database, * and to query only instances of a class from the database. * Every concrete persistent subclass must have a single unique indicator defined for it. * If the root class is concrete then it must also define an indicator. * Only the root class's descriptor of the entire inheritance hierarchy can define the class indicator mapping. */ public void addClassIndicator(Class childClass, Object typeValue) { // Note we should think about supporting null values. // Store as key and value for bi-directional lookup. getClassIndicatorMapping().put(typeValue, childClass); getClassIndicatorMapping().put(childClass, typeValue); }