castor
  1. castor
  2. CASTOR-2279

ClassCastException in method org.exolab.castor.xml.schema.writer.SchemaWriter.processSimpleType

    Details

    • Type: Bug Bug
    • Status: Closed Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 1.1, 1.1.1, 1.1.2, 1.1.2.1
    • Fix Version/s: 1.3 rc1
    • Component/s: XML
    • Labels:
      None
    • Environment:
      Castor v1.0
      Xerces J v2.6.2
      JDK v1.5.0_06
    • Number of attachments :
      4

      Description

      In class "org.exolab.castor.xml.schema.writer.SchemaWriter", method "processSimpleType", when looking for the base type of a simple type the only call performed is the one prefixed with a star character:

      private void processSimpleType (SimpleType simpleType, String schemaPrefix) throws SAXException {
      [...]
      //-- handle restriction

      • SimpleType base = (SimpleType)simpleType.getBaseType();
        boolean isRestriction = false;
        if (base != null)
        Unknown macro: { if (simpleType instanceof ListType) { isRestriction = (base instanceof ListType); } else isRestriction = true; }

        [...]
        }

      However, if that reference happens to be null for any reason, then we enter a series of conditions into which the simple element is trusted to be either a union or a list (see lines prefixed with star below):

      private void processSimpleType (SimpleType simpleType, String schemaPrefix) throws SAXException {
      [...]
      else if (simpleType instanceof Union)

      { * processUnion((Union)simpleType, schemaPrefix); }

      //-- handle List
      else

      { String ELEM_LIST = schemaPrefix + SchemaNames.LIST; _atts.clear(); * SimpleType itemType = ((ListType)simpleType).getItemType(); [...] }

      This leads to a potentially invalid cast operation if the simple type isn't one of these though, and unfortunately I got the case, with a simple type being an instance of "org.exolab.castor.xml.schema.DeferredSimpleType", and having a base type defined into another (imported) schema.
      This instance had a null reference to its base type, and caused a class cast exception for being casted to a ListType in the code mentionned above.

      The fix I made in order to unblock the issue locally is to enable a walk throught the list of imported schemas in order to look for the missing base type reference.
      To find the base type instance, I'm using the base type name owned by the simple type that is currently processed.

      To gain ability to find the base type name, I augment the class "org.exolab.castor.xml.schema.XMLType" with a getter on it:

      public String getBaseTypeName()

      { return baseType != null ? baseType.getName() : null; }

      Then in class "org.exolab.castor.xml.schema.DeferredSimpleType", which happens to be the one for which the class cast error occurred for me, I override this getter to return the instance field "baseTypeName" :

      public String getBaseTypeName()

      { return baseTypeName; }

      Now we can go back to method "processSimpleType" of class "org.exolab.castor.xml.schema.writer.SchemaWriter" and complement it with an additional attempt of resolving the reference to the base type:

      private void processSimpleType (SimpleType simpleType, String schemaPrefix) throws SAXException {
      [...]
      //-- handle restriction
      SimpleType base = (SimpleType)simpleType.getBaseType();

      // ADDED (BEGIN)
      String baseTypeName = simpleType.getBaseTypeName();
      if(base == null && baseTypeName != null)

      { Schema schema = simpleType.getSchema(); * base = getTypeFromSchema(schema, baseTypeName); }

      // ADDED (END)

      boolean isRestriction = false;
      [...]
      }

      The method "getTypeFromSchema" mentiomned on the line prefixed with a star is added to this class as well:

      private SimpleType getTypeFromSchema(Schema schema, String typeName) {
      SimpleType base = schema.getSimpleType(typeName);
      if(base == null) {
      Enumeration imports = schema.getImportedSchema();
      while (imports.hasMoreElements() && base == null)

      { Schema sch = (Schema) imports.nextElement(); base = getTypeFromSchema(sch, typeName); }

      }
      return base;
      }

      This allows me to fix the issue, although I'm not sure this is the fix that you guys would apply, since I'm not even sure that this is normal that I got an instance of "org.exolab.castor.xml.schema.DeferredSimpleType" with a null reference to a base type.

      Still, if this can be of any help, then all these debugging hours will not be lost.

      Thanks & regards,
      Alex.

      1. patch.c2279.20080205.txt
        4 kB
        Werner Guttmann

        Activity

        Werner Guttmann logged work - 05/Feb/08 4:37 PM
        • Time Spent:
          20 minutes
           
          Patch creation from individual patches.

          People

          • Assignee:
            Werner Guttmann
            Reporter:
            Alexandre Delarge
          • Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Time Tracking

              Estimated:
              Original Estimate - Not Specified
              Not Specified
              Remaining:
              Remaining Estimate - 0 minutes
              0m
              Logged:
              Time Spent - 20 minutes
              20m