Package org.ajax4jsf.builder.config

Source Code of org.ajax4jsf.builder.config.BuilderConfig

/**
* License Agreement.
*
* Rich Faces - Natural Ajax for Java Server Faces (JSF)
*
* Copyright (C) 2007 Exadel, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1 as published by the Free Software Foundation.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
*/

package org.ajax4jsf.builder.config;

import java.beans.PropertyDescriptor;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

import javax.naming.ConfigurationException;

import org.ajax4jsf.builder.generator.Logger;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.digester.Digester;
import org.apache.commons.digester.ExtendedBaseRules;
import org.apache.tools.ant.BuildException;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.ext.EntityResolver2;

/**
* Parse builder config file for use with component creation.
*
* @author asmirnov@exadel.com (latest modification by $Author: ishabalov $)
* @version $Revision: 1.1.2.10 $ $Date: 2007/02/20 20:57:58 $
*
*/
public class BuilderConfig implements LoaderHolder {

    /**
         * Resource path to config file schemas and entities
         */
    public static final String COMPONENT_SCHEMA_BASE = "/META-INF/schema/";

    /**
         * Resource path to config file schemas and entities
         */
    public static final String ENTITIES_FOLDER = "entities";

    /**
         * default URI to dtd in classpath
         */
    private static final String COMPONENT_CONFIG_DTD_URI = COMPONENT_SCHEMA_BASE
      + "component-config.dtd";

    /**
         * root element of configuration file
         */
    private static final String GENERATOR_CONFIG_ROOT_ELEMENT = "components";

    /**
         * PUBLIC Id of configuration schema
         */
    private static final String GENERATOR_CONFIG_PUBLIC_ID = "-//AJAX4JSF//CDK Generator config/EN";

    /**
         * components described in this configuration
         */
    private List<ComponentBean> components = new ArrayList<ComponentBean>();

    /**
         * validators described in this configuration
         */
    private List<ValidatorBean> validators = new ArrayList<ValidatorBean>();

    /**
         * components described in this configuration
         */
    private List<ConverterBean> converters = new ArrayList<ConverterBean>();

    /**
         * renderers described in this configuration
         */
    private List<RendererBean> renderers = new ArrayList<RendererBean>();

    private List<ListenerBean> listeners = new ArrayList<ListenerBean>();

    private List<FunctionBean> functions = new ArrayList<FunctionBean>();
   
    private ClassLoader _loader;

    private Logger _log;

    /**
         * @param project -
         *                current ant project
         */
    public BuilderConfig(ClassLoader loader, Logger log) {
  _loader = loader;
  _log = log;
    }

    /**
         * Parsing builder configuration file
         *
         * @param configFile
         * @throws ParsingException
         */
    public void parseConfig(final File configFile) throws ParsingException {
  getLog().info(" Parse config file " + configFile.toString());
  Digester digester = new Digester();
  digester.setRules(new ExtendedBaseRules());
  digester.setValidating(false);
  digester.setNamespaceAware(false);
  // try {
  // URL dtd =
        // this.getClass().getClassLoader().getResource(COMPONENT_CONFIG_DTD_URI);
  // new
        // URL("resource:/com/exadel/vcp/builder/config/component-config.dtd");
  getLog()
    .debug("Register config DTD as URI " + COMPONENT_CONFIG_DTD_URI);
  digester.register(GENERATOR_CONFIG_PUBLIC_ID, COMPONENT_CONFIG_DTD_URI);
  // } catch (MalformedURLException e) {
  // throw new ParsingException("Malformed URL for internal DTD
        // reference",e);
  // }

  // setup custom entity resolver for handle file-resource path's
  // resolve DTD even it not pointed in file, and, for entities - resolve
        // it in
  // classpath if entity registered in DTD witn path /META-INF/schema
  digester.setEntityResolver(new EntityResolver2() {

      /*
                 * (non-Javadoc)
                 *
                 * @see org.xml.sax.EntityResolver#resolveEntity(java.lang.String,
                 *      java.lang.String)
                 */
      public InputSource resolveEntity(String publicId, String systemId)
        throws SAXException, IOException {
    getLog().debug(
      "Request for entity with systemId " + systemId
        + " and publicId " + publicId);
    if (GENERATOR_CONFIG_PUBLIC_ID.equals(publicId)) {
        return getDTDSource();
    } else if (null != publicId && null != systemId
      && systemId.contains(ENTITIES_FOLDER)) {
        int base = systemId.indexOf(ENTITIES_FOLDER);
        String entity = COMPONENT_SCHEMA_BASE
          + systemId.substring(base);
        getLog().debug(
          "attempt to load entity from classpath " + entity);
        InputStream entityStream = BuilderConfig.class
          .getResourceAsStream(entity);
        if (null != entityStream) {
      return new InputSource(entityStream);
        }
    }
    return null;
      }

      public InputSource getExternalSubset(String name, String baseURI)
        throws SAXException, IOException {
    getLog().debug(
      "Request for ExternalSubset with name " + name
        + " and baseURI " + baseURI);
    if (GENERATOR_CONFIG_ROOT_ELEMENT.equals(name)) {
        return getDTDSource();
    }
    return null;
      }

      public InputSource resolveEntity(String name, String publicId,
        String baseURI, String systemId) throws SAXException,
        IOException {
    getLog().debug(
      "Request for extended entity with systemId " + systemId
        + " and publicId " + publicId);
    getLog().debug(
      "additional parameters with name " + name
        + " and baseURI " + baseURI);
    if ("[dtd]".equals(name)
      && GENERATOR_CONFIG_PUBLIC_ID.equals(publicId)) {
        return getDTDSource();
    } else if (null == name
      || (!name.startsWith("[") && !name.startsWith("&"))) {
        return resolveEntity(publicId, systemId);
    }
    return null;
      }

      /**
                 * Resolve config DTD from classpath
                 *
                 * @return source of config file DTD
                 */
      private InputSource getDTDSource() {
    return new InputSource(BuilderConfig.class
      .getResourceAsStream(COMPONENT_CONFIG_DTD_URI));
      }

  });

  // Parsing rules.

  // Components
  String path = "components/component";
  digester.addObjectCreate(path, ComponentBean.class);
  digester.addBeanPropertySetter(path + "/name");
  digester.addBeanPropertySetter(path + "/family");
  digester.addBeanPropertySetter(path + "/classname");
  digester.addBeanPropertySetter(path + "/superclass");
  digester.addBeanPropertySetter(path + "/description");
  digester.addBeanPropertySetter(path + "/displayname");
  digester.addBeanPropertySetter(path + "/icon");
  // TODO - for superclass, populate from description in config file, if
        // exist
  digester.addSetProperties(path);
  digester.addSetNext(path, "addComponent");
  path = "components/renderer";
  digester.addObjectCreate(path, RendererBean.class);
  digester.addBeanPropertySetter(path + "/?");
  digester.addSetProperties(path);
  digester.addSetNext(path, "addRenderer");
  path = "components/component/renderer";
  digester.addObjectCreate(path, RendererBean.class);
  digester.addBeanPropertySetter(path + "/?");
  digester.addSetProperties(path);
  digester.addSetNext(path, "setRenderer");

  path = "components/component/facet";
  digester.addObjectCreate(path, JsfBean.class);
  digester.addBeanPropertySetter(path + "/?");
  digester.addSetProperties(path);
  digester.addSetNext(path, "addFacet");
  path = "components/component/event";
  digester.addObjectCreate(path, EventBean.class);
  digester.addBeanPropertySetter(path + "/?");
  digester.addSetProperties(path);
  digester.addSetNext(path, "addEvent");

  // Validators

  path = "components/validator";
  digester.addObjectCreate(path, ValidatorBean.class);
  digester.addBeanPropertySetter(path + "/id");
  digester.addBeanPropertySetter(path + "/classname");
  digester.addBeanPropertySetter(path + "/superclass");
  digester.addBeanPropertySetter(path + "/description");
  digester.addBeanPropertySetter(path + "/displayname");
  digester.addBeanPropertySetter(path + "/icon");
  // TODO - for superclass, populate from description in config file, if
        // exist
  digester.addSetProperties(path);
  digester.addSetNext(path, "addValidator");

  path = "components/validator/property";
  digester.addObjectCreate(path, PropertyBean.class);
  digester.addBeanPropertySetter(path + "/?");
  digester.addSetProperties(path);
  digester.addSetNext(path, "addProperty");

  // Converters

  path = "components/converter";
  digester.addObjectCreate(path, ConverterBean.class);
  digester.addBeanPropertySetter(path + "/id");
  digester.addBeanPropertySetter(path + "/classname");
  digester.addBeanPropertySetter(path + "/superclass");
  digester.addBeanPropertySetter(path + "/description");
  digester.addBeanPropertySetter(path + "/displayname");
  digester.addBeanPropertySetter(path + "/icon");
  digester.addBeanPropertySetter(path + "/forclass");
  // TODO - for superclass, populate from description in config file, if
        // exist
  digester.addSetProperties(path);
  digester.addSetNext(path, "addConverter");

  // Functions

  path = "components/function";
  digester.addObjectCreate(path, FunctionBean.class);
  digester.addBeanPropertySetter(path + "/name");
  digester.addBeanPropertySetter(path + "/description");
  digester.addBeanPropertySetter(path + "/method");
  digester.addSetNext(path, "addFunction");
 
  // - Tags & Tag handlers

  path = "components/component/tag";
  digester.addObjectCreate(path, TagBean.class);
  digester.addBeanPropertySetter(path + "/?");
  digester.addSetProperties(path);
  digester.addSetNext(path, "setTag");

  path = "components/validator/tag";
  digester.addObjectCreate(path, TagBean.class);
  digester.addBeanPropertySetter(path + "/?");
  digester.addSetProperties(path);
  digester.addSetNext(path, "setTag");

  path = "components/converter/tag";
  digester.addObjectCreate(path, TagBean.class);
  digester.addBeanPropertySetter(path + "/?");
  digester.addSetProperties(path);
  digester.addSetNext(path, "setTag");

  path = "components/component/tag/test";
  digester.addObjectCreate(path, TagTestClassHolder.class);
  digester.addBeanPropertySetter(path + "/?");
  digester.addSetProperties(path);
  digester.addSetNext(path, "setTest");

  path = "components/component/test";
  digester.addObjectCreate(path, TestClassHolder.class);
  digester.addBeanPropertySetter(path + "/?");
  digester.addSetProperties(path);
  digester.addSetNext(path, "setTest");

  path = "components/component/taghandler";
  digester.addObjectCreate(path, TagHandlerBean.class);
  digester.addBeanPropertySetter(path + "/?");
  digester.addSetProperties(path);
  digester.addSetNext(path, "setTaghandler");
  /*
         * path = "components/component/taghandler/test";
         * digester.addObjectCreate(path, TestClassHolder.class);
         * digester.addBeanPropertySetter(path+"/?");
         * digester.addSetProperties(path); digester.addSetNext(path,
         * "setTest");
         */

  // Properties
  path = "components/component/property";
  digester.addObjectCreate(path, PropertyBean.class);
  digester.addBeanPropertySetter(path + "/?");
  digester.addSetProperties(path);
  digester.addSetNext(path, "addProperty");

  // path = "components/validator/property";
  // digester.addObjectCreate(path, PropertyBean.class);
  // digester.addBeanPropertySetter(path+"/?");
  // digester.addSetProperties(path);
  // digester.addSetNext(path, "addProperty");

  path = "components/converter/property";
  digester.addObjectCreate(path, PropertyBean.class);
  digester.addBeanPropertySetter(path + "/?");
  digester.addSetProperties(path);
  digester.addSetNext(path, "addProperty");

  path = "*/properties/property";
  digester.addObjectCreate(path, PropertyBean.class);
  digester.addBeanPropertySetter(path + "/?");
  digester.addSetProperties(path);
  digester.addSetNext(path, "addProperty");

  // Listeners

  path = "components/listener";
  digester.addObjectCreate(path, ListenerBean.class);
  digester.addBeanPropertySetter(path + "/?");
  digester.addSetProperties(path);
  digester.addSetNext(path, "addListener");
  path = "components/listener/tag";
  digester.addObjectCreate(path, TagBean.class);
  digester.addBeanPropertySetter(path + "/?");
  digester.addSetProperties(path);
  digester.addSetNext(path, "setTag");
  path = "components/listener/taghandler";
  digester.addObjectCreate(path, TagHandlerBean.class);
  digester.addBeanPropertySetter(path + "/?");
  digester.addSetProperties(path);
  digester.addSetNext(path, "setTaghandler");
  path = "components/listener/property";
  digester.addObjectCreate(path, PropertyBean.class);
  digester.addBeanPropertySetter(path + "/?");
  digester.addSetProperties(path);
  digester.addSetNext(path, "addProperty");

  // Set this config as root.
  digester.push(this);
  try {
      digester.parse(configFile.toString());
  } catch (IOException e) {
      // TODO Auto-generated catch block
      throw new ParsingException("I/O error on parsing config file ", e);
  } catch (SAXException e) {
      // TODO Auto-generated catch block
      throw new ParsingException("SAX Parsing error in config file ", e);
  }
  // checkComopnentProperties();
  // return this;
    }

    /**
         * Check all components for existing and default properties.
         *
         * @param classpath -
         *                classpath to find user components, renderers, tags
         * @throws ConfigurationException
         */
    public void checkComponentProperties() throws ParsingException {
  // ClassLoader loader = getProject().createClassLoader(classpath);
  // if(null == loader) {
  // loader = this.getClass().getClassLoader();
  // }
  // setLoader(loader);

  for (ListenerBean listener : getListeners()) {
      try {
    Class<?> listenerClass = Class.forName(listener
      .getComponentclass(), false, getLoader());

    for (ComponentBean bean : getComponents()) {
        if (bean.getSuperclass() != null) {
      Class<?> componentSClass = Class.forName(bean
        .getSuperclass(), false, getLoader());
     
      if (listenerClass.isAssignableFrom(componentSClass)) {

          PropertyBean listenerProperty = bean
            .getProperty(listener.getName());
         
          if (null == listenerProperty) {
          listenerProperty = new PropertyBean();
          listenerProperty.setName(listener.getName());
          bean.addProperty(listenerProperty);
            listenerProperty.setClassname("javax.el.MethodExpression");
          }
         
          Map<String, PropertyDescriptor> map =
            getPropertyDescriptors(componentSClass);
       
          PropertyDescriptor propertyDescriptor =
            map.get(listener.getName());
         
          if (propertyDescriptor != null) {
            String componentPropertyName = propertyDescriptor.getPropertyType().getName();
           
            if (!componentPropertyName.equals(listenerProperty.getClassname())) {
              _log.error(
                  String.format("Overriding property type %s with %s for %s.%s",
                  listenerProperty.getClassname(),
                  componentPropertyName,
                  bean.getClassname(),
                  listener.getName()
                  ));
            }
           
          listenerProperty.setClassname(componentPropertyName);
          }
         
          // TODO - check existing property for compability with this listener.
          listenerProperty.setEl(true);
          listenerProperty.setElonly(true);
          listenerProperty.setAttachedstate(true);
          listenerProperty.setMethodargs(listener
            .getEventclass());
          listener.addSuitableComponent(bean);
      }
        }
    }
      } catch (ClassNotFoundException e) {
    throw new BuildException(e);
      }
     
      listener.checkProperties();
  }

  for (Iterator iter = this.getComponents().iterator(); iter.hasNext();) {
      ComponentBaseBean component = (ComponentBaseBean) iter.next();
      component.checkProperties();
  }

  for (Iterator iter = this.getValidators().iterator(); iter.hasNext();) {
      ComponentBaseBean component = (ComponentBaseBean) iter.next();
      component.checkProperties();
  }

  for (Iterator iter = this.getConverters().iterator(); iter.hasNext();) {
      ComponentBaseBean component = (ComponentBaseBean) iter.next();
      component.checkProperties();
  }

    }

   
    private Map<String, PropertyDescriptor> getPropertyDescriptors(Class<?> clazz) {
     
      if (clazz.equals(Object.class)) {
        return Collections.emptyMap();
      }
     
      Map<String, PropertyDescriptor> m =
        new TreeMap<String, PropertyDescriptor>();

      Class<?> superclass = clazz.getSuperclass();
      if (superclass != null) {
        m.putAll(getPropertyDescriptors(superclass));
      }
     
      Class<?>[] interfaces = clazz.getInterfaces();
      if (interfaces != null) {
          for (Class<?> intrfc : interfaces) {
          m.putAll(getPropertyDescriptors(intrfc));
        }
      }
     
      PropertyDescriptor[] descriptors =
        PropertyUtils.getPropertyDescriptors(clazz);
     
      for (PropertyDescriptor propertyDescriptor : descriptors) {
      m.put(propertyDescriptor.getName(), propertyDescriptor);
    }
     
      return m;
    }
   
    /*
         * (non-Javadoc)
         *
         * @see com.exadel.vcp.builder.config.LoaderHolder#getLoader()
         */
    public ClassLoader getLoader() {
  return _loader;
    }

    /*
         * (non-Javadoc)
         *
         * @see com.exadel.vcp.builder.config.LoaderHolder#setLoader(java.lang.ClassLoader)
         */
    public void setLoader(ClassLoader loader) {
  _loader = loader;
    }

    public Logger getLog() {
  return _log;
    }

    public void addComponent(ComponentBean component) {
  this.components.add(component);
  component.setParent(this);
    }

    public void addValidator(ValidatorBean validator) {
  this.validators.add(validator);
  validator.setParent(this);
    }

    public void addConverter(ConverterBean converter) {
  this.converters.add(converter);
  converter.setParent(this);
    }

    public void addRenderer(RendererBean renderer) {
  this.renderers.add(renderer);
  renderer.setParent(this);
    }

    public void addListener(ListenerBean listener) {
  this.listeners.add(listener);
  listener.setParent(this);
    }

    public void addFunction(FunctionBean function) {
  this.functions.add(function);
  function.setParent(this);
    }

    /*
         * (non-Javadoc)
         *
         * @see java.util.List#clear()
         */
    public void clear() {
  components.clear();
  renderers.clear();
    }

    /*
         * (non-Javadoc)
         *
         * @see java.util.List#contains(java.lang.Object)
         */
    public boolean contains(Object o) {
  return components.contains(o);
    }

    /*
         * (non-Javadoc)
         *
         * @see java.util.List#get(int)
         */
    public ComponentBaseBean get(int index) {
  return components.get(index);
    }

    /*
         * (non-Javadoc)
         *
         * @see java.util.List#indexOf(java.lang.Object)
         */
    public int indexOf(ComponentBaseBean o) {
  return components.indexOf(o);
    }

    /*
         * (non-Javadoc)
         *
         * @see java.util.List#isEmpty()
         */
    public boolean isEmpty() {
  return components.isEmpty();
    }

    /*
         * (non-Javadoc)
         *
         * @see java.util.List#listIterator()
         */
    public List<ComponentBean> getComponents() {
  return components;
    }

    public List<ConverterBean> getConverters() {
  return converters;
    }

    public List<ValidatorBean> getValidators() {
  return validators;
    }

    public List<ListenerBean> getListeners() {
  return listeners;
    }

    /**
         * @return the renderers
         */
    public List<RendererBean> getRenderers() {
  return this.renderers;
    }

    public List<FunctionBean> getFunctions() {
  return functions;
    }
   
    /*
         * (non-Javadoc)
         *
         * @see java.util.List#remove(int)
         */
    public ComponentBaseBean remove(int index) {
  return components.remove(index);
    }

    /*
         * (non-Javadoc)
         *
         * @see java.util.List#remove(java.lang.Object)
         */
    public boolean remove(ComponentBaseBean o) {
  return components.remove(o);
    }

    /*
         * (non-Javadoc)
         *
         * @see java.util.List#size()
         */
    public int size() {
  return components.size();
    }
}
TOP

Related Classes of org.ajax4jsf.builder.config.BuilderConfig

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.