⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cmsxmlcontentdefinition.java

📁 cms是开源的框架
💻 JAVA
📖 第 1 页 / 共 4 页
字号:
            CmsXmlNestedContentDefinition cd = new CmsXmlNestedContentDefinition(null, typeName, minOccurs, maxOccurs);
            sequence.add(cd);
        }

        // return a data structure with the collected values
        return definition.new CmsXmlComplexTypeSequence(name, sequence, hasLanguageAttribute);
    }

    /**
     * Looks up the given XML content definition system id in the internal content definition cache.<p> 
     * 
     * @param schemaLocation the system id of the XML content definition to look up
     * @param resolver the XML entitiy resolver to use (contains the cache)
     * 
     * @return the XML content definition found, or null if no definition is cached for the given system id
     */
    private static CmsXmlContentDefinition getCachedContentDefinition(String schemaLocation, EntityResolver resolver) {

        if (resolver instanceof CmsXmlEntityResolver) {
            // check for a cached version of this content definition
            CmsXmlEntityResolver cmsResolver = (CmsXmlEntityResolver)resolver;
            return cmsResolver.getCachedContentDefinition(schemaLocation);
        }
        return null;
    }

    /**
     * Internal method to unmarshal (read) a XML content definition instance from a XML document.<p>
     * 
     * It is assumed that the XML content definition cache has already been tested and the document 
     * has not been found in the cache. After the XML content definition has been successfully created, 
     * it is placed in the cache.<p>
     * 
     * @param document the XML document to generate a XML content definition from
     * @param schemaLocation the location from which the XML schema was read (system id)
     * @param resolver the XML entitiy resolver used by the given XML document
     * 
     * @return a XML content definition instance unmarshalled from the XML document
     * 
     * @throws CmsXmlException if something goes wrong
     */
    private static CmsXmlContentDefinition unmarshalInternal(
        Document document,
        String schemaLocation,
        EntityResolver resolver) throws CmsXmlException {

        // analyze the document and generate the XML content type definition        
        Element root = document.getRootElement();
        if (!XSD_NODE_SCHEMA.equals(root.getQName())) {
            // schema node is required
            throw new CmsXmlException(Messages.get().container(Messages.ERR_CD_NO_SCHEMA_NODE_0));
        }

        List includes = root.elements(XSD_NODE_INCLUDE);
        if (includes.size() < 1) {
            // one include is required
            throw new CmsXmlException(Messages.get().container(Messages.ERR_CD_ONE_INCLUDE_REQUIRED_0));
        }

        Element include = (Element)includes.get(0);
        String target = validateAttribute(include, XSD_ATTRIBUTE_SCHEMA_LOCATION, null);
        if (!XSD_INCLUDE_OPENCMS.equals(target)) {
            // the first include must point to the default OpenCms standard schema include
            throw new CmsXmlException(Messages.get().container(
                Messages.ERR_CD_FIRST_INCLUDE_2,
                XSD_INCLUDE_OPENCMS,
                target));
        }

        Set nestedDefinitions = new HashSet();
        if (includes.size() > 1) {
            // resolve additional, nested include calls
            for (int i = 1; i < includes.size(); i++) {

                Element inc = (Element)includes.get(i);
                String schemaLoc = validateAttribute(inc, XSD_ATTRIBUTE_SCHEMA_LOCATION, null);
                InputSource source = null;
                try {
                    source = resolver.resolveEntity(null, schemaLoc);
                } catch (Exception e) {
                    throw new CmsXmlException(Messages.get().container(Messages.ERR_CD_BAD_INCLUDE_1, schemaLoc));
                }
                CmsXmlContentDefinition xmlContentDefinition = unmarshal(source, schemaLoc, resolver);
                nestedDefinitions.add(xmlContentDefinition);
            }
        }

        List elements = root.elements(XSD_NODE_ELEMENT);
        if (elements.size() != 1) {
            // only one root element is allowed
            throw new CmsXmlException(Messages.get().container(
                Messages.ERR_CD_ROOT_ELEMENT_COUNT_1,
                XSD_INCLUDE_OPENCMS,
                new Integer(elements.size())));
        }

        // collect the data from the root element node
        Element main = (Element)elements.get(0);
        String name = validateAttribute(main, XSD_ATTRIBUTE_NAME, null);

        // now process the complex types
        List complexTypes = root.elements(XSD_NODE_COMPLEXTYPE);
        if (complexTypes.size() != 2) {
            // exactly two complex types are required
            throw new CmsXmlException(Messages.get().container(
                Messages.ERR_CD_COMPLEX_TYPE_COUNT_1,
                new Integer(complexTypes.size())));
        }

        // generate the result XML content definition
        CmsXmlContentDefinition result = new CmsXmlContentDefinition(name, null, schemaLocation);

        // set the nested definitions
        result.m_includes = nestedDefinitions;

        List complexTypeData = new ArrayList();
        Iterator ct = complexTypes.iterator();
        while (ct.hasNext()) {
            Element e = (Element)ct.next();
            CmsXmlComplexTypeSequence sequence = validateComplexTypeSequence(e, nestedDefinitions, result);
            complexTypeData.add(sequence);
        }

        // get the outer element sequence, this must be the first element 
        CmsXmlComplexTypeSequence outerSequence = (CmsXmlComplexTypeSequence)complexTypeData.get(0);
        CmsXmlNestedContentDefinition outer = (CmsXmlNestedContentDefinition)outerSequence.m_sequence.get(0);

        // make sure the inner and outer element names are as required
        String outerTypeName = createTypeName(name);
        String innerTypeName = createTypeName(outer.getName());
        validateAttribute((Element)complexTypes.get(0), XSD_ATTRIBUTE_NAME, outerTypeName);
        validateAttribute((Element)complexTypes.get(1), XSD_ATTRIBUTE_NAME, innerTypeName);
        validateAttribute(main, XSD_ATTRIBUTE_TYPE, outerTypeName);

        // the inner name is the element name set in the outer sequence
        result.setInnerName(outer.getName());

        // get the inner element sequence, this must be the second element 
        CmsXmlComplexTypeSequence innerSequence = (CmsXmlComplexTypeSequence)complexTypeData.get(1);

        // add the types from the main sequence node
        Iterator it = innerSequence.m_sequence.iterator();
        while (it.hasNext()) {
            result.addType((I_CmsXmlSchemaType)it.next());
        }

        // resolve the XML content handler information
        List annotations = root.elements(XSD_NODE_ANNOTATION);
        I_CmsXmlContentHandler contentHandler = null;
        Element appInfoElement = null;

        if (annotations.size() > 0) {
            List appinfos = ((Element)annotations.get(0)).elements(XSD_NODE_APPINFO);

            if (appinfos.size() > 0) {
                // the first appinfo node contains the specific XML content data 
                appInfoElement = (Element)appinfos.get(0);

                // check for a special content handler in the appinfo node
                Element handlerElement = appInfoElement.element("handler");
                if (handlerElement != null) {
                    String className = handlerElement.attributeValue("class");
                    if (className != null) {
                        contentHandler = OpenCms.getXmlContentTypeManager().getContentHandler(className, schemaLocation);
                    }
                }
            }
        }

        if (contentHandler == null) {
            // if no content handler is defined, the default handler is used
            contentHandler = OpenCms.getXmlContentTypeManager().getContentHandler(
                CmsDefaultXmlContentHandler.class.getName(),
                name);
        }

        // analyze the app info node with the selected XML content handler
        contentHandler.initialize(appInfoElement, result);
        result.m_contentHandler = contentHandler;

        result.freeze();

        if (resolver instanceof CmsXmlEntityResolver) {
            // put the generated content definition in the cache
            ((CmsXmlEntityResolver)resolver).cacheContentDefinition(schemaLocation, result);
        }

        return result;
    }

    /**
     * Adds the missing default XML according to this content definition to the given document element.<p>  
     * 
     * In case the root element already contains subnodes, only missing subnodes are added.<p>
     * 
     * @param cms the current users OpenCms context
     * @param document the document where the XML is added in (required for default XML generation)
     * @param root the root node to add the missing XML for
     * @param locale the locale to add the XML for
     * 
     * @return the given root element with the missing content added
     */
    public Element addDefaultXml(CmsObject cms, I_CmsXmlDocument document, Element root, Locale locale) {

        Iterator i = m_typeSequence.iterator();
        int currentPos = 0;
        List allElements = root.elements();

        while (i.hasNext()) {
            I_CmsXmlSchemaType type = (I_CmsXmlSchemaType)i.next();

            // check how many elements of this type already exist in the XML
            String elementName = type.getName();
            List elements = root.elements(elementName);

            currentPos += elements.size();
            for (int j = elements.size(); j < type.getMinOccurs(); j++) {
                // append the missing elements
                Element typeElement = type.generateXml(cms, document, root, locale);
                // need to check for default value again because the of appinfo "mappings" node
                I_CmsXmlContentValue value = type.createValue(document, typeElement, locale);
                String defaultValue = document.getContentDefinition().getContentHandler().getDefault(cms, value, locale);
                if (defaultValue != null) {
                    // only if there is a default value available use it to overwrite the initial default
                    value.setStringValue(cms, defaultValue);
                }

                // re-sort elements as they have been appended to the end of the XML root, not at the correct position
                typeElement.detach();
                allElements.add(currentPos, typeElement);
                currentPos++;
            }
        }

        return root;
    }

    /**
     * Adds a nested (included) XML content definition.<p>
     * 
     * @param nestedSchema the nested (included) XML content definition to add
     */
    public void addInclude(CmsXmlContentDefinition nestedSchema) {

        m_includes.add(nestedSchema);
    }

    /**
     * Adds the given content type.<p>
     * 
     * @param type the content type to add
     * 
     * @throws CmsXmlException in case an unregisterd type is added
     */
    public void addType(I_CmsXmlSchemaType type) throws CmsXmlException {

        // check if the type to add actually exists in the type manager
        CmsXmlContentTypeManager typeManager = OpenCms.getXmlContentTypeManager();
        if (type.isSimpleType() && (typeManager.getContentType(type.getTypeName()) == null)) {
            throw new CmsXmlException(Messages.get().container(Messages.ERR_UNREGISTERED_TYPE_1, type.getTypeName()));
        }

        // add the type to the internal type sequence and lookup table
        m_typeSequence.add(type);
        m_types.put(type.getName(), type);

        // store reference to the content definition in the type
        type.setContentDefinition(this);
    }

    /**
     * Creates a clone of this XML content definition.<p> 
     * 
     * @return a clone of this XML content definition
     */
    public Object clone() {

        CmsXmlContentDefinition result = new CmsXmlContentDefinition();
        result.m_innerName = m_innerName;
        result.m_schemaLocation = m_schemaLocation;
        result.m_typeSequence = m_typeSequence;
        result.m_types = m_types;
        result.m_contentHandler = m_contentHandler;
        result.m_typeName = m_typeName;
        result.m_includes = m_includes;
        return result;
    }

    /**
     * Generates the default XML content for this content definition, and append it to the given root element.<p>
     * 
     * Please note: The default values for the annotations are read from the content definition of the given
     * document. For a nested content definitions, this means that all defaults are set in the annotations of the 
     * "outer" or "main" content defintition.<p>
     * 
     * @param cms the current users OpenCms context
     * @param document the OpenCms XML document the XML is created for

⌨️ 快捷键说明

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