com.alkacon.opencms.feeder.CmsFeedXmlContentHandler.java Source code

Java tutorial

Introduction

Here is the source code for com.alkacon.opencms.feeder.CmsFeedXmlContentHandler.java

Source

/*
 * File   : $Source: /alkacon/cvs/alkacon/com.alkacon.opencms.feeder/src/com/alkacon/opencms/feeder/CmsFeedXmlContentHandler.java,v $
 * Date   : $Date: 2007/12/13 15:48:47 $
 * Version: $Revision: 1.1 $
 *
 * This file is part of the Alkacon OpenCms Add-On Module Package
 *
 * Copyright (c) 2007 Alkacon Software GmbH (http://www.alkacon.com)
 *
 * The Alkacon OpenCms Add-On Module Package is free software: 
 * you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * The Alkacon OpenCms Add-On Module Package is distributed 
 * in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with the Alkacon OpenCms Add-On Module Package.  
 * If not, see http://www.gnu.org/licenses/.
 *
 * For further information about Alkacon Software GmbH, please see the
 * company website: http://www.alkacon.com.
 *
 * For further information about OpenCms, please see the
 * project website: http://www.opencms.org.
 */

package com.alkacon.opencms.feeder;

import org.opencms.configuration.CmsConfigurationManager;
import org.opencms.i18n.CmsEncoder;
import org.opencms.main.CmsRuntimeException;
import org.opencms.util.CmsFileUtil;
import org.opencms.xml.CmsXmlContentDefinition;
import org.opencms.xml.CmsXmlEntityResolver;
import org.opencms.xml.CmsXmlException;
import org.opencms.xml.CmsXmlUtils;
import org.opencms.xml.content.CmsDefaultXmlContentHandler;
import org.opencms.xml.content.Messages;
import org.opencms.xml.types.I_CmsXmlSchemaType;

import java.util.Collections;
import java.util.Iterator;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

/**
 * Adds syndication feed mapping rules to the default XML content handler.<p>
 * 
 * @author Alexander Kandzior 
 * 
 * @version $Revision: 1.1 $ 
 */
public class CmsFeedXmlContentHandler extends CmsDefaultXmlContentHandler {

    /** Constant for the "feedrule" element name. */
    public static final String APPINFO_FEEDRULE = "feedrule";

    /** Constant for the "feedrules" element name. */
    public static final String APPINFO_FEEDRULES = "feedrules";

    /** Constant for the "default" attribute. */
    public static final String ATTR_DEFAULT = "default";

    /** Constant for the "maxLength" attribute. */
    public static final String ATTR_MAXLENGTH = "maxLength";

    /** The path to the Alkacon OpenCms Feeder package (calculated from the package name). */
    public static final String FEED_PACKAGE_PATH = CmsFeed.class.getPackage().getName().replace('.', '/');

    /** The file where the extended feed schema is located. */
    public static final String FEED_APPINFO_SCHEMA_FILE = FEED_PACKAGE_PATH + "/FeedAppinfo.xsd";

    /** The XML system id for the extended feed schema. */
    public static final String FEED_APPINFO_SCHEMA_SYSTEM_ID = CmsConfigurationManager.DEFAULT_DTD_PREFIX
            + FEED_APPINFO_SCHEMA_FILE;

    /** The feed mapping this class is all about. */
    protected CmsFeedContentMapping m_feedMapping;

    /**
     * Static initializer for caching the extended feed validation schema.<p>
     */
    static {

        // the schema definition is located in a separate file for easier editing
        byte[] appinfoSchema;
        try {
            appinfoSchema = CmsFileUtil.readFile(FEED_APPINFO_SCHEMA_FILE);
        } catch (Exception e) {
            throw new CmsRuntimeException(Messages.get().container(
                    org.opencms.xml.types.Messages.ERR_XMLCONTENT_LOAD_SCHEMA_1, FEED_APPINFO_SCHEMA_FILE), e);
        }
        CmsXmlEntityResolver.cacheSystemId(FEED_APPINFO_SCHEMA_SYSTEM_ID, appinfoSchema);
    }

    /**
     * Returns the initialized feed mapping for this XML content handler.<p>
     * 
     * @return the initialized feed mapping for this XML content handler
     */
    public CmsFeedContentMapping getFeedMapping() {

        return m_feedMapping;
    }

    /**
     * @see org.opencms.xml.content.CmsDefaultXmlContentHandler#initialize(org.dom4j.Element, org.opencms.xml.CmsXmlContentDefinition)
     */
    public synchronized void initialize(Element appInfoElement, CmsXmlContentDefinition contentDefinition)
            throws CmsXmlException {

        if (appInfoElement != null) {
            // first initialize all the default values
            super.initialize(appInfoElement, contentDefinition);

            Element feedElement = appInfoElement.element(APPINFO_FEEDRULES);
            if (feedElement != null) {
                initFeedRules(feedElement, contentDefinition);
            }
        }
    }

    /**
     * Adds a feed rule mapping.<p>
     * 
     * @param contentDefinition the XML content definition this XML content handler belongs to
     * @param xmlField the element name to map to the feed
     * @param feedField the feed field to map the XML field to
     * @param maxLength the optional max length of the field
     * @param defaultValue the optional default value for the mapping
     * 
     * @throws CmsXmlException in case an unknown element name is used
     */
    protected void addFeedRule(CmsXmlContentDefinition contentDefinition, String xmlField, String feedField,
            String maxLength, String defaultValue) throws CmsXmlException {

        if (contentDefinition.getSchemaType(xmlField) == null) {
            throw new CmsXmlException(
                    Messages.get().container(Messages.ERR_XMLCONTENT_INVALID_ELEM_MAPPING_1, xmlField));
        }

        m_feedMapping.addFeedFieldMapping(Collections.singletonList(CmsXmlUtils.createXpath(xmlField, 1)),
                feedField, maxLength, defaultValue);
    }

    /**
     * @see org.opencms.xml.content.CmsDefaultXmlContentHandler#init()
     */
    protected void init() {

        super.init();
        m_feedMapping = new CmsFeedContentMapping();
    }

    /**
     * Initializes the feed rule mappings for this content handler.<p>
     * 
     * @param root the "feedrules" element from the appinfo node of the XML content definition
     * @param contentDefinition the content definition the mappings belong to
     * 
     * @throws CmsXmlException if something goes wrong
     */
    protected void initFeedRules(Element root, CmsXmlContentDefinition contentDefinition) throws CmsXmlException {

        Iterator i = root.elementIterator(APPINFO_FEEDRULE);
        while (i.hasNext()) {
            // iterate all "mapping" elements in the "mappings" node
            Element element = (Element) i.next();
            // this is a mapping node
            String xmlField = element.attributeValue(APPINFO_ATTR_ELEMENT);
            String maptoName = element.attributeValue(APPINFO_ATTR_MAPTO);
            String maxLength = element.attributeValue(ATTR_MAXLENGTH);
            String defaultValue = element.attributeValue(ATTR_DEFAULT);
            if ((xmlField != null) && (maptoName != null)) {
                // add the element mapping 
                addFeedRule(contentDefinition, xmlField, maptoName, maxLength, defaultValue);
            }
        }
    }

    /**
     * @see org.opencms.xml.content.CmsDefaultXmlContentHandler#validateAppinfoElement(org.dom4j.Element)
     */
    protected void validateAppinfoElement(Element appinfoElement) throws CmsXmlException {

        // create a document to validate
        Document doc = DocumentHelper.createDocument();
        Element root = doc.addElement(APPINFO_APPINFO);
        // attach the default appinfo schema
        root.add(I_CmsXmlSchemaType.XSI_NAMESPACE);
        root.addAttribute(I_CmsXmlSchemaType.XSI_NAMESPACE_ATTRIBUTE_NO_SCHEMA_LOCATION,
                FEED_APPINFO_SCHEMA_SYSTEM_ID);
        // append the content from the appinfo node in the content definition 
        root.appendContent(appinfoElement);
        // now validate the document with the default appinfo schema
        CmsXmlUtils.validateXmlStructure(doc, CmsEncoder.ENCODING_UTF_8, new CmsXmlEntityResolver(null));
    }
}