protected void createEmbeddedAttributeProperty(
      PersistentDescriptor descriptor,
      EmbeddedAttribute embeddedAttribute,
      ObjAttribute attribute) {

    Class<?> embeddableClass = embeddedAttribute.getJavaClass();

    String propertyPath = attribute.getName();
    int lastDot = propertyPath.lastIndexOf('.');
    if (lastDot <= 0 || lastDot == propertyPath.length() - 1) {
      throw new IllegalArgumentException("Invalid embeddable path: " + propertyPath);
    }

    String embeddableName = propertyPath.substring(lastDot + 1);

    EmbeddableDescriptor embeddableDescriptor = createEmbeddableDescriptor(embeddedAttribute);

    Accessor embeddedAccessor =
        createAccessor(descriptor, embeddedAttribute.getName(), embeddableClass);
    Accessor embeddedableAccessor =
        createEmbeddableAccessor(embeddableDescriptor, embeddableName, attribute.getJavaClass());

    Accessor accessor =
        new EmbeddedFieldAccessor(embeddableDescriptor, embeddedAccessor, embeddedableAccessor);
    descriptor.addDeclaredProperty(new SimpleAttributeProperty(descriptor, accessor, attribute));
  }
 /** Creates a descriptor of the embedded property. */
 protected EmbeddableDescriptor createEmbeddableDescriptor(EmbeddedAttribute embeddedAttribute) {
   // TODO: andrus, 11/19/2007 = avoid creation of descriptor for every
   // property of
   // embeddable; look up reusable descriptor instead.
   return new FieldEmbeddableDescriptor(
       embeddedAttribute.getEmbeddable(), "owner", "embeddedProperty");
 }
  protected ClassDescriptor getDescriptor(ObjEntity entity, Class<?> entityClass) {
    String superEntityName = entity.getSuperEntityName();

    ClassDescriptor superDescriptor =
        (superEntityName != null) ? descriptorMap.getDescriptor(superEntityName) : null;

    PersistentDescriptor descriptor = createDescriptor();

    descriptor.setEntity(entity);
    descriptor.setSuperclassDescriptor(superDescriptor);
    descriptor.setObjectClass(entityClass);
    descriptor.setPersistenceStateAccessor(
        new BeanAccessor(entityClass, "persistenceState", Integer.TYPE));

    // only include this entity attributes and skip superclasses...
    for (ObjAttribute attribute : descriptor.getEntity().getDeclaredAttributes()) {

      if (attribute instanceof EmbeddedAttribute) {
        EmbeddedAttribute embedded = (EmbeddedAttribute) attribute;
        for (ObjAttribute objAttribute : embedded.getAttributes()) {
          createEmbeddedAttributeProperty(descriptor, embedded, objAttribute);
        }
      } else {
        createAttributeProperty(descriptor, attribute);
      }
    }

    // only include this entity relationships and skip superclasses...
    for (ObjRelationship relationship : descriptor.getEntity().getDeclaredRelationships()) {

      if (relationship.isToMany()) {

        String collectionType = relationship.getCollectionType();
        if (collectionType == null
            || ObjRelationship.DEFAULT_COLLECTION_TYPE.equals(collectionType)) {
          createToManyListProperty(descriptor, relationship);
        } else if (collectionType.equals("java.util.Map")) {
          createToManyMapProperty(descriptor, relationship);
        } else if (collectionType.equals("java.util.Set")) {
          createToManySetProperty(descriptor, relationship);
        } else if (collectionType.equals("java.util.Collection")) {
          createToManyCollectionProperty(descriptor, relationship);
        } else {
          throw new IllegalArgumentException(
              "Unsupported to-many collection type: " + collectionType);
        }
      } else {
        createToOneProperty(descriptor, relationship);
      }
    }

    EntityInheritanceTree inheritanceTree =
        descriptorMap.getResolver().getInheritanceTree(descriptor.getEntity().getName());
    descriptor.setEntityInheritanceTree(inheritanceTree);
    indexSubclassDescriptors(descriptor, inheritanceTree);
    indexQualifiers(descriptor, inheritanceTree);

    appendDeclaredRootDbEntity(descriptor, descriptor.getEntity());
    indexRootDbEntities(descriptor, inheritanceTree);

    indexSuperclassProperties(descriptor);

    descriptor.sortProperties();

    return descriptor;
  }