tapestry-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hls...@apache.org
Subject cvs commit: jakarta-tapestry/framework/src/org/apache/tapestry/parse Tapestry_1_4.dtd SpecificationParser.java
Date Sun, 23 Mar 2003 23:18:30 GMT
hlship      2003/03/23 15:18:30

  Modified:    framework/src/org/apache/tapestry/enhance
                        ComponentClassFactory.java MethodFabricator.java
                        ClassFabricator.java CreatePropertyEnhancer.java
               framework/src/org/apache/tapestry TapestryStrings.properties
               framework/src/org/apache/tapestry/link DirectLink.java
                        DirectLink.jwc
               framework/src/org/apache/tapestry/pageload PageLoader.java
               framework/src/org/apache/tapestry/spec Direction.java
               framework/src/org/apache/tapestry/param
                        ParameterManager.java
               framework/src/org/apache/tapestry/parse Tapestry_1_4.dtd
                        SpecificationParser.java
  Added:       framework/src/org/apache/tapestry/enhance
                        CreateAutoParameterEnhancer.java
  Log:
  Add support for parameter direction 'auto'.
  
  Revision  Changes    Path
  1.8       +49 -6     jakarta-tapestry/framework/src/org/apache/tapestry/enhance/ComponentClassFactory.java
  
  Index: ComponentClassFactory.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/enhance/ComponentClassFactory.java,v
  retrieving revision 1.7
  retrieving revision 1.8
  diff -u -r1.7 -r1.8
  --- ComponentClassFactory.java	23 Mar 2003 01:26:41 -0000	1.7
  +++ ComponentClassFactory.java	23 Mar 2003 23:18:29 -0000	1.8
  @@ -326,7 +326,7 @@
        * 
        **/
   
  -    protected String buildMethodName(String prefix, String propertyName)
  +    public String buildMethodName(String prefix, String propertyName)
       {
           StringBuffer result = new StringBuffer(prefix);
   
  @@ -479,7 +479,7 @@
           String fieldName,
           String propertyName,
           String readMethodName)
  -    {
  +    {	
           String methodName =
               readMethodName == null ? buildMethodName("get", propertyName) : readMethodName;
   
  @@ -590,7 +590,7 @@
   
               scanForBindingProperty(name, ps);
   
  -            scanForParameterProperty(ps);
  +            scanForParameterProperty(name, ps);
           }
   
       }
  @@ -628,10 +628,18 @@
           addEnhancer(enhancer);
       }
   
  -    protected void scanForParameterProperty(ParameterSpecification ps)
  +    protected void scanForParameterProperty(String parameterName, ParameterSpecification
ps)
       {
  -        if (ps.getDirection() == Direction.CUSTOM)
  +        Direction direction = ps.getDirection();
  +
  +        if (direction == Direction.CUSTOM)
  +            return;
  +
  +        if (direction == Direction.AUTO)
  +        {
  +            addAutoParameterEnhancer(parameterName, ps);
               return;
  +        }
   
           String propertyName = ps.getPropertyName();
   
  @@ -654,6 +662,36 @@
           addEnhancer(enhancer);
       }
   
  +    protected void addAutoParameterEnhancer(String parameterName, ParameterSpecification
ps)
  +    {
  +        Location location = ps.getLocation();
  +        String propertyName = ps.getPropertyName();
  +
  +        if (!ps.isRequired())
  +            throw new ApplicationRuntimeException(
  +                Tapestry.getString("ComponentClassFactory.auto-must-be-required", parameterName),
  +                location,
  +                null);
  +
  +        Class propertyType = convertPropertyType(ps.getType(), location);
  +
  +        String readMethodName = checkAccessors(propertyName, propertyType, location);
  +
  +        Type fieldType = getObjectType(ps.getType());
  +
  +        IEnhancer enhancer =
  +            new CreateAutoParameterEnhancer(
  +                this,
  +                propertyName,
  +                parameterName,
  +                fieldType,
  +                ps.getType(),
  +                readMethodName,
  +                location);
  +
  +        addEnhancer(enhancer);
  +    }
  +
       protected void scanForSpecifiedProperty(PropertySpecification ps)
       {
           String propertyName = ps.getName();
  @@ -681,6 +719,11 @@
               LOG.debug("Creating field: " + fieldName);
   
           _classFabricator.addField(fieldType, fieldName);
  +    }
  +
  +    public ClassFabricator getClassFabricator()
  +    {
  +        return _classFabricator;
       }
   
   }
  
  
  
  1.3       +32 -2     jakarta-tapestry/framework/src/org/apache/tapestry/enhance/MethodFabricator.java
  
  Index: MethodFabricator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/enhance/MethodFabricator.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- MethodFabricator.java	23 Mar 2003 01:26:41 -0000	1.2
  +++ MethodFabricator.java	23 Mar 2003 23:18:29 -0000	1.3
  @@ -60,6 +60,7 @@
   
   import org.apache.tapestry.Tapestry;
   import org.apache.bcel.classfile.Method;
  +import org.apache.bcel.generic.BranchInstruction;
   import org.apache.bcel.generic.ClassGen;
   import org.apache.bcel.generic.CompoundInstruction;
   import org.apache.bcel.generic.Instruction;
  @@ -67,6 +68,7 @@
   import org.apache.bcel.generic.InstructionList;
   import org.apache.bcel.generic.LocalVariableGen;
   import org.apache.bcel.generic.MethodGen;
  +import org.apache.bcel.generic.ObjectType;
   import org.apache.bcel.generic.Type;
   
   /**
  @@ -174,12 +176,22 @@
           return _instructionList.append(instruction);
       }
   
  +    /**
  +     *  Convienience method for adding instructions.
  +     * 
  +     **/
  +
  +    public InstructionHandle append(CompoundInstruction instruction)
  +    {
  +        return _instructionList.append(instruction);
  +    }
  +
   	/**
   	 *  Convienience method for adding instructions.
   	 * 
   	 **/
   	
  -	public InstructionHandle append(CompoundInstruction instruction)
  +	public InstructionHandle append(BranchInstruction instruction)
   	{
   		return _instructionList.append(instruction);
   	}
  @@ -244,5 +256,23 @@
           }
   
           _argumentsCommitted = true;
  +    }
  +
  +	/**
  +	 *  Adds an exception handler.  The start and end instructions are indicated by their
  +	 *  handles (to be honest, I'm shakey on whether the entire end instruction is covered,
  +	 *  or only until just before the end instruction).  The handler is an instruction
  +	 *  that should immediately follow the protected block.  The catch type
  +	 *  determines what kind of exception will be caught.
  +	 * 
  +	 **/
  +	
  +    public void addExceptionHandler(
  +        InstructionHandle start,
  +        InstructionHandle end,
  +        InstructionHandle handler,
  +        ObjectType catchType)
  +    {
  +        _methodGen.addExceptionHandler(start, end, handler, catchType);
       }
   }
  
  
  
  1.3       +80 -35    jakarta-tapestry/framework/src/org/apache/tapestry/enhance/ClassFabricator.java
  
  Index: ClassFabricator.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/enhance/ClassFabricator.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- ClassFabricator.java	23 Mar 2003 01:26:41 -0000	1.2
  +++ ClassFabricator.java	23 Mar 2003 23:18:29 -0000	1.3
  @@ -73,6 +73,7 @@
   {
       private ClassGen _classGen;
       private InstructionFactory _instructionFactory;
  +    private MethodFabricator _staticInitializeMethod;
   
       /**
        *  Creates a public final class.
  @@ -101,14 +102,14 @@
                   null);
       }
   
  -	/**
  -	 *  Creates a new {@link MethodFabricator}.  Invoke
  -	 *  {@link MethodFabricator#getInstructionList()}
  -	 *  to obtain the (initially empty) instruction list
  -	 *  for the method.
  -	 * 
  -	 **/
  -	
  +    /**
  +     *  Creates a new {@link MethodFabricator}.  Invoke
  +     *  {@link MethodFabricator#getInstructionList()}
  +     *  to obtain the (initially empty) instruction list
  +     *  for the method.
  +     * 
  +     **/
  +
       public MethodFabricator createMethod(int accessFlags, Type returnType, String methodName)
       {
           return new MethodFabricator(_classGen, accessFlags, returnType, methodName);
  @@ -158,49 +159,93 @@
           _classGen.addEmptyConstructor(Constants.ACC_PUBLIC);
       }
   
  +    /**
  +     *  Adds an interface to the list of interfaces implemented
  +     *  by the class.
  +     * 
  +     **/
   
  -	/**
  -	 *  Adds an interface to the list of interfaces implemented
  -	 *  by the class.
  -	 * 
  -	 **/
  -	
  -	public void addInterface(String interfaceName)
  -	{
  -		_classGen.addInterface(interfaceName);
  -	}
  -	
  -	public void addInterface(Class interfaceClass)
  -	{
  -		addInterface(interfaceClass.getName());
  -	}
  -	
  -	public InstructionFactory getInstructionFactory()
  -	{
  -		if (_instructionFactory == null)
  -			_instructionFactory = new InstructionFactory(_classGen);
  -		
  -		return _instructionFactory;
  -	}
  +    public void addInterface(String interfaceName)
  +    {
  +        _classGen.addInterface(interfaceName);
  +    }
  +
  +    public void addInterface(Class interfaceClass)
  +    {
  +        addInterface(interfaceClass.getName());
  +    }
  +
  +    public InstructionFactory getInstructionFactory()
  +    {
  +        if (_instructionFactory == null)
  +            _instructionFactory = new InstructionFactory(_classGen);
  +
  +        return _instructionFactory;
  +    }
   
       /**
        *  Invoked very much last, to create the
        *  new {@link org.apache.bcel.classfile.JavaClass} instance.
        * 
  +     *  If there is a
  +     *  {@link #getStaticInitializerMethod() static initializer method},
  +     *  then a {@link RETURN} opcode is appended, and the method is committed.
  +     * 
        **/
   
       public JavaClass commit()
       {
  +        if (_staticInitializeMethod != null)
  +        {
  +        	_staticInitializeMethod.append(InstructionConstants.RETURN);
  +            _staticInitializeMethod.commit();
  +        }
  +
           return _classGen.getJavaClass();
       }
  -    
  +
  +    /**
  +     *  Returns the static initializer method for the class,
  +     *  creating it if necessary.
  +     * 
  +     *  <p>
  +     *  Do not add {@link RETURN} opcodes to the initializer;
  +     *  it may be accessed by several enhancers, each of which
  +     *  will need to add some code; putting a RETURN in the middle
  +     *  will keep some of the initializations from being executed!
  +     * 
  +     *  <p>
  +     *  {@link #commit()} will append a RETURN and commit
  +     *  the method.
  +     * 
  +     **/
  +
  +    public MethodFabricator getStaticInitializerMethod()
  +    {
  +        if (_staticInitializeMethod == null)
  +            _staticInitializeMethod =
  +                createMethod(Constants.ACC_STATIC, Type.VOID, Constants.STATIC_INITIALIZER_NAME);
  +
  +        return _staticInitializeMethod;
  +    }
  +
       /**
        *  Returns the mutable constant pool.
        * 
        **/
  -    
  +
       public ConstantPoolGen getConstantPool()
       {
  -    	return _classGen.getConstantPool();
  +        return _classGen.getConstantPool();
  +    }
  +
  +    /**
  +     *  Returns the name of the class being fabricated.
  +     * 
  +     **/
  +
  +    public String getClassName()
  +    {
  +        return _classGen.getClassName();
       }
   }
  
  
  
  1.2       +12 -1     jakarta-tapestry/framework/src/org/apache/tapestry/enhance/CreatePropertyEnhancer.java
  
  Index: CreatePropertyEnhancer.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/enhance/CreatePropertyEnhancer.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- CreatePropertyEnhancer.java	23 Mar 2003 01:26:41 -0000	1.1
  +++ CreatePropertyEnhancer.java	23 Mar 2003 23:18:29 -0000	1.2
  @@ -58,6 +58,17 @@
   import org.apache.bcel.generic.Type;
   import org.apache.tapestry.Location;
   
  +/**
  + *  Creates a new property of a particular type in the enhanced subclass.  May optionally
  + *  make the property a persistent property, by injecting an invocation of
  + *  {@link org.apache.tapestry.AbstractComponent#fireObservedChange(String, Object)}
  + *  into the mutator (setter) method.
  + *
  + *  @author Howard Lewis Ship
  + *  @version $Id$
  + *  @since 2.4
  + *
  + **/
   public class CreatePropertyEnhancer implements IEnhancer
   {
       private String _propertyName;
  @@ -89,7 +100,7 @@
       {
           String fieldName = "_$" + _propertyName;
   
  -  		factory.createField(_propertyType, fieldName);
  +        factory.createField(_propertyType, fieldName);
           factory.createAccessor(_propertyType, fieldName, _propertyName, _readMethodName);
           factory.createMutator(_propertyType, fieldName, _propertyName, _persistent);
       }
  
  
  
  1.1                  jakarta-tapestry/framework/src/org/apache/tapestry/enhance/CreateAutoParameterEnhancer.java
  
  Index: CreateAutoParameterEnhancer.java
  ===================================================================
  package org.apache.tapestry.enhance;
  
  import org.apache.bcel.Constants;
  import org.apache.bcel.generic.BranchInstruction;
  import org.apache.bcel.generic.GOTO;
  import org.apache.bcel.generic.IFNONNULL;
  import org.apache.bcel.generic.InstructionConstants;
  import org.apache.bcel.generic.InstructionFactory;
  import org.apache.bcel.generic.InstructionHandle;
  import org.apache.bcel.generic.ObjectType;
  import org.apache.bcel.generic.PUSH;
  import org.apache.bcel.generic.ReferenceType;
  import org.apache.bcel.generic.Type;
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  import org.apache.tapestry.ApplicationRuntimeException;
  import org.apache.tapestry.IBinding;
  import org.apache.tapestry.Location;
  import org.apache.tapestry.Tapestry;
  
  /**
   *  Creates a synthetic property for a
   *  {@link org.apache.tapestry.spec.Direction#AUTO}
   *  parameter.
   *
   *  @author Howard Lewis Ship
   *  @version $Id: CreateAutoParameterEnhancer.java,v 1.1 2003/03/23 23:18:29 hlship Exp
$
   *  @since 2.4
   *
   **/
  
  public class CreateAutoParameterEnhancer implements IEnhancer
  {
      private static final Log LOG = LogFactory.getLog(CreateAutoParameterEnhancer.class);
  
      private ComponentClassFactory _factory;
      private String _propertyName;
      private String _parameterName;
      private Type _type;
      private String _typeClassName;
      private String _readMethodName;
      private Location _location;
  
      private Type _bindingType;
      private Type _classType;
  
      public CreateAutoParameterEnhancer(
          ComponentClassFactory factory,
          String propertyName,
          String parameterName,
          Type type,
          String typeClassName,
          String readMethodName,
          Location location)
      {
          _factory = factory;
          _propertyName = propertyName;
          _parameterName = parameterName;
          _type = type;
          _typeClassName = typeClassName;
          _readMethodName = readMethodName;
          _location = location;
  
          _bindingType = factory.getObjectType(IBinding.class.getName());
          _classType = factory.getObjectType(Class.class.getName());
      }
  
      public void performEnhancement(ComponentClassFactory factory)
      {
          if (LOG.isDebugEnabled())
              LOG.debug("Creating auto property: " + _propertyName);
  
          ClassFabricator cf = factory.getClassFabricator();
  
          String readBindingMethodName =
              _factory.buildMethodName(
                  "get",
                  _parameterName + Tapestry.PARAMETER_PROPERTY_NAME_SUFFIX);
  
          createReadMethod(cf, readBindingMethodName);
          createWriteMethod(cf, readBindingMethodName);
      }
  
      private String createParameterTypeField(ClassFabricator cf)
      {
          String fieldName = "$type$" + _parameterName;
  
          cf.addField(Constants.ACC_PRIVATE | Constants.ACC_STATIC, _classType, fieldName);
  
          MethodFabricator mf = cf.getStaticInitializerMethod();
          InstructionFactory factory = cf.getInstructionFactory();
          String className = cf.getClassName();
          Type throwableType = _factory.getObjectType(Throwable.class.getName());
  
          mf.append(factory.createGetStatic(className, fieldName, _classType));
  
          BranchInstruction ifNotNullBI = new IFNONNULL(null);
  
          mf.append(ifNotNullBI);
  
          // Invoke Class.forName and store ther result.
          // Concern: will the class be visible to the right class loader?
          // May need to use alternate forName() and pass Thread's context class loader.
  
  		mf.append(new PUSH(cf.getConstantPool(), _typeClassName));
          InstructionHandle tryStart =
              mf.append(
                  factory.createInvoke(
                      "java.lang.Class",
                      "forName",
                      _classType,
                      new Type[] { Type.STRING },
                      Constants.INVOKESTATIC));
          mf.append(factory.createPutStatic(className, fieldName, _classType));
  
          GOTO jumpOut = new GOTO(null);
  
          InstructionHandle tryEnd = mf.append(jumpOut);
  
          String exceptionClassName = ApplicationRuntimeException.class.getName();
  
          InstructionHandle catchHandle = mf.append(factory.createNew(exceptionClassName));
  
  		// This stuff can make my head spin, so let's map it out a little.
  		// CCE = ClassCastException, ARE = ApplicationRuntimeException
  
  		// Stack: CCE, ARE --> ARE, CCE, ARE
  		
  		mf.append(InstructionConstants.DUP_X1);
  		
  		// Stack: ARE, CCE, ARE -> ARE, ARE, CCE
  		
          mf.append(InstructionConstants.SWAP);
  
          mf.append(
              factory.createInvoke(
                  exceptionClassName,
                  Constants.CONSTRUCTOR_NAME,
                  Type.VOID,
                  new Type[] { throwableType },
                  Constants.INVOKESPECIAL));
  
          mf.append(InstructionConstants.ATHROW);
  
          mf.addExceptionHandler(
              tryStart,
              tryEnd,
              catchHandle,
              new ObjectType(ClassNotFoundException.class.getName()));
  
          InstructionHandle end = mf.append(InstructionConstants.NOP);
  
          ifNotNullBI.setTarget(end);
          jumpOut.setTarget(end);
  
          return fieldName;
      }
  
      private void createReadMethod(ClassFabricator cf, String readBindingMethodName)
      {
          String methodName =
              _readMethodName == null
                  ? _factory.buildMethodName("get", _propertyName)
                  : _readMethodName;
  
          if (LOG.isDebugEnabled())
              LOG.debug("Creating method: " + methodName);
  
  		Type[] noArgs = new Type[] { };
  
          MethodFabricator mf = cf.createMethod(Constants.ACC_PUBLIC, _type, methodName);
  
          InstructionFactory factory = cf.getInstructionFactory();
  
          mf.append(factory.createThis());
          mf.append(
              factory.createInvoke(
                  cf.getClassName(),
                  readBindingMethodName,
                  _bindingType,
                  noArgs,
                  Constants.INVOKEVIRTUAL));
  
          String accessMethodName = null;
  
          if (isBoolean(_type))
              accessMethodName = "getBoolean";
          else
              if (isInt(_type))
                  accessMethodName = "getInt";
              else
                  if (isDouble(_type))
                      accessMethodName = "getDouble";
                  else
                      if (isString(_type))
                          accessMethodName = "getString";
  
          if (accessMethodName != null)
          {
              // The binding object is on top of the stack
              mf.append(
                  factory.createInvoke(
                      IBinding.class.getName(),
                      accessMethodName,
                      _type,
                      noArgs,
                      Constants.INVOKEINTERFACE));
          }
          else
          {
              // Type is either an object type or an array type
  
              // To invoke getObject(parameterName, type) we need the type.
              // We mimic what Java compiler does; create a private static field
              // to store the type, and add a static initializer that invokes Class.forName.
  
              String fieldName = createParameterTypeField(cf);
  
              mf.append(new PUSH(cf.getConstantPool(), _parameterName));
              mf.append(factory.createGetStatic(cf.getClassName(), fieldName, _classType));
  
              mf.append(
                  factory.createInvoke(
                      IBinding.class.getName(),
                      "getObject",
                      Type.OBJECT,
                      new Type[] { Type.STRING, _classType },
                      Constants.INVOKEINTERFACE));
  
              // ReferenceType is superclass to ObjectType and ArrayType
  
              mf.append(factory.createCheckCast((ReferenceType) _type));
          }
  
          mf.append(factory.createReturn(_type));
  
          mf.commit();
      }
  
      private void createWriteMethod(ClassFabricator cf, String readBindingMethodName)
      {
          String methodName = _factory.buildMethodName("set", _propertyName);
  
          if (LOG.isDebugEnabled())
              LOG.debug("Creating method: " + methodName);
  
          MethodFabricator mf = cf.createMethod(methodName);
          mf.addArgument(_type, _propertyName);
  
          InstructionFactory factory = cf.getInstructionFactory();
  
          String updateMethodName = null;
          Type argumentType = _type;
  
          if (isBoolean(_type))
              updateMethodName = "setBoolean";
          else
              if (isInt(_type))
                  updateMethodName = "setInt";
              else
                  if (isDouble(_type))
                      updateMethodName = "setDouble";
                  else
                      if (isString(_type))
                          updateMethodName = "setString";
                      else
                      {
                          updateMethodName = "setObject";
                          argumentType = Type.OBJECT;
                      }
  
          // Get the binding
  
          mf.append(factory.createThis());
          mf.append(
              factory.createInvoke(
                  cf.getClassName(),
                  readBindingMethodName,
                  _bindingType,
                  new Type[] { },
                  Constants.INVOKEVIRTUAL));
  
          // Push the parameter value (remember,
          // parameter 0 is "this")
  
          mf.append(factory.createLoad(_type, 1));
  
          // Invoke the update method
  
          mf.append(
              factory.createInvoke(
                  IBinding.class.getName(),
                  updateMethodName,
                  Type.VOID,
                  new Type[] { argumentType },
                  Constants.INVOKEINTERFACE));
  
          mf.append(InstructionConstants.RETURN);
          mf.commit();
      }
  
      private boolean isBoolean(Type t)
      {
          return t.getType() == Constants.T_BOOLEAN;
      }
  
      private boolean isDouble(Type t)
      {
          return t.getType() == Constants.T_DOUBLE;
      }
  
      private boolean isInt(Type t)
      {
          return t.getType() == Constants.T_INT;
      }
  
      private boolean isString(Type t)
      {
          return Type.STRING.equals(t);
      }
  }
  
  
  
  1.9       +3 -1      jakarta-tapestry/framework/src/org/apache/tapestry/TapestryStrings.properties
  
  Index: TapestryStrings.properties
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/TapestryStrings.properties,v
  retrieving revision 1.8
  retrieving revision 1.9
  diff -u -r1.8 -r1.9
  --- TapestryStrings.properties	23 Mar 2003 16:12:38 -0000	1.8
  +++ TapestryStrings.properties	23 Mar 2003 23:18:29 -0000	1.9
  @@ -175,6 +175,8 @@
   ComponentClassFactory.non-abstract-read=Unable to enhance class {0} because it implements
a non-abstract read method for property ''{1}''.
   ComponentClassFactory.non-abstract-write=Unable to enhance class {0} because it implements
a non-abstract write method for property ''{1}''.
   ComponentClassFactory.unable-to-introspect-class=Unable to introspect properties of class
{0}.
  +ComponentClassFactory.auto-must-be-required=Parameter ''{0}'' must be required as it uses
direction ''auto''.
  +
   
   EnhancedClassLoader.unable-to-define-class=Unable to define class {0}: {1}
   
  
  
  
  1.3       +6 -23     jakarta-tapestry/framework/src/org/apache/tapestry/link/DirectLink.java
  
  Index: DirectLink.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/link/DirectLink.java,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- DirectLink.java	15 Mar 2003 21:22:27 -0000	1.2
  +++ DirectLink.java	23 Mar 2003 23:18:29 -0000	1.3
  @@ -79,6 +79,7 @@
   {
   
       public abstract IBinding getStatefulBinding();
  +    public abstract IActionListener getListener();
   
       /**
        *  Returns true if the stateful parameter is bound to
  @@ -151,30 +152,12 @@
   
       public void trigger(IRequestCycle cycle)
       {
  -        IActionListener listener = getListener(cycle);
  +        IActionListener listener = getListener();
  +        
  +        if (listener == null)
  +        	throw Tapestry.createRequiredParameterException(this, "listener");
   
           listener.actionTriggered(this, cycle);
  -    }
  -
  -    public abstract IBinding getListenerBinding();
  -
  -    /**
  -     *  Need to use the listener binding, since this method gets called even when the
  -     *  component is not rendering.
  -     * 
  -     **/
  -
  -    private IActionListener getListener(IRequestCycle cycle)
  -    {
  -        IBinding listenerBinding = getListenerBinding();
  -
  -        IActionListener result =
  -            (IActionListener) listenerBinding.getObject("listener", IActionListener.class);
  -
  -        if (result == null)
  -            throw Tapestry.createRequiredParameterException(this, "listener");
  -
  -        return result;
       }
   
       /** @since 2.2 **/
  
  
  
  1.2       +2 -2      jakarta-tapestry/framework/src/org/apache/tapestry/link/DirectLink.jwc
  
  Index: DirectLink.jwc
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/link/DirectLink.jwc,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- DirectLink.jwc	5 Mar 2003 22:59:39 -0000	1.1
  +++ DirectLink.jwc	23 Mar 2003 23:18:29 -0000	1.2
  @@ -14,7 +14,7 @@
     <parameter name="listener" 
     	type="org.apache.tapestry.IActionListener" 
     	required="yes"
  -  	direction="custom"/>
  +  	direction="auto"/>
     	
     <parameter name="parameters" type="java.lang.Object" direction="in">
       <description>
  
  
  
  1.6       +16 -7     jakarta-tapestry/framework/src/org/apache/tapestry/pageload/PageLoader.java
  
  Index: PageLoader.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/pageload/PageLoader.java,v
  retrieving revision 1.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- PageLoader.java	23 Mar 2003 01:29:43 -0000	1.5
  +++ PageLoader.java	23 Mar 2003 23:18:29 -0000	1.6
  @@ -416,8 +416,15 @@
                   _engine.getPropertySource().getPropertyValue(
                       "org.apache.tapestry.default-script-language");
   
  +        // Construct the binding.  The first parameter is the compononent
  +        // (not the DirectLink or Form, but the page or component containing the link or
form).
  +
           IBinding binding =
  -            new ListenerBinding(component, language, spec.getScript(), spec.getLocation());
  +            new ListenerBinding(
  +                component.getContainer(),
  +                language,
  +                spec.getScript(),
  +                spec.getLocation());
   
           component.setBinding(bindingName, binding);
       }
  @@ -595,6 +602,7 @@
               className = BaseComponent.class.getName();
   
           Class componentClass = _enhancer.getEnhancedClass(spec, className);
  +        String enhancedClassName = componentClass.getName();
   
           try
           {
  @@ -604,15 +612,15 @@
           catch (ClassCastException ex)
           {
               throw new ApplicationRuntimeException(
  -                Tapestry.getString("PageLoader.class-not-component", className),
  +                Tapestry.getString("PageLoader.class-not-component", enhancedClassName),
                   container,
                   spec.getLocation(),
                   ex);
           }
  -        catch (Exception ex)
  +        catch (Throwable ex)
           {
               throw new ApplicationRuntimeException(
  -                Tapestry.getString("PageLoader.unable-to-instantiate", className),
  +                Tapestry.getString("PageLoader.unable-to-instantiate", enhancedClassName),
                   container,
                   spec.getLocation(),
                   ex);
  @@ -677,6 +685,7 @@
           }
   
           Class pageClass = _enhancer.getEnhancedClass(spec, className);
  +        String enhancedClassName = pageClass.getName();
   
           try
           {
  @@ -692,14 +701,14 @@
           catch (ClassCastException ex)
           {
               throw new ApplicationRuntimeException(
  -                Tapestry.getString("PageLoader.class-not-page", className),
  +                Tapestry.getString("PageLoader.class-not-page", enhancedClassName),
                   location,
                   ex);
           }
           catch (Exception ex)
           {
               throw new ApplicationRuntimeException(
  -                Tapestry.getString("PageLoader.unable-to-instantiate", className),
  +                Tapestry.getString("PageLoader.unable-to-instantiate", enhancedClassName),
                   location,
                   ex);
           }
  
  
  
  1.2       +12 -1     jakarta-tapestry/framework/src/org/apache/tapestry/spec/Direction.java
  
  Index: Direction.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/spec/Direction.java,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Direction.java	5 Mar 2003 22:59:37 -0000	1.1
  +++ Direction.java	23 Mar 2003 23:18:30 -0000	1.2
  @@ -111,6 +111,17 @@
   	
   	public static final Direction CUSTOM = new Direction("CUSTOM");
   
  +
  +	/**
  +	 *  Causes a synthetic property to be created that automatically
  +	 *  references and de-references the underlying binding.
  +	 * 
  +	 *  @since 2.4
  +	 * 
  +	 **/
  +	
  +	public static final Direction AUTO = new Direction("AUTO");
  +	
       protected Direction(String name)
       {
           super(name);
  
  
  
  1.4       +3 -2      jakarta-tapestry/framework/src/org/apache/tapestry/param/ParameterManager.java
  
  Index: ParameterManager.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/param/ParameterManager.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- ParameterManager.java	15 Mar 2003 21:22:16 -0000	1.3
  +++ ParameterManager.java	23 Mar 2003 23:18:30 -0000	1.4
  @@ -197,8 +197,9 @@
               }
   
               ParameterSpecification pspec = spec.getParameter(name);
  +            Direction direction = pspec.getDirection();
   
  -            if (pspec.getDirection() == Direction.CUSTOM)
  +            if (direction != Direction.IN && direction != Direction.FORM)
               {
                   if (debug)
                       LOG.debug("Parameter is " + pspec.getDirection().getName() + ".");
  
  
  
  1.2       +7 -9      jakarta-tapestry/framework/src/org/apache/tapestry/parse/Tapestry_1_4.dtd
  
  Index: Tapestry_1_4.dtd
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/parse/Tapestry_1_4.dtd,v
  retrieving revision 1.1
  retrieving revision 1.2
  diff -u -r1.1 -r1.2
  --- Tapestry_1_4.dtd	5 Mar 2003 22:59:28 -0000	1.1
  +++ Tapestry_1_4.dtd	23 Mar 2003 23:18:30 -0000	1.2
  @@ -30,6 +30,7 @@
   - added <property-specification> element
   - renamed java-type to type inside <parameter>
   - allow values to be specified as attributes or wrapped character data in many elements
  +- allow only a single <description> per element
   -->
   
   <!-- =======================================================
  @@ -50,7 +51,7 @@
   -->
   <!ENTITY % static-value-type "(boolean|int|long|double|String) 'String'">
   
  -<!ENTITY % library-content "(description*, property*, (page|component-type|service|library|extension)*)">
  +<!ENTITY % library-content "(description?, property*, (page|component-type|service|library|extension)*)">
   
   <!-- =======================================================
   Element: application
  @@ -100,7 +101,7 @@
   newly instantiated beans, and beans that are retrieved from a pool.
   
   -->
  -<!ELEMENT bean (description*, property*, (set-property | set-string-property)*)>
  +<!ELEMENT bean (description?, property*, (set-property | set-string-property)*)>
   <!ATTLIST bean
     name CDATA #REQUIRED
     class CDATA #REQUIRED
  @@ -204,7 +205,7 @@
       explictily defined) are allowed.
   -->
   <!ELEMENT component-specification 
  -	(description*, parameter*, reserved-parameter*, property*,
  +	(description?, parameter*, reserved-parameter*, property*,
   	(bean |	component | external-asset | context-asset | private-asset | property-specification)*)>
   <!ATTLIST component-specification
     class CDATA #IMPLIED
  @@ -237,12 +238,9 @@
   optional.  The eventual goal is to provide help in some form of IDE.
   Currently, descriptions are optional and ignored.
   
  -Attributes:
  -  xml:lang the language that the description is expressed in.
   -->
   <!ELEMENT description (#PCDATA)>
   <!ATTLIST description
  -  xml:lang NMTOKEN "en"
   >
   
   <!-- =======================================================
  @@ -379,7 +377,7 @@
   Attributes:
     class: The Java class to instantiate for the component.
   -->
  -<!ELEMENT page-specification (description*, property*,
  +<!ELEMENT page-specification (description?, property*,
       (bean | component | external-asset | context-asset | private-asset | property-specification)*)>
   <!ATTLIST page-specification
     class CDATA #IMPLIED
  @@ -401,13 +399,13 @@
     direction: The normal flow of data through the component.
   -->
   
  -<!ELEMENT parameter (description*)>
  +<!ELEMENT parameter (description?)>
   <!ATTLIST parameter
     name CDATA #REQUIRED
     type CDATA #IMPLIED
     required %attribute-flag; "no"
     property-name CDATA #IMPLIED
  -  direction (in|form|custom) "custom"
  +  direction (in|form|custom|auto) "custom"
   >
   
   <!-- =======================================================
  
  
  
  1.4       +2 -1      jakarta-tapestry/framework/src/org/apache/tapestry/parse/SpecificationParser.java
  
  Index: SpecificationParser.java
  ===================================================================
  RCS file: /home/cvs/jakarta-tapestry/framework/src/org/apache/tapestry/parse/SpecificationParser.java,v
  retrieving revision 1.3
  retrieving revision 1.4
  diff -u -r1.3 -r1.4
  --- SpecificationParser.java	23 Mar 2003 01:29:16 -0000	1.3
  +++ SpecificationParser.java	23 Mar 2003 23:18:30 -0000	1.4
  @@ -618,6 +618,7 @@
           CONVERSION_MAP.put("in", Direction.IN);
           CONVERSION_MAP.put("form", Direction.FORM);
           CONVERSION_MAP.put("custom", Direction.CUSTOM);
  +        CONVERSION_MAP.put("auto", Direction.AUTO);
       }
   
       public SpecificationParser(IResourceResolver resolver)
  
  
  

Mime
View raw message