Package com.dbxml.labrador.broker

Source Code of com.dbxml.labrador.broker.Configurator

package com.dbxml.labrador.broker;

/*
* The dbXML Labrador Software License, Version 1.0
*
*
* Copyright (c) 2003 The dbXML Group, L.L.C.  All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
*    notice, this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
*    notice, this list of conditions and the following disclaimer in
*    the documentation and/or other materials provided with the
*    distribution.
*
* 3. The end-user documentation included with the redistribution,
*    if any, must include the following acknowledgment:
*       "This product includes software developed by The
*        dbXML Group, L.L.C. (http://www.dbxml.com/)."
*    Alternately, this acknowledgment may appear in the software
*    itself, if and wherever such third-party acknowledgments normally
*    appear.
*
* 4. The names "Labrador" and "dbXML Group" must not be used to
*    endorse or promote products derived from this software without
*    prior written permission. For written permission, please contact
*    info@dbxml.com
*
* 5. Products derived from this software may not be called "Labrador",
*    nor may "Labrador" appear in their name, without prior written
*    permission of The dbXML Group, L.L.C..
*
* THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED.  IN NO EVENT SHALL THE DBXML GROUP, L.L.C. OR ITS
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
* ====================================================================
*
* $Id: Configurator.java,v 1.10 2003/10/06 17:36:32 bradford Exp $
*/

import com.dbxml.labrador.Describer;
import com.dbxml.labrador.Filter;
import com.dbxml.labrador.Handler;
import com.dbxml.labrador.Resolver;
import com.dbxml.labrador.configuration.Configurable;
import com.dbxml.labrador.configuration.Configuration;
import com.dbxml.labrador.configuration.ConfigurationCallback;
import com.dbxml.labrador.configuration.ConfigurationException;
import com.dbxml.labrador.util.DOMHelper;
import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URL;
import java.util.StringTokenizer;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.xml.sax.SAXException;

/**
* Configurator is a utility class that offloads the Broker
* configuration responsibility.
*/

final class Configurator {
   private static final int BUFFER_SIZE = 8192;
  
   private static final String ELEM_LABRADOR = "labrador";

   private static final int TYPE_RESOLVER = 0;
   private static final int TYPE_DESCRIBER = 1;
   private static final int TYPE_HANDLER = 2;
   private static final int TYPE_FILTER = 3;
   private static final int TYPE_INSTANCE = 4;

   private static final String[] ELEM_NAMES = {"resolver",
                                               "describer",
                                               "handler",
                                               "filter",
                                               "instance"};

   private static final Class[] ELEM_CLASSES = {Resolver.class,
                                                Describer.class,
                                                Handler.class,
                                                Filter.class,
                                                Object.class};

   private static final String ELEM_ROOT = "root";

   private static final String ATTR_CLASS = "class";
   private static final String ATTR_STATIC = "static";
   private static final String ATTR_NAME = "name";
   private static final String ATTR_INITIALIZER = "initializer";

   private static final String METHOD_SETCONFIG = "setConfig";

   private Broker broker;

   public Configurator(Broker broker) {
      this.broker = broker;
   }

   public void configure() {
      Broker.println("Labrador Broker Initialization");

      String config = System.getProperty(Broker.PROP_CONFIG);

      if ( config != null && config.length() > 0 ) {
         try {
            if ( config.indexOf("://") != -1 ) {
               // Load config from a URL
               URL url = new URL(config);
               InputStream is = url.openStream();
               BufferedInputStream bis = new BufferedInputStream(is, BUFFER_SIZE);
               loadConfiguration(bis);
               is.close();
            }
            else {
               // Load config from a File
               FileInputStream fis = new FileInputStream(config);
               BufferedInputStream bis = new BufferedInputStream(fis, BUFFER_SIZE);
               loadConfiguration(bis);
               fis.close();
            }
            return;
         }
         catch ( Exception e ) {
            Broker.printwarning("Labrador Configuration Error");
            Broker.printwarning("   '" + config + "' " + e.getMessage());
            Broker.printwarning("   Falling back to internal configuration");
         }
      }

      // Fall back to the resource based config
      try {
         InputStream is = this.getClass().getResourceAsStream(Broker.DEFAULT_CONFIG);
         BufferedInputStream bis = new BufferedInputStream(is, BUFFER_SIZE);
         loadConfiguration(bis);
         is.close();
      }
      catch ( Exception e ) {
         Broker.printerr("Labrador Configuration Error");
         Broker.printerr("   Default configuration cannot be read");
         Broker.printerr("   " + e.getMessage());
      }

      String instances = System.getProperty(Broker.PROP_INSTANCES);
      if ( instances != null ) {
         try {
            Document doc = DOMHelper.newDocument();
            Element root = doc.createElement(ELEM_ROOT);
            doc.appendChild(root);

            StringTokenizer st = new StringTokenizer(instances, ",");
            while ( st.hasMoreTokens() ) {
               String className = st.nextToken();
               if ( className.trim().length() != -1 ) {
                  Element instElem = doc.createElement(ELEM_NAMES[TYPE_INSTANCE]);
                  root.appendChild(instElem);
                  int idx = className.indexOf('=');
                  if ( idx != -1 ) {
                     String instName = className.substring(0, idx);
                     className = className.substring(idx + 1);
                     instElem.setAttribute(ATTR_NAME, instName);
                  }
                  instElem.setAttribute(ATTR_CLASS, className);
                  Configuration cfg = new Configuration(instElem);
                  Object o = constructInstance(cfg, ELEM_CLASSES[TYPE_INSTANCE]);
                  Broker.println("Instance: " + o.getClass().getName());
               }
            }
         }
         catch ( Exception e ) {
            Broker.printerr("Labrador Configuration Error");
            Broker.printerr("   " + e.getMessage());
         }
      }
   }

   private void loadConfiguration(InputStream is) throws ConfigurationException, IOException {
      try {
         Document doc = DOMHelper.parse(is);
         Configuration root = new Configuration(doc);

         if ( !root.getName().equals(ELEM_LABRADOR) )
            throw new IOException("Invalid configuration format");

         root.processChildren(new ConfigurationCallback() {
            public void process(Configuration cfg) {
               for ( int j = 0; j < ELEM_NAMES.length; j++ ) {
                  if ( cfg.getName().equals(ELEM_NAMES[j]) ) {
                     Class c = ELEM_CLASSES[j];
                     Object o = constructInstance(cfg, c);
                     if ( o != null ) {
                        switch ( j ) {
                           case TYPE_RESOLVER:
                              broker.addResolver((Resolver)o);
                              break;
                           case TYPE_DESCRIBER:
                              broker.addDescriber((Describer)o);
                              break;
                           case TYPE_HANDLER:
                              broker.addHandler((Handler)o);
                              break;
                           case TYPE_FILTER:
                              broker.addFilter((Filter)o);
                              break;
                           case TYPE_INSTANCE:
                              Broker.println("Instance: " + o.getClass().getName());
                              break;
                        }
                     }
                     continue;
                  }
               }
            }
         });
      }
      catch ( SAXException e ) {
         Broker.printerr("Labrador Configuration Error");
         Broker.printerr("   Couldn't parse configuration");
         Broker.printerr("   " + e.getMessage());
         return;
      }
   }

   private Object constructInstance(Configuration cfg, Class comp) {
      try {
         Class c = Class.forName(cfg.getAttribute(ATTR_CLASS));

         if ( comp != null && c.getClass().isAssignableFrom(comp) ) {
            Broker.printerr("Labrador Configuration Error");
            Broker.printerr("   Class is not compatible");
            Broker.printerr("   " + comp.getName());
            return null;
         }

         String nameValue = cfg.getAttribute(ATTR_NAME);

         if ( cfg.getBooleanAttribute(ATTR_STATIC) ) {
            try {
               // If an initializer attribute is specified, call it either
               // passing the specified name or void parameters.
               String initValue = cfg.getAttribute(ATTR_INITIALIZER);
               if ( initValue != null && initValue.length() > 0 ) {
                  if ( nameValue != null && nameValue.length() > 0 ) {
                     Method m = c.getMethod(initValue, new Class[]{String.class});
                     int mods = m.getModifiers();
                     if ( Modifier.isStatic(mods) && Modifier.isPublic(mods) )
                        m.invoke(c, new Object[]{nameValue});
                  }
                  else {
                     Method m = c.getMethod(initValue, new Class[0]);
                     int mods = m.getModifiers();
                     if ( Modifier.isStatic(mods) && Modifier.isPublic(mods) )
                        m.invoke(c, new Object[0]);
                  }
               }
            }
            catch ( Exception e ) {
               Broker.printerr("Labrador Configuration Error");
               Broker.printerr("   Couldn't find initializer method");
               Broker.printerr("   " + e.getMessage());
            }

            try {
               // If this is a static instance, check for a static setConfig
               // method and call it with the current Configuration object
               Method m = c.getMethod(METHOD_SETCONFIG, new Class[]{Configuration.class});
               if ( m != null ) {
                  int mods = m.getModifiers();
                  if ( Modifier.isStatic(mods) && Modifier.isPublic(mods) )
                     m.invoke(c, new Object[]{cfg});
               }
            }
            catch ( Exception e ) {
               // If it doesn't have the setConfig method, then no biggie
            }

            return null;
         }
         else {
            Object obj;
            // If a name is specified, construct the object with the name
            // as a parameter, otherwise use the default constructor.
            if ( nameValue != null && nameValue.length() > 0 ) {
               Constructor constructor = c.getConstructor(new Class[]{String.class});
               obj = constructor.newInstance(new Object[]{nameValue});
            }
            else
               obj = c.newInstance();

            // If the object is Configurable, call setMethod with the
            // current Configuration object.
            if ( obj instanceof Configurable )
               ((Configurable)obj).setConfig(cfg);

            return obj;
         }
      }
      catch ( Exception ex ) {
         ex.printStackTrace(System.err);
         Broker.printerr("Labrador Configuration Error");
         Broker.printerr("   Couldn't create class instance");
         Broker.printerr("   " + ex.getMessage());
         return null;
      }
   }
}
TOP

Related Classes of com.dbxml.labrador.broker.Configurator

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.