/**
   * INTERNAL: For this Type generate classes
   *
   * @param packageName
   * @param nr
   */
  public void preInitialize(String packageName, List namespaceResolvers) {
    String instanceClassName = getInstanceClassName();
    if (null == instanceClassName) {
      if (null == packageName) {
        String uri = getURI();
        if (null == uri) {
          packageName = SDOUtil.getDefaultPackageName() + SDOConstants.JAVA_PACKAGE_NAME_SEPARATOR;
        } else {
          packageName =
              SDOUtil.getPackageNameFromURI(uri) + SDOConstants.JAVA_PACKAGE_NAME_SEPARATOR;
        }
      }

      // Verify and fix any Class name that does not conform to conventions
      // run the class name through the JAXB mangler
      String mangledClassName = SDOUtil.className(getName(), false, true, true);

      // we will not fix any type collision at this time as a result of class renaming
      // write fully qualified java class name
      StringBuffer fullClassName = new StringBuffer(packageName);
      fullClassName.append(mangledClassName);
      setInstanceClassName(fullClassName.toString());
    }
    AbstractSessionLog.getLog()
        .log(
            AbstractSessionLog.FINER, //
            "sdo_type_generation_processing_type", //
            new Object[] {Helper.getShortClassName(getClass()), getInstanceClassName()});

    initializeNamespaces(namespaceResolvers);
    getXmlDescriptor().setJavaClassName(getImplClassName());

    // See SDOResolvable enhancement
    String schemaContext = getName();
    if (getXmlDescriptor().getNamespaceResolver() != null) {
      String prefix = getXmlDescriptor().getNamespaceResolver().resolveNamespaceURI(getURI());
      if ((prefix != null) && !prefix.equals(SDOConstants.EMPTY_STRING)) {
        schemaContext = prefix + SDOConstants.SDO_XPATH_NS_SEPARATOR_FRAGMENT + schemaContext;
      }
    }
    String schemaContextWithSlash = SDOConstants.SDO_XPATH_SEPARATOR_FRAGMENT + schemaContext;

    XMLSchemaReference schemaRef = new XMLSchemaClassPathReference();
    schemaRef.setSchemaContext(schemaContextWithSlash);
    schemaRef.setType(XMLSchemaReference.COMPLEX_TYPE);
    getXmlDescriptor().setSchemaReference(schemaRef);
  }
  @Override
  public void writeXsiTypeAttribute(
      Descriptor xmlDescriptor, XMLSchemaReference xmlRef, boolean addToNamespaceResolver) {
    QName contextAsQName = xmlRef.getSchemaContextAsQName();

    if (contextAsQName == null) {
      contextAsQName = xmlRef.getSchemaContextAsQName(namespaceResolver);
    }
    if (contextAsQName != null) {
      writeXsiTypeAttribute(
          xmlDescriptor,
          contextAsQName.getNamespaceURI(),
          contextAsQName.getLocalPart(),
          null,
          addToNamespaceResolver);
    }
  }
  public boolean addXsiTypeAndClassIndicatorIfRequired(
      Descriptor descriptor,
      Descriptor referenceDescriptor,
      Field xmlField,
      boolean isRootElement) {
    ObjectBuilder objectBuilder = (ObjectBuilder) descriptor.getObjectBuilder();
    boolean xsiTypeIndicatorField = objectBuilder.isXsiTypeIndicatorField();

    if (objectBuilder.addClassIndicatorFieldToRow(this)) {
      return true;
    }

    QName leafType = null;
    if (xmlField != null) {
      leafType = xmlField.getLeafElementType();

      XMLSchemaReference xmlRef = descriptor.getSchemaReference();
      if (xmlRef != null) {
        if (leafType == null) {
          if (xmlRef.getType() == XMLSchemaReference.ELEMENT) {
            return false;
          }
          if (referenceDescriptor == null) {
            writeXsiTypeAttribute(descriptor, xmlRef, isRootElement);
            return true;
          }
        } else if (((xmlRef.getType() == XMLSchemaReference.COMPLEX_TYPE)
                || (xmlRef.getType() == XMLSchemaReference.SIMPLE_TYPE))
            && xmlRef.getSchemaContext() != null
            && xmlRef.isGlobalDefinition()) {
          QName ctxQName = xmlRef.getSchemaContextAsQName(descriptor.getNamespaceResolver());
          if (!ctxQName.equals(leafType)) {
            writeXsiTypeAttribute(descriptor, xmlRef, isRootElement);
            return true;
          }
        }
      }
    }

    if (referenceDescriptor != null && referenceDescriptor == descriptor) {
      return false;
    }
    if (descriptor.hasInheritance()
        && !descriptor.getInheritancePolicy().isRootParentDescriptor()) {
      CoreInheritancePolicy inheritancePolicy = descriptor.getInheritancePolicy();
      Field indicatorField = (Field) inheritancePolicy.getClassIndicatorField();
      if (indicatorField != null && xsiTypeIndicatorField) {
        Object classIndicatorValueObject =
            inheritancePolicy.getClassIndicatorMapping().get(descriptor.getJavaClass());
        String classIndicatorUri = null;
        String classIndicatorLocal = null;
        String classIndicatorPrefix = null;
        if (classIndicatorValueObject instanceof QName) {
          QName classIndicatorQName = (QName) classIndicatorValueObject;
          classIndicatorUri = classIndicatorQName.getNamespaceURI();
          classIndicatorLocal = classIndicatorQName.getLocalPart();
          classIndicatorPrefix = classIndicatorQName.getPrefix();
        } else {
          String classIndicatorValue =
              (String) inheritancePolicy.getClassIndicatorMapping().get(descriptor.getJavaClass());
          int nsindex = classIndicatorValue.indexOf(Constants.COLON);
          String prefix = null;
          if (nsindex != -1) {
            classIndicatorLocal = classIndicatorValue.substring(nsindex + 1);
            prefix = classIndicatorValue.substring(0, nsindex);
          } else {
            classIndicatorLocal = classIndicatorValue;
          }
          classIndicatorUri =
              descriptor.getNonNullNamespaceResolver().resolveNamespacePrefix(prefix);
        }
        if (leafType == null
            || isRootElement && marshaller.isApplicationJSON() && !marshaller.isIncludeRoot()
            || !(leafType.getLocalPart().equals(classIndicatorLocal))
            || (classIndicatorUri == null
                && (leafType.getNamespaceURI() != null && leafType.getNamespaceURI().length() > 0))
            || (classIndicatorUri != null
                && !classIndicatorUri.equals(leafType.getNamespaceURI()))) {
          if (inheritancePolicy.hasClassExtractor()) {
            objectBuilder.addClassIndicatorFieldToRow(this);
          } else {
            writeXsiTypeAttribute(
                descriptor,
                classIndicatorUri,
                classIndicatorLocal,
                classIndicatorPrefix,
                isRootElement);
          }
          return true;
        }
        return false;
      }
    }
    return false;
  }