ant-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cos...@apache.org
Subject cvs commit: jakarta-ant/proposal/sandbox/embed RuntimeConfigurable2.java ProjectHelperImpl2.java ProjectComponentHelper.java
Date Fri, 17 May 2002 21:26:41 GMT
costin      02/05/17 14:26:41

  Modified:    proposal/sandbox/embed ProjectHelperImpl2.java
  Added:       proposal/sandbox/embed RuntimeConfigurable2.java
  Removed:     proposal/sandbox/embed ProjectComponentHelper.java
  Log:
  Small update to the SAX2 reader - use a class that extends RuntimeConfigurable
  and supports SAX2 attributes.
  
  In addition, the property substitution has few enhancements: if the
  property name is not found and it has a special syntax we'll use the
  references to compute a value.
  
  This is work in progress, but the intention is to support dom: syntax
  for selecting nodes ( similar with XmlProperties, but using 'life'
  DOM tree ) and bean: to use getters on the tasks/objects in the reference
  table.
  
  Revision  Changes    Path
  1.3       +20 -32    jakarta-ant/proposal/sandbox/embed/ProjectHelperImpl2.java
  
  Index: ProjectHelperImpl2.java
  ===================================================================
  RCS file: /home/cvs/jakarta-ant/proposal/sandbox/embed/ProjectHelperImpl2.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ProjectHelperImpl2.java	5 Mar 2002 21:53:27 -0000	1.2
  +++ ProjectHelperImpl2.java	17 May 2002 21:26:41 -0000	1.3
  @@ -83,9 +83,10 @@
   import javax.xml.parsers.ParserConfigurationException;
   
   /**
  - * Original helper.
  + * Sax2 based project reader
    *
    * @author duncan@x180.com
  + * @author Costin Manolache
    */
   public class ProjectHelperImpl2 extends ProjectHelper {
       /* Stateless */
  @@ -709,14 +710,14 @@
            * Wrapper for the parent element, if any. The wrapper for this 
            * element will be added to this wrapper as a child.
            */
  -        private RuntimeConfigurable parentWrapper;
  +        private RuntimeConfigurable2 parentWrapper;
           /**
            * Wrapper for this element which takes care of actually configuring
            * the element, if this element is contained within a target. 
            * Otherwise the configuration is performed with the configure method.
            * @see ProjectHelper#configure(Object,Attributes,Project)
            */
  -        private RuntimeConfigurable wrapper = null;
  +        private RuntimeConfigurable2 wrapper = null;
           
           /**
            * Constructor.
  @@ -739,7 +740,7 @@
            * @param target        Target this element is part of.
            *                      May be <code>null</code>.
            */
  -        public TaskHandler(TaskContainer container, RuntimeConfigurable parentWrapper,
Target target) {
  +        public TaskHandler(TaskContainer container, RuntimeConfigurable2 parentWrapper,
Target target) {
               this.container = container;
               this.parentWrapper = parentWrapper;
               this.target = target;
  @@ -790,14 +791,15 @@
                   task.setOwningTarget(target);
                   container.addTask(task);
                   task.init();
  -                wrapper = task.getRuntimeConfigurableWrapper();
  -                wrapper.setAttributes(sax1Attributes(attrs));
  +                //wrapper = task.getRuntimeConfigurableWrapper();
  +                wrapper=new RuntimeConfigurable2(task, task.getTaskName());
  +                wrapper.setAttributes2(attrs);
                   if (parentWrapper != null) {
                       parentWrapper.addChild(wrapper);
                   }
               } else {
                   task.init();
  -                ProjectHelper.configure(task, sax1Attributes(attrs), context.project);
  +                RuntimeConfigurable2.configure(task, attrs, context.project);
               }
           }
   
  @@ -879,14 +881,14 @@
            * Wrapper for the parent element, if any. The wrapper for this 
            * element will be added to this wrapper as a child.
            */
  -        private RuntimeConfigurable parentWrapper;
  +        private RuntimeConfigurable2 parentWrapper;
           /**
            * Wrapper for this element which takes care of actually configuring
            * the element, if a parent wrapper is provided.
            * Otherwise the configuration is performed with the configure method.
            * @see ProjectHelper#configure(Object,Attributes,Project)
            */
  -        private RuntimeConfigurable childWrapper = null;
  +        private RuntimeConfigurable2 childWrapper = null;
           /** Target this element is part of, if any. */
           private Target target;
   
  @@ -907,7 +909,7 @@
            *                      May be <code>null</code>.
            */
           public NestedElementHandler(Object parent,
  -                                    RuntimeConfigurable parentWrapper,
  +                                    RuntimeConfigurable2 parentWrapper,
                                       Target target) {
               if (parent instanceof TaskAdapter) {
                   this.parent = ((TaskAdapter) parent).getProxy();
  @@ -957,11 +959,11 @@
                   context.configureId(child, attrs);
   
                   if (parentWrapper != null) {
  -                    childWrapper = new RuntimeConfigurable(child, qname);
  -                    childWrapper.setAttributes(sax1Attributes(attrs));
  +                    childWrapper = new RuntimeConfigurable2(child, qname);
  +                    childWrapper.setAttributes2(attrs);
                       parentWrapper.addChild(childWrapper);
                   } else {
  -                    ProjectHelper.configure(child, sax1Attributes(attrs), context.project);
  +                    RuntimeConfigurable2.configure(child, attrs, context.project);
                       ih.storeElement(context.project, parent, child, elementName);
                   }
               } catch (BuildException exc) {
  @@ -1035,7 +1037,7 @@
           /** The element being configured. */
           private Object element;
           /** Wrapper for this element, if it's part of a target. */
  -        private RuntimeConfigurable wrapper = null;
  +        private RuntimeConfigurable2 wrapper = null;
           
           /**
            * Constructor with a target specified.
  @@ -1075,11 +1077,11 @@
                   }
                   
                   if (target != null) {
  -                    wrapper = new RuntimeConfigurable(element, qname);
  -                    wrapper.setAttributes(sax1Attributes(attrs));
  +                    wrapper = new RuntimeConfigurable2(element, qname);
  +                    wrapper.setAttributes2(attrs);
                       target.addDataType(wrapper);
                   } else {
  -                    ProjectHelper.configure(element, sax1Attributes(attrs), context.project);
  +                    RuntimeConfigurable2.configure(element, attrs, context.project);
                       context.configureId(element, attrs);
                   }
               } catch (BuildException exc) {
  @@ -1131,19 +1133,5 @@
               return new NestedElementHandler(element, wrapper, target);
           }
       }
  -
  -    public static AttributeList sax1Attributes( Attributes sax2Att ) {
  -        AttributeListImpl sax1Att=new AttributeListImpl();
  -        int length = sax2Att.getLength();
  -        if (length > 0) {
  -            for (int i = 0; i < length; i++) {
  -                // System.out.println("Attributes: " + sax2Att.getQName(i) + " " +
  -                //                    sax2Att.getValue(i));
  -                sax1Att.addAttribute( sax2Att.getQName(i), 
  -                                      sax2Att.getType(i),
  -                                      sax2Att.getValue(i));
  -            }
  -	}
  -        return sax1Att;
  -    }
  +    
   }
  
  
  
  1.1                  jakarta-ant/proposal/sandbox/embed/RuntimeConfigurable2.java
  
  Index: RuntimeConfigurable2.java
  ===================================================================
  /*
   * The Apache Software License, Version 1.1
   *
   * Copyright (c) 2000-2002 The Apache Software Foundation.  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 acknowlegement:
   *       "This product includes software developed by the
   *        Apache Software Foundation (http://www.apache.org/)."
   *    Alternately, this acknowlegement may appear in the software itself,
   *    if and wherever such third-party acknowlegements normally appear.
   *
   * 4. The names "The Jakarta Project", "Ant", and "Apache Software
   *    Foundation" must not be used to endorse or promote products derived
   *    from this software without prior written permission. For written
   *    permission, please contact apache@apache.org.
   *
   * 5. Products derived from this software may not be called "Apache"
   *    nor may "Apache" appear in their names without prior written
   *    permission of the Apache Group.
   *
   * 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 APACHE SOFTWARE FOUNDATION 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.
   * ====================================================================
   *
   * This software consists of voluntary contributions made by many
   * individuals on behalf of the Apache Software Foundation.  For more
   * information on the Apache Software Foundation, please see
   * <http://www.apache.org/>.
   */
  
  package org.apache.tools.ant;
  
  import org.apache.tools.ant.helper.*;
  import java.util.Enumeration;
  import java.util.Locale;
  import java.util.Vector;
  import org.xml.sax.AttributeList;
  import org.xml.sax.Attributes;
  import org.xml.sax.helpers.AttributeListImpl;
  import org.xml.sax.helpers.AttributesImpl;
  
  /**
   * Wrapper class that holds the attributes of an element, its children, and 
   * any text within it. It then takes care of configuring that element at 
   * runtime.
   *
   * This uses SAX2 and a more flexible substitution mechansim, based on
   * o.a.tomcat.util.IntrospectionUtil.
   *
   * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a>
   * @author Costin Manolache
   */
  public class RuntimeConfigurable2 extends RuntimeConfigurable {
  
      /** Name of the element to configure. */
      private String elementTag = null;
      /** List of child element wrappers. */
      private Vector children = new Vector();
      /** The element to configure. */
      private Object wrappedObject = null;
      /** XML attributes for the element. */
      private Attributes attributes;
      /** Text appearing within the element. */
      private StringBuffer characters = new StringBuffer();
  
      /**
       * Sole constructor creating a wrapper for the specified object.
       * 
       * @param proxy The element to configure. Must not be <code>null</code>.
       * @param elementTag The tag name generating this element.
       *                   Should not be <code>null</code>.
       */
      public RuntimeConfigurable2(Object proxy, String elementTag) {
          super( proxy, elementTag );
          wrappedObject = proxy;
          this.elementTag = elementTag;
      }
  
      /**
       * Sets the element to configure. This is used when the real type of 
       * an element isn't known at the time of wrapper creation.
       * 
       * @param proxy The element to configure. Must not be <code>null</code>.
       */
      void setProxy(Object proxy) {
          wrappedObject = proxy;
      }
  
      /**
       * Sets the attributes for the wrapped element.
       * 
       * @param attributes List of attributes defined in the XML for this
       *                   element. May be <code>null</code>.
       * @deprecated It shouldn't be called by anyone except ProjectHelper
       */
      public void setAttributes(AttributeList attributes) {
          //    this.attributes = new AttributeListImpl(attributes);
      }
  
      public void setAttributes2(Attributes attributes) {
          this.attributes=new AttributesImpl( attributes );
      }
      
      /**
       * Returns the list of attributes for the wrapped element.
       * 
       * @return An AttributeList representing the attributes defined in the
       *         XML for this element. May be <code>null</code>.
       * @deprecated only for bkwd compatibility
       */
      public AttributeList getAttributes() {
          return sax1Attributes( attributes );
      }
  
      public Attributes getAttributes2() {
          return attributes;
      }
  
      public static AttributeList sax1Attributes( Attributes sax2Att ) {
          AttributeListImpl sax1Att=new AttributeListImpl();
          int length = sax2Att.getLength();
          if (length > 0) {
              for (int i = 0; i < length; i++) {
                  // System.out.println("Attributes: " + sax2Att.getQName(i) + " " +
                  //                    sax2Att.getValue(i));
                  sax1Att.addAttribute( sax2Att.getQName(i), 
                                        sax2Att.getType(i),
                                        sax2Att.getValue(i));
              }
  	}
          return sax1Att;
      }
  
      /**
       * Adds a child element to the wrapped element.
       * 
       * @param child The child element wrapper to add to this one.
       *              Must not be <code>null</code>.
       */
      public void addChild(RuntimeConfigurable child) {
          children.addElement(child);
      }
  
      /**
       * Returns the child wrapper at the specified position within the list.
       * 
       * @param index The index of the child to return.
       * 
       * @return The child wrapper at position <code>index</code> within the
       *         list.
       */
      RuntimeConfigurable getChild(int index) {
          return (RuntimeConfigurable) children.elementAt(index);
      }
  
      /**
       * Adds characters from #PCDATA areas to the wrapped element.
       * 
       * @param data Text to add to the wrapped element. 
       *        Should not be <code>null</code>.
       */
      public void addText(String data) {
          characters.append(data);
      }
  
      /**
       * Adds characters from #PCDATA areas to the wrapped element.
       * 
       * @param buf A character array of the text within the element.
       *            Must not be <code>null</code>.
       * @param start The start element in the array.
       * @param count The number of characters to read from the array.
       * 
       */
      public void addText(char[] buf, int start, int count) {
          addText(new String(buf, start, count));
      }
  
      /**
       * Returns the tag name of the wrapped element.
       * 
       * @return The tag name of the wrapped element. This is unlikely
       *         to be <code>null</code>, but may be.
       */
      public String getElementTag() {
          return elementTag;
      }
  
      /**
       * Configures the wrapped element and all its children.
       * The attributes and text for the wrapped element are configured,
       * and then each child is configured and added. Each time the
       * wrapper is configured, the attributes and text for it are
       * reset.
       * 
       * If the element has an <code>id</code> attribute, a reference
       * is added to the project as well.
       * 
       * @param p The project containing the wrapped element. 
       *          Must not be <code>null</code>.
       * 
       * @exception BuildException if the configuration fails, for instance due
       *            to invalid attributes or children, or text being added to
       *            an element which doesn't accept it.
       */
      public void maybeConfigure(Project p) throws BuildException {
          String id = null;
  
          if (attributes != null) {
              configure(wrappedObject, attributes, p);
              id = attributes.getValue("id");
              attributes = null;
          }
          
          if (characters.length() != 0) {
              ProjectHelper.addText(p, wrappedObject, characters.toString());
              characters.setLength(0);
          }
          Enumeration enum = children.elements();
          while (enum.hasMoreElements()) {
              RuntimeConfigurable2 child 
                  = (RuntimeConfigurable2) enum.nextElement();
              if (child.wrappedObject instanceof Task) {
                  Task childTask = (Task) child.wrappedObject;
                  childTask.setRuntimeConfigurableWrapper(child);
                  childTask.maybeConfigure();
              } else {
                  child.maybeConfigure(p);
              }
              ProjectHelper.storeChild(p, wrappedObject, child.wrappedObject, 
                  child.getElementTag().toLowerCase(Locale.US));
          }
  
          if (id != null) {
              p.addReference(id, wrappedObject);
          }
      }
  
  
      public static void configure( Object target, Attributes attrs, Project project )
          throws BuildException
      {
          if (target instanceof TaskAdapter) {
              target = ((TaskAdapter) target).getProxy();
          }
          
          IntrospectionHelper ih = 
              IntrospectionHelper.getHelper(target.getClass());
          
          project.addBuildListener(ih);
          
          for (int i = 0; i < attrs.getLength(); i++) {
              // reflect these into the target
              String value = RuntimeConfigurable2.replaceProperties(project, attrs.getValue(i));
              
              try {
                  ih.setAttribute(project, target, 
                                  attrs.getQName(i).toLowerCase(Locale.US), value);
                  
              } catch (BuildException be) {
                  // id attribute must be set externally
                  if (!attrs.getQName(i).equals("id")) {
                      throw be;
                  }
              }
          }
      }
  
      public static String replaceProperties( Project project ,String value ) {
          if (value == null) {
              return null;
          }
  
          Vector fragments = new Vector();
          Vector propertyRefs = new Vector();
  
          ProjectHelper.parsePropertyString(value, fragments, propertyRefs);
  
          StringBuffer sb = new StringBuffer();
          Enumeration i = fragments.elements();
          Enumeration j = propertyRefs.elements();
          while (i.hasMoreElements()) {
              
              String fragment = (String) i.nextElement();
              if (fragment == null) {
                  String propertyName = (String) j.nextElement();
                  Object repl=project.getProperty( propertyName );
  
                  if( repl==null) {
                      // Try a dynamic substitiution using ref
                      repl=processReference( project, propertyName );
                  }
                  
                  if (repl==null ) {
                      project.log("Property ${" + propertyName 
                          + "} has not been set", Project.MSG_VERBOSE);
                      fragment="${" + propertyName + "}"; 
                  } else {
                      fragment = (String) repl;
                  }
              }
              sb.append(fragment);
          }                        
          
          return sb.toString();
  
      }
      
      
      /** Use the reference table to generate values for ${} substitution.
       *  To preserve backward compat ( as much as possible ) we'll only process
       *  ids with a 'namespace-like' syntax.
       *
       *  Currently we support:
       *    dom:idName:/xpath/like/syntax  - the referenced node must be a DOM, we'll use
       *                      XPath to extract a node. ( a simplified syntax is handled
       *                      directly, XXX used for 'real' xpaths ).
       *    toString:idName - we use toString on the referenced object
       *    bean:idName.propertyName - we get the idName and call the getter for the property.

       */
      static String processReference( Project project, String name ) {
          if( name.startsWith("dom:") ) {
              name=name.substring( 4 );
              int idx=name.indexOf(":");
              if( idx<0 ) return null;
  
              String objName=name.substring( 0, idx );
              String path=name.substring( idx );
              System.out.println("XXX dom: " + objName + " " + path );
  
              Object v=project.getReference( objName );
              if( v==null ) return null;
  
          }
  
          if( name.startsWith( "toString:" )) {
              name=name.substring( "toString:".length());
              Object v=project.getReference( name );
              if( v==null ) return null;
              return v.toString();
          }
  
          if( name.startsWith( "bean:" )) {
              name=name.substring( "toString:".length());
              int idx=name.indexOf(":");
              if( idx<0 ) return null;
  
              String objName=name.substring( 0, idx );
              String path=name.substring( idx );
              System.out.println("XXX bean: " + objName + " " + path );
  
              Object v=project.getReference( objName );
              if( v==null ) return null;
  
              return v.toString();
          }
  
  
          
          // If everything else fails, use toString()
          return null;
      }
  
  
  }
  
  
  

--
To unsubscribe, e-mail:   <mailto:ant-dev-unsubscribe@jakarta.apache.org>
For additional commands, e-mail: <mailto:ant-dev-help@jakarta.apache.org>


Mime
View raw message