private void buildExceptionType()

in rt/databinding/jaxb/src/main/java/org/apache/cxf/jaxb/JAXBSchemaInitializer.java [470:602]


    private void buildExceptionType(MessagePartInfo part, Class<?> cls) {
        SchemaInfo schemaInfo = null;
        for (SchemaInfo s : serviceInfo.getSchemas()) {
            if (s.getNamespaceURI().equals(part.getElementQName().getNamespaceURI())) {
                schemaInfo = s;
                break;
            }
        }
        XmlAccessorOrder xmlAccessorOrder = cls.getAnnotation(XmlAccessorOrder.class);
        XmlType xmlTypeAnno = cls.getAnnotation(XmlType.class);
        String[] propertyOrder = null;
        boolean respectXmlTypeNS = false;
        XmlSchema faultBeanSchema = null;
        if (xmlTypeAnno != null && !StringUtils.isEmpty(xmlTypeAnno.namespace())
            && !xmlTypeAnno.namespace().equals(part.getElementQName().getNamespaceURI())) {
            respectXmlTypeNS = true;
            NamespaceMap nsMap = new NamespaceMap();
            nsMap.add(WSDLConstants.CONVENTIONAL_TNS_PREFIX, xmlTypeAnno.namespace());
            nsMap.add(WSDLConstants.NP_SCHEMA_XSD, WSDLConstants.NS_SCHEMA_XSD);

            SchemaInfo faultBeanSchemaInfo = createSchemaIfNeeded(xmlTypeAnno.namespace(), nsMap);
            faultBeanSchema = faultBeanSchemaInfo.getSchema();
        }

        if (xmlTypeAnno != null &&  xmlTypeAnno.propOrder().length > 0) {
            propertyOrder = xmlTypeAnno.propOrder();
            //TODO: handle @XmlAccessOrder
        }

        if (schemaInfo == null) {
            NamespaceMap nsMap = new NamespaceMap();
            nsMap.add(WSDLConstants.CONVENTIONAL_TNS_PREFIX, part.getElementQName().getNamespaceURI());
            nsMap.add(WSDLConstants.NP_SCHEMA_XSD, WSDLConstants.NS_SCHEMA_XSD);
            schemaInfo = createSchemaIfNeeded(part.getElementQName().getNamespaceURI(), nsMap);

        }
        XmlSchema schema = schemaInfo.getSchema();


        // Before updating everything, make sure we haven't added this
        // type yet.  Multiple methods that throw the same exception
        // types will cause duplicates.
        String faultTypeName = xmlTypeAnno != null && !StringUtils.isEmpty(xmlTypeAnno.name())
               ? xmlTypeAnno.name()  :  part.getElementQName().getLocalPart();
        XmlSchemaType existingType = schema.getTypeByName(faultTypeName);
        if (existingType != null) {
            return;
        }

        XmlSchemaElement el = new XmlSchemaElement(schema, true);
        el.setName(part.getElementQName().getLocalPart());
        part.setXmlSchema(el);
        schemaInfo.setElement(null);

        if (respectXmlTypeNS) {
            schema = faultBeanSchema; //create complexType in the new created schema for xmlType
        }

        XmlSchemaComplexType ct = new XmlSchemaComplexType(schema, true);
        ct.setName(faultTypeName);

        el.setSchemaTypeName(ct.getQName());

        XmlSchemaSequence seq = new XmlSchemaSequence();
        ct.setParticle(seq);
        String namespace = part.getElementQName().getNamespaceURI();
        XmlAccessType accessType = Utils.getXmlAccessType(cls);
//
        for (Field f : Utils.getFields(cls, accessType)) {
            //map field
            Type type = Utils.getFieldType(f);
            //we want to return the right type for collections so if we get null
            //from the return type we check if it's ParameterizedType and get the
            //generic return type.
            if ((type == null) && f.getGenericType() instanceof ParameterizedType) {
                type = f.getGenericType();
            }
            if (generateGenericType(type)) {
                buildGenericElements(schema, seq, f);
            } else {
                JAXBBeanInfo beanInfo = getBeanInfo(type);
                if (beanInfo != null) {
                    XmlElement xmlElementAnno = f.getAnnotation(XmlElement.class);
                    addElement(schema, seq, beanInfo, new QName(namespace, f.getName()), isArray(type), xmlElementAnno);
                }
            }
        }
        for (Method m : Utils.getGetters(cls, accessType)) {
            //map method
            Type type = Utils.getMethodReturnType(m);
            // we want to return the right type for collections so if we get null
            // from the return type we check if it's ParameterizedType and get the
            // generic return type.
            if ((type == null) && m.getGenericReturnType() instanceof ParameterizedType) {
                type = m.getGenericReturnType();
            }

            if (generateGenericType(type)) {
                buildGenericElements(schema, seq, m, type);
            } else {
                JAXBBeanInfo beanInfo = getBeanInfo(type);
                if (beanInfo != null) {
                    int idx = m.getName().startsWith("get") ? 3 : 2;
                    String name = m.getName().substring(idx);
                    name = Character.toLowerCase(name.charAt(0)) + name.substring(1);
                    XmlElement xmlElementAnno = m.getAnnotation(XmlElement.class);
                    addElement(schema, seq, beanInfo, new QName(namespace, name), isArray(type), xmlElementAnno);
                }
            }
        }
        // Create element in xsd:sequence for Exception.class
        if (Exception.class.isAssignableFrom(cls)) {
            addExceptionMessage(cls, schema, seq);
        }

        if (propertyOrder != null) {
            if (propertyOrder.length == seq.getItems().size()) {
                sortItems(seq, propertyOrder);
            } else if (propertyOrder.length > 1
                || (propertyOrder.length == 1 && !propertyOrder[0].isEmpty())) {
                LOG.log(Level.WARNING, "propOrder in @XmlType doesn't define all schema elements :"
                    + Arrays.toString(propertyOrder));
            }
        }

        if (xmlAccessorOrder != null && xmlAccessorOrder.value().equals(XmlAccessOrder.ALPHABETICAL)
            && propertyOrder == null) {
            sort(seq);
        }

        schemas.addCrossImports();
        part.setProperty(JAXBDataBinding.class.getName() + ".CUSTOM_EXCEPTION", Boolean.TRUE);
    }