org.apache.torque.generator.configuration.source.SourceTransformerSaxHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.torque.generator.configuration.source.SourceTransformerSaxHandler.java

Source

package org.apache.torque.generator.configuration.source;

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

import static org.apache.torque.generator.configuration.source.SourceConfigurationTags.ELEMENTS_ATTRIBUTE;
import static org.apache.torque.generator.configuration.source.SourceConfigurationTags.TRANSFORMER_CLASS_ATTRIBUTE;
import static org.apache.torque.generator.configuration.source.SourceConfigurationTags.TRANSFORMER_TAG;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.torque.generator.configuration.ConfigurationProvider;
import org.apache.torque.generator.configuration.paths.ProjectPaths;
import org.apache.torque.generator.source.transform.SourceTransformer;
import org.xml.sax.Attributes;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;

/**
 * Reads a source transformer from the controller configuration file.
 */
public class SourceTransformerSaxHandler extends DefaultHandler {
    /** The logger for this class. */
    private static Log log = LogFactory.getLog(DefaultHandler.class);

    /** The SourceTransformer which is currently configured. */
    private SourceTransformer sourceTransformer;

    /** On which Elements the sourceTransformer should be applied. */
    private String elements;

    /** The current nesting level inside the processed element. */
    private int level = 0;

    /**
     * The name of the currently read bean property of the transformer,
     * or null if no property is currently read.
     */
    private String propertyName;

    /**
     * The value of the currently read bean property of the transformer,
     * or null if no property is currently read or the property is a
     * list property.
     */
    private StringBuilder simplePropertyValue;

    /**
     * The value of the currently read bean property of the transformer,
     * or null if no property is currently read or the property is a
     * simple property.
     */
    private ArrayList<String> listPropertyValue;

    /**
     * The value of the currently read list entry of the currently read
     * property of the transformer,
     * or null if no list entry is currently read or the property is a
     * simple property.
     */
    private StringBuilder listPropertyEntry;

    /**
     * Constructor.
     *
     * @param configurationProvider The access object for the configuration
     *        files, not null.
     * @param projectPaths The paths of the surrounding project, not null.
     *
     * @throws NullPointerException if an argument is null.
     */
    public SourceTransformerSaxHandler(ConfigurationProvider configurationProvider, ProjectPaths projectPaths) {
        if (configurationProvider == null) {
            throw new NullPointerException("configurationProvider must not be null");
        }
        if (projectPaths == null) {
            throw new NullPointerException("projectPaths must not be null");
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void startElement(String uri, String localName, String rawName, Attributes attributes)
            throws SAXException {
        if (level == 0) {
            level++;
            if (rawName.equals(TRANSFORMER_TAG)) {
                String className = attributes.getValue(TRANSFORMER_CLASS_ATTRIBUTE);
                if (className == null) {
                    throw new SAXException("The attribute " + TRANSFORMER_CLASS_ATTRIBUTE
                            + " must not be null for the element " + TRANSFORMER_TAG);
                }
                elements = attributes.getValue(ELEMENTS_ATTRIBUTE);
                sourceTransformer = createJavaSourceTransformer(className);
            } else {
                throw new SAXException("Unknown element " + rawName);
            }
        } else if (level == 1) {
            level++;
            propertyName = rawName;
            simplePropertyValue = new StringBuilder();
        } else if (level == 2) {
            level++;
            if (simplePropertyValue.length() > 0 && !StringUtils.isWhitespace(simplePropertyValue.toString())) {
                throw new SAXException(
                        "Cannot parse both text content and child elements " + " in element " + propertyName);
            }
            simplePropertyValue = null;
            if (listPropertyValue == null) {
                listPropertyValue = new ArrayList<String>();
            }
            listPropertyEntry = new StringBuilder();
        } else {
            throw new SAXException("unknown Element " + rawName);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void endElement(String uri, String localName, String rawName) throws SAXException {
        level--;
        if (level == 2) {
            listPropertyValue.add(listPropertyEntry.toString());
            listPropertyEntry = null;
        } else if (level == 1) {
            if (!PropertyUtils.isWriteable(sourceTransformer, propertyName)) {
                throw new SAXException("No setter found for property " + propertyName + " in class "
                        + sourceTransformer.getClass().getName());
            }
            Object propertyValue;
            if (simplePropertyValue != null) {
                propertyValue = simplePropertyValue.toString();
            } else {
                propertyValue = listPropertyValue;
            }
            try {
                BeanUtils.copyProperty(sourceTransformer, propertyName, propertyValue);
            } catch (InvocationTargetException e) {
                throw new SAXException("error while setting Property " + propertyName + " for java transformer "
                        + sourceTransformer.getClass().getName() + " with value " + propertyValue.toString(), e);
            } catch (IllegalAccessException e) {
                throw new SAXException("error while setting Property " + propertyName + " for java transformer "
                        + sourceTransformer.getClass().getName() + " with value " + propertyValue.toString(), e);
            }
            propertyName = null;
            propertyValue = null;
        } else if (level != 0) {
            throw new SAXException("endElemend reached Level " + level);
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void characters(char[] ch, int start, int length) throws SAXException {
        if (simplePropertyValue != null) {
            for (int i = start; i < start + length; ++i) {
                simplePropertyValue.append(ch[i]);
            }
            return;
        }
        if (listPropertyEntry != null) {
            for (int i = start; i < start + length; ++i) {
                listPropertyEntry.append(ch[i]);
            }
            return;
        }
    }

    /**
     * Returns the configuration filled with the contents of the parsed snippet.
     *
     * @return the configuration which was filled, not null if a
     *         matching snippet was processed.
     */
    public SourceTransformer getSourceTransformer() {
        return sourceTransformer;
    }

    /**
     * Returns the path to source elements to which the transformer is applied.
     *
     * @return the path to the source element, or null to apply the transformer
     *         to the root element.
     */
    public String getElements() {
        return elements;
    }

    /**
     * Returns the configuration filled with the contents of the parsed snippet.
     *
     * @return the configuration which was filled, not null if a
     *         matching snippet was processed.
     */
    public boolean isFinished() {
        return (sourceTransformer != null && level == 0);
    }

    /**
     * Creates an instance of a transformer.
     *
     * @param className the name of the transformer to be created.
     *
     * @return the instance of the transformer, not null.
     *
     * @throws ExceptionInInitializerError if an error occurs in the
     *        initializer of the transformer.
     * @throws LinkageError if the linkage fails.
     * @throws SAXException if any other  error occurs during instantiation
     *         of the class.
     */
    private static SourceTransformer createJavaSourceTransformer(String className) throws SAXException {
        Class<?> transformerClass;
        try {
            transformerClass = Class.forName(className);
        } catch (ClassNotFoundException e) {
            throw new SAXException(
                    "Error  while initializing a source transformer :" + " Could not load class " + className, e);
        } catch (ExceptionInInitializerError e) {
            log.error("Error  while initializing a source transformer :" + " Could not initialize class "
                    + className + " : " + e.getMessage());
            throw e;
        } catch (LinkageError e) {
            log.error("Error  while initializing a source transformer :" + " Could not link class " + className
                    + " : " + e.getMessage());
            throw e;
        }

        SourceTransformer result;
        try {
            Constructor<?> constructor = transformerClass.getConstructor();
            result = (SourceTransformer) constructor.newInstance();
        } catch (NoSuchMethodException e) {
            throw new SAXException("Error  while instantiating a source transformer :" + " The class " + className
                    + " has no default constructor", e);
        } catch (ClassCastException e) {
            throw new SAXException("Error  while instantiating a source transformer :" + " The class " + className
                    + " is not an instance of " + SourceTransformer.class.getName(), e);
        } catch (IllegalAccessException e) {
            throw new SAXException("Error  while instantiating a source transformer :"
                    + " The constructor of class " + className + " could not be accessed", e);
        } catch (InvocationTargetException e) {
            throw new SAXException("Error  while instantiating a source transformer :"
                    + " The constructor of class " + className + " could not be called", e);
        } catch (InstantiationException e) {
            throw new SAXException("Error  while instantiating a source transformer :" + " The class " + className
                    + " represents an abstract class, " + "an interface, an array class, a primitive type, "
                    + "or void, or the class has no parameterless constructor, "
                    + "or the instantiation fails for some other reason.", e);
        } catch (SecurityException e) {
            throw new SAXException("Error  while instantiating a source transformer :"
                    + " The security manager denies instantiation of the class " + className, e);
        }

        return result;
    }
}