schemacompiler.java

来自「开源的axis2框架的源码。用于开发WEBSERVER」· Java 代码 · 共 1,423 行 · 第 1/5 页

JAVA
1,423
字号

                        //store in the schema map to retrive in the unwrapping
                        xsElt.addMetaInfo(
                                SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY,
                                className);
                    } else if (schemaType instanceof XmlSchemaSimpleType) {
                        //set a name
                        schemaType.setName(generatedTypeName.getLocalPart());
                        changedSimpleTypeSet.add(schemaType);
                        // Must do this up front to support recursive types
                        String fullyQualifiedClassName = writer.makeFullyQualifiedClassName(schemaType.getQName());
                        processedTypemap.put(schemaType.getQName(), fullyQualifiedClassName);

                        BeanWriterMetaInfoHolder metaInfHolder = (BeanWriterMetaInfoHolder) processedAnonymousComplexTypesMap.get(xsElt);
                        metaInfHolder.setOwnQname(schemaType.getQName());
                        metaInfHolder.setOwnClassName(fullyQualifiedClassName);

                        writeSimpleType((XmlSchemaSimpleType) schemaType,
                                metaInfHolder);
                        //remove the reference from the anon list since we named the type
                        processedAnonymousComplexTypesMap.remove(xsElt);
                        String className = findClassName(schemaType.getQName(), isArray(xsElt));
                        innerElementMap.put(
                                xsElt.getQName(),
                                className);

                        //store in the schema map
                        xsElt.addMetaInfo(
                                SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY,
                                className);
                    }
                }
            } else {
                // set the binary status of this element
                this.processedElementList.add(xsElt.getQName());
            }
            //referenced name
        } else if (xsElt.getRefName() != null) {

            if (xsElt.getRefName().equals(SchemaConstants.XSD_SCHEMA)) {
                innerElementMap.put(xsElt.getQName(), writer.getDefaultClassName());
                return;
            }
            //process the referenced type. It could be thought that the referenced element replaces this
            //element
            XmlSchemaElement referencedElement = getReferencedElement(parentSchema, xsElt.getRefName());
            if (referencedElement == null) {
                throw new SchemaCompilationException(
                        SchemaCompilerMessages.getMessage("schema.referencedElementNotFound", xsElt.getRefName().toString()));
            }

            //if the element is referenced, then it should be one of the outer (global) ones
            processElement(referencedElement, parentSchema);

            //no outer check required here. If the element is having a ref, then it is definitely
            //not an outer element since the top level elements are not supposed to have refs
            //Also we are sure that it should have a type reference
            QName referenceEltQName = referencedElement.getQName();
            if (referencedElement.getSchemaTypeName() != null) {
                // we have to only find the class name without arrary part
                String javaClassName = findClassName(referencedElement.getSchemaTypeName(), false);
                //if this element is referenced, there's no QName for this element
                this.processedElementRefMap.put(referenceEltQName, javaClassName);
                referencedElement.addMetaInfo(SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY,
                        javaClassName);
                // set the element class name to be used in unwrapping
                xsElt.addMetaInfo(SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY,
                                javaClassName);
            } else {
                //this referenced element has an anon type and that anon type has been already
                //processed. But in this case we need it to be a seperate class since this
                //complextype has to be added as an attribute in a class.
                //generate a name for this type
                QName generatedTypeName = generateTypeQName(referenceEltQName, parentSchema);
                XmlSchemaType referenceSchemaType = referencedElement.getSchemaType();


                if (referenceSchemaType instanceof XmlSchemaComplexType) {

                    if (referencedElement.getSchemaTypeName() == null) {
                        referencedElement.setSchemaTypeName(generatedTypeName);
                    }

                    //set a name
                    referenceSchemaType.setName(generatedTypeName.getLocalPart());

                    String javaclassName = writeComplexType((XmlSchemaComplexType) referenceSchemaType,
                            (BeanWriterMetaInfoHolder) processedAnonymousComplexTypesMap.get(referencedElement)
                    );
                    //remove the reference from the anon list since we named the type
                    // DEEPAL :- We can not remove the entry from the hashtable ,
                    // this will fail if there are two reference for the same type

                    //processedAnonymousComplexTypesMap.remove(referencedElement);

                    processedTypemap.put(generatedTypeName, javaclassName);
                    this.processedElementRefMap.put(referenceEltQName, javaclassName);
                    // set the class name to be used in unwrapping
                    xsElt.addMetaInfo(SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY,
                                javaclassName);

                }
            }
            // schema type name is present but not the schema type object
        } else if (xsElt.getSchemaTypeName() != null) {
            //There can be instances where the SchemaType is null but the schemaTypeName is not!
            //this specifically happens with xsd:anyType.
            QName schemaTypeName = xsElt.getSchemaTypeName();

            XmlSchema currentParentSchema = resolveParentSchema(schemaTypeName, parentSchema);
            XmlSchemaType typeByName = getType(currentParentSchema, schemaTypeName);

            if (typeByName != null) {
                //this type is found in the schema so we can process it
                processSchema(xsElt, typeByName, currentParentSchema);
                if (!isOuter) {
                    String className = findClassName(schemaTypeName, isArray(xsElt));
                    //since this is a inner element we should add it to the inner element map
                    innerElementMap.put(xsElt.getQName(), className);
                    // set the class name to be used in unwrapping
                    xsElt.addMetaInfo(SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY,
                                className);
                } else {
                    this.processedElementList.add(xsElt.getQName());
                }
            } else {
                //this type is not found at all. we'll just register it with whatever the class name we can comeup with
                if (!isOuter) {
                    String className = findClassName(schemaTypeName, isArray(xsElt));
                    innerElementMap.put(xsElt.getQName(), className);
                    // set the class name to be used in unwrapping
                    xsElt.addMetaInfo(SchemaConstants.SchemaCompilerInfoHolder.CLASSNAME_KEY,
                                className);
                } else {
                    this.processedElementList.add(xsElt.getQName());
                }
            }
        }

        //add this elements QName to the nillable group if it has the  nillable attribute
        if (xsElt.isNillable()) {
            if (isOuter) {
                this.nillableElementList.add(xsElt.getQName());
            } else {
                localNillableList.add(xsElt.getQName());
            }
        }

    }

    /**
     * resolve the parent schema for the given schema type name
     *
     * @param schemaTypeName
     * @param currentSchema
     */
    private XmlSchema resolveParentSchema(QName schemaTypeName, XmlSchema currentSchema)
            throws SchemaCompilationException {
        String targetNamespace = schemaTypeName.getNamespaceURI();

        // if the current schema has the same namespace we use it
        if ((currentSchema.getTargetNamespace() != null) &&
                currentSchema.getTargetNamespace().equals(targetNamespace)){
            return currentSchema;
        }
        Object loadedSchema = loadedSchemaMap.get(targetNamespace);
        if (loadedSchema != null) {
            return (XmlSchema) loadedSchema;
        } else if (availableSchemaMap.containsKey(targetNamespace)) {
            //compile the referenced Schema first and then pass it
            XmlSchema schema = (XmlSchema) availableSchemaMap.get(targetNamespace);
            compile(schema);
            return schema;
        } else {
            return currentSchema;
        }
    }

    /**
     * Generate a unique type Qname using an element name
     *
     * @param referenceEltQName
     * @param parentSchema
     */
    private QName generateTypeQName(QName referenceEltQName, XmlSchema parentSchema) {
        QName generatedTypeName = new QName(referenceEltQName.getNamespaceURI(),
                referenceEltQName.getLocalPart() + getNextTypeSuffix(referenceEltQName.getLocalPart()));
        while (parentSchema.getTypeByName(generatedTypeName) != null) {
            generatedTypeName = new QName(referenceEltQName.getNamespaceURI(),
                    referenceEltQName.getLocalPart() + getNextTypeSuffix(referenceEltQName.getLocalPart()));
        }
        return generatedTypeName;
    }

    /**
     * Finds whether a given class is already made
     *
     * @param qName
     */
    private boolean isAlreadyProcessed(QName qName) {
        return processedTypemap.containsKey(qName) ||
                simpleTypesMap.containsKey(qName) ||
                baseSchemaTypeMap.containsKey(qName);
    }


    /**
     * A method to pick the ref class name
     *
     * @param name
     * @param isArray
     */
    private String findRefClassName(QName name, boolean isArray) {
        String className = null;
        if (processedElementRefMap.get(name) != null) {
            className = (String) processedElementRefMap.get(name);

            if (isArray) {
                //append the square braces that say this is an array
                //hope this works for all cases!!!!!!!
                //todo this however is a thing that needs to be
                //todo fixed to get complete language support
                className = className + "[]";
            }
        }
        return className;

    }

    /**
     * Finds a class name from the given Qname
     *
     * @param qName
     * @param isArray
     * @return FQCN
     */
    private String findClassName(QName qName, boolean isArray) throws SchemaCompilationException {

        //find the class name
        String className;
        if (processedTypemap.containsKey(qName)) {
            className = (String) processedTypemap.get(qName);
        } else if (simpleTypesMap.containsKey(qName)) {
            className = (String) simpleTypesMap.get(qName);
        } else if (baseSchemaTypeMap.containsKey(qName)) {
            className = (String) baseSchemaTypeMap.get(qName);
        } else {
            if (isSOAP_ENC(qName.getNamespaceURI())) {
                throw new SchemaCompilationException(SchemaCompilerMessages.getMessage("schema.soapencoding.error", qName.toString()));

            }
            // We seem to have failed in finding a class name for the
            //contained schema type. We better set the default then
            //however it's better if the default can be set through the
            //property file
            className = writer.getDefaultClassName();
            log.warn(SchemaCompilerMessages
                    .getMessage("schema.typeMissing", qName.toString()));
        }

        if (isArray) {
            //append the square braces that say this is an array
            //hope this works for all cases!!!!!!!
            //todo this however is a thing that needs to be
            //todo fixed to get complete language support
            className = className + "[]";
        }
        return className;
    }

    /**
     * Returns true if SOAP_ENC Namespace.
     *
     * @param s a string representing the URI to check
     * @return true if <code>s</code> matches a SOAP ENCODING namespace URI,
     *         false otherwise
     */
    public static boolean isSOAP_ENC(String s) {
        if (s.equals(Constants.URI_SOAP11_ENC))
            return true;
        return s.equals(Constants.URI_SOAP12_ENC);
    }

    /**
     * Process a schema element which has been refered to by an element

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?