You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2004/11/03 18:28:17 UTC
cvs commit: jakarta-tapestry/eclipse Tapestry-Workbench.launch
hlship 2004/11/03 09:28:16
Modified: framework/src/java/org/apache/tapestry/enhance
EnhancementOperation.java
SpecifiedPropertyWorker.java
ParameterPropertyWorker.java
EnhancementOperationImpl.java EnhanceUtils.java
framework/src/test/org/apache/tapestry/enhance
TestEnhancementOperation.java
framework/src/descriptor/META-INF tapestry.enhance.xml
src/documentation/content/xdocs/UsersGuide state.xml
examples/Workbench/src/context/WEB-INF Chart.page Border.jwc
framework/src/java/org/apache/tapestry/html
ExceptionDisplay.java
framework/src/java/org/apache/tapestry
AbstractComponent.java
eclipse Tapestry-Workbench.launch
Added: framework/src/java/org/apache/tapestry/enhance
AbstractPropertyWorker.java
framework/src/test/org/apache/tapestry/enhance
TestAbstractPropertyWorker.java
Log:
Modify the component enhancers to support creating concrete properties for other-wise unclaimed abstract properties.
Revision Changes Path
1.6 +28 -0 jakarta-tapestry/framework/src/java/org/apache/tapestry/enhance/EnhancementOperation.java
Index: EnhancementOperation.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/enhance/EnhancementOperation.java,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- EnhancementOperation.java 2 Nov 2004 13:30:00 -0000 1.5
+++ EnhancementOperation.java 3 Nov 2004 17:28:16 -0000 1.6
@@ -14,6 +14,9 @@
package org.apache.tapestry.enhance;
+import java.util.List;
+
+import org.apache.hivemind.service.BodyBuilder;
import org.apache.hivemind.service.MethodSignature;
import org.apache.tapestry.spec.IComponentSpecification;
@@ -40,6 +43,13 @@
public void claimProperty(String propertyName);
/**
+ * Returns a list of the names of existing properties that are not claimed and which have
+ * abstract accessor methods.
+ */
+
+ public List findUnclaimedAbstractProperties();
+
+ /**
* Adds a field to the enhanced class; the field will be private and use the provided name and
* type.
*/
@@ -120,4 +130,22 @@
*/
public Class getPropertyType(String name);
+
+ /**
+ * Allows for a kind of distributed construction of a particular method, within a particular
+ * interface. The {@link BodyBuilder}for a given interface method can be obtained and added to.
+ * When the enhanced class is finialized, the method is added with whatever contents are in its
+ * body. If the base class implements the method, then the method body will
+ * include an initial call to that implementation.
+ *
+ * <p>
+ * At this time, this works best for void methods.
+ *
+ * @param interfaceClass the interface containing the method. If the base class does
+ * not implement the interface, then the enhanced class will have the interface
+ * added.
+ * @param methodSignature the signature of the method to be added.
+ * @returns The {@link BodyBuilder} for the specified method.
+ */
+ public BodyBuilder getBodyBuilderForMethod(Class interfaceClass, MethodSignature methodSignature);
}
1.4 +7 -11 jakarta-tapestry/framework/src/java/org/apache/tapestry/enhance/SpecifiedPropertyWorker.java
Index: SpecifiedPropertyWorker.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/enhance/SpecifiedPropertyWorker.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- SpecifiedPropertyWorker.java 3 Nov 2004 13:53:43 -0000 1.3
+++ SpecifiedPropertyWorker.java 3 Nov 2004 17:28:16 -0000 1.4
@@ -87,9 +87,14 @@
// Release 3.0 would squack a bit about overriding non-abstract methods
// if they exist. 3.1 is less picky ... it blindly adds new methods, possibly
// overwriting methods in the base component class.
-
- addAccessor(op, propertyName, propertyType, field);
+
+ EnhanceUtils.createSimpleAccessor(op, field, propertyName, propertyType);
+
addMutator(op, propertyName, propertyType, field, ps.isPersistent());
+
+ // TODO: For properties with no initializer, should use the
+ // same kind of logic as AbstractPropertyWorker (and remove some logic
+ // from PageLoader.
}
// Package private for testing purposes
@@ -108,15 +113,6 @@
Class propertyType = op.getPropertyType(propertyName);
return propertyType == null ? Object.class : propertyType;
- }
-
- private void addAccessor(EnhancementOperation op, String name, Class type, String field)
- {
- String methodName = op.getAccessorMethodName(name);
-
- MethodSignature sig = new MethodSignature(type, methodName, null, null);
-
- op.addMethod(Modifier.PUBLIC, sig, "return " + field + ";");
}
private void addMutator(EnhancementOperation op, String propertyName, Class propertyType,
1.4 +1 -32 jakarta-tapestry/framework/src/java/org/apache/tapestry/enhance/ParameterPropertyWorker.java
Index: ParameterPropertyWorker.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/enhance/ParameterPropertyWorker.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ParameterPropertyWorker.java 2 Nov 2004 18:59:14 -0000 1.3
+++ ParameterPropertyWorker.java 3 Nov 2004 17:28:16 -0000 1.4
@@ -96,38 +96,7 @@
return;
}
- createSimpleParameterProperty(op, propertyName, propertyType);
- }
-
- private void createSimpleParameterProperty(EnhancementOperation op, String propertyName,
- Class propertyType)
- {
- String fieldName = "_$" + propertyName;
-
- op.addField(fieldName, propertyType);
-
- createSimpleAccessor(op, fieldName, propertyName, propertyType);
- createSimpleMutator(op, fieldName, propertyName, propertyType);
- }
-
- private void createSimpleAccessor(EnhancementOperation op, String fieldName,
- String propertyName, Class propertyType)
- {
- String methodName = op.getAccessorMethodName(propertyName);
-
- op.addMethod(
- Modifier.PUBLIC,
- new MethodSignature(propertyType, methodName, null, null),
- "return " + fieldName + ";");
- }
-
- private void createSimpleMutator(EnhancementOperation op, String fieldName,
- String propertyName, Class propertyType)
- {
- String methodName = EnhanceUtils.createMutatorMethodName(propertyName);
-
- op.addMethod(Modifier.PUBLIC, new MethodSignature(void.class, methodName, new Class[]
- { propertyType }, null), fieldName + " = $1;");
+ EnhanceUtils.createSimpleProperty(op, propertyName, propertyType);
}
private void createAutoParameterProperty(EnhancementOperation op, String parameterName,
1.7 +136 -0 jakarta-tapestry/framework/src/java/org/apache/tapestry/enhance/EnhancementOperationImpl.java
Index: EnhancementOperationImpl.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/enhance/EnhancementOperationImpl.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- EnhancementOperationImpl.java 2 Nov 2004 18:59:14 -0000 1.6
+++ EnhancementOperationImpl.java 3 Nov 2004 17:28:16 -0000 1.7
@@ -19,9 +19,12 @@
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -34,6 +37,7 @@
import org.apache.hivemind.service.ClassFab;
import org.apache.hivemind.service.ClassFactory;
import org.apache.hivemind.service.MethodSignature;
+import org.apache.hivemind.util.ToStringBuilder;
import org.apache.tapestry.services.ComponentConstructor;
import org.apache.tapestry.spec.IComponentSpecification;
@@ -65,6 +69,18 @@
private List _constructorArguments = new ArrayList();
/**
+ * Set of interfaces added to the enhanced class.
+ */
+
+ private Set _addedInterfaces = new HashSet();
+
+ /**
+ * Map of {@link BodyBuilder}, keyed on {@link MethodSignature}.
+ */
+
+ private Map _incompleteMethods = new HashMap();
+
+ /**
* Keyed on class to instance variable name.
*/
@@ -98,6 +114,17 @@
introspectBaseClass();
}
+ public String toString()
+ {
+ ToStringBuilder builder = new ToStringBuilder(this);
+
+ builder.append("baseClass", _baseClass.getName());
+ builder.append("claimedProperties", _claimedProperties);
+ builder.append("classFab", _classFab);
+
+ return builder.toString();
+ }
+
private void introspectBaseClass()
{
try
@@ -312,6 +339,8 @@
private void finalizeEnhancedClass()
{
+ finalizeIncompleteMethods();
+
if (_classFab == null)
return;
@@ -326,6 +355,24 @@
}
}
+ private void finalizeIncompleteMethods()
+ {
+ Iterator i = _incompleteMethods.entrySet().iterator();
+ while (i.hasNext())
+ {
+ Map.Entry e = (Map.Entry) i.next();
+ MethodSignature sig = (MethodSignature) e.getKey();
+ BodyBuilder builder = (BodyBuilder) e.getValue();
+
+ // Each BodyBuilder is created and given a begin(), this is
+ // the matching end()
+
+ builder.end();
+
+ classFab().addMethod(Modifier.PUBLIC, sig, builder.toString());
+ }
+ }
+
private Constructor findConstructor()
{
if (_classFab == null)
@@ -372,5 +419,94 @@
int dotx = baseName.lastIndexOf('.');
return "$" + baseName.substring(dotx + 1) + "_" + _uid++;
+ }
+
+ public BodyBuilder getBodyBuilderForMethod(Class interfaceClass, MethodSignature methodSignature)
+ {
+ addInterfaceIfNeeded(interfaceClass);
+
+ BodyBuilder result = (BodyBuilder) _incompleteMethods.get(methodSignature);
+
+ if (result == null)
+ {
+ result = createIncompleteMethod(methodSignature);
+
+ _incompleteMethods.put(methodSignature, result);
+ }
+
+ return result;
+ }
+
+ private void addInterfaceIfNeeded(Class interfaceClass)
+ {
+ if (interfaceClass.isAssignableFrom(_baseClass))
+ return;
+
+ if (_addedInterfaces.contains(interfaceClass))
+ return;
+
+ classFab().addInterface(interfaceClass);
+ _addedInterfaces.add(interfaceClass);
+ }
+
+ private BodyBuilder createIncompleteMethod(MethodSignature sig)
+ {
+ BodyBuilder result = new BodyBuilder();
+
+ // Matched inside finalizeIncompleteMethods()
+
+ result.begin();
+
+ try
+ {
+ Method m = _baseClass.getMethod(sig.getName(), sig.getParameterTypes());
+
+ if (!Modifier.isAbstract(m.getModifiers()))
+ result.addln("super.{0}($$);", sig.getName());
+ }
+ catch (NoSuchMethodException ex)
+ {
+ // Good; no super-implementation to invoke.
+ }
+
+ return result;
+ }
+
+ public List findUnclaimedAbstractProperties()
+ {
+ List result = new ArrayList();
+
+ Iterator i = _properties.values().iterator();
+
+ while (i.hasNext())
+ {
+ PropertyDescriptor pd = (PropertyDescriptor) i.next();
+
+ String name = pd.getName();
+
+ if (_claimedProperties.contains(name))
+ continue;
+
+ if (isAbstractProperty(pd))
+ result.add(name);
+ }
+
+ return result;
+ }
+
+ /**
+ * A property is abstract if either its read method or it write method is abstract. We could do
+ * some additional checking to ensure that both are abstract if either is. Note that in many
+ * cases, there will only be one accessor (a reader or a writer).
+ */
+ private boolean isAbstractProperty(PropertyDescriptor pd)
+ {
+ return isExistingAbstractMethod(pd.getReadMethod())
+ || isExistingAbstractMethod(pd.getWriteMethod());
+ }
+
+ private boolean isExistingAbstractMethod(Method m)
+ {
+ return m != null && Modifier.isAbstract(m.getModifiers());
}
}
1.3 +47 -0 jakarta-tapestry/framework/src/java/org/apache/tapestry/enhance/EnhanceUtils.java
Index: EnhanceUtils.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/enhance/EnhanceUtils.java,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- EnhanceUtils.java 30 Oct 2004 23:37:06 -0000 1.2
+++ EnhanceUtils.java 3 Nov 2004 17:28:16 -0000 1.3
@@ -14,6 +14,14 @@
package org.apache.tapestry.enhance;
+import java.lang.reflect.Modifier;
+
+import org.apache.hivemind.service.MethodSignature;
+import org.apache.tapestry.IRequestCycle;
+import org.apache.tapestry.engine.IPageLoader;
+import org.apache.tapestry.event.PageEvent;
+import org.apache.tapestry.spec.IComponentSpecification;
+
/**
* Convienience methods needed by various parts of the enhancement subsystem.
*
@@ -22,6 +30,14 @@
*/
public class EnhanceUtils
{
+ static MethodSignature FINISH_LOAD_SIGNATURE = new MethodSignature(void.class, "finishLoad",
+ new Class[]
+ { IRequestCycle.class, IPageLoader.class, IComponentSpecification.class }, null);
+
+ static MethodSignature PAGE_DETACHED_SIGNATURE = new MethodSignature(void.class,
+ "pageDetached", new Class[]
+ { PageEvent.class }, null);
+
public static String createMutatorMethodName(String propertyName)
{
return "set" + upcase(propertyName);
@@ -35,5 +51,36 @@
private static String upcase(String name)
{
return name.substring(0, 1).toUpperCase() + name.substring(1);
+ }
+
+ public static void createSimpleAccessor(EnhancementOperation op, String fieldName,
+ String propertyName, Class propertyType)
+ {
+ String methodName = op.getAccessorMethodName(propertyName);
+
+ op.addMethod(
+ Modifier.PUBLIC,
+ new MethodSignature(propertyType, methodName, null, null),
+ "return " + fieldName + ";");
+ }
+
+ public static void createSimpleMutator(EnhancementOperation op, String fieldName,
+ String propertyName, Class propertyType)
+ {
+ String methodName = createMutatorMethodName(propertyName);
+
+ op.addMethod(Modifier.PUBLIC, new MethodSignature(void.class, methodName, new Class[]
+ { propertyType }, null), fieldName + " = $1;");
+ }
+
+ public static void createSimpleProperty(EnhancementOperation op, String propertyName,
+ Class propertyType)
+ {
+ String fieldName = "_$" + propertyName;
+
+ op.addField(fieldName, propertyType);
+
+ createSimpleAccessor(op, fieldName, propertyName, propertyType);
+ createSimpleMutator(op, fieldName, propertyName, propertyType);
}
}
1.1 jakarta-tapestry/framework/src/java/org/apache/tapestry/enhance/AbstractPropertyWorker.java
Index: AbstractPropertyWorker.java
===================================================================
// Copyright 2004 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.enhance;
import java.util.Iterator;
import org.apache.hivemind.ErrorLog;
import org.apache.hivemind.service.BodyBuilder;
import org.apache.tapestry.IComponent;
import org.apache.tapestry.event.PageDetachListener;
/**
* No, this class isn't abstract ... this worker locates abstract properties in the base component
* class and provides a concrete implementation for them in the enhanced class.
*
* @author Howard M. Lewis Ship
* @since 3.1
*/
public class AbstractPropertyWorker implements EnhancementWorker
{
private ErrorLog _errorLog;
public void performEnhancement(EnhancementOperation op)
{
Iterator i = op.findUnclaimedAbstractProperties().iterator();
while (i.hasNext())
{
String name = (String) i.next();
try
{
createProperty(op, name);
}
catch (Exception ex)
{
_errorLog.error(
EnhanceMessages.errorAddingProperty(name, op.getBaseClass(), ex),
op.getSpecification().getLocation(),
ex);
}
}
}
private void createProperty(EnhancementOperation op, String name)
{
// This won't be null because its always for existing properties.
Class propertyType = op.getPropertyType(name);
String fieldName = "_$" + name;
String defaultFieldName = fieldName + "$defaultValue";
op.addField(fieldName, propertyType);
op.addField(defaultFieldName, propertyType);
EnhanceUtils.createSimpleAccessor(op, fieldName, name, propertyType);
EnhanceUtils.createSimpleMutator(op, fieldName, name, propertyType);
BodyBuilder finishLoadBody = op.getBodyBuilderForMethod(
IComponent.class,
EnhanceUtils.FINISH_LOAD_SIGNATURE);
// Inside finish load, "snapshot" the value of the real field
finishLoadBody.addln("{0} = {1};", defaultFieldName, fieldName);
// When detaching the page, overwrite the field value with
// the snapshot.
BodyBuilder pageDetachedBody = op.getBodyBuilderForMethod(
PageDetachListener.class,
EnhanceUtils.PAGE_DETACHED_SIGNATURE);
pageDetachedBody.addln("{0} = {1};", fieldName, defaultFieldName);
// This is not all that necessary, but is proper.
op.claimProperty(name);
}
public void setErrorLog(ErrorLog errorLog)
{
_errorLog = errorLog;
}
}
1.5 +204 -0 jakarta-tapestry/framework/src/test/org/apache/tapestry/enhance/TestEnhancementOperation.java
Index: TestEnhancementOperation.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/test/org/apache/tapestry/enhance/TestEnhancementOperation.java,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- TestEnhancementOperation.java 2 Nov 2004 13:30:00 -0000 1.4
+++ TestEnhancementOperation.java 3 Nov 2004 17:28:16 -0000 1.5
@@ -20,16 +20,20 @@
import java.util.Set;
import org.apache.hivemind.ApplicationRuntimeException;
+import org.apache.hivemind.ClassResolver;
import org.apache.hivemind.Location;
import org.apache.hivemind.impl.DefaultClassResolver;
+import org.apache.hivemind.service.BodyBuilder;
import org.apache.hivemind.service.ClassFab;
import org.apache.hivemind.service.ClassFactory;
import org.apache.hivemind.service.MethodSignature;
import org.apache.hivemind.service.impl.ClassFactoryImpl;
import org.apache.hivemind.test.HiveMindTestCase;
import org.apache.tapestry.BaseComponent;
+import org.apache.tapestry.IComponent;
import org.apache.tapestry.IPage;
import org.apache.tapestry.components.Insert;
+import org.apache.tapestry.event.PageDetachListener;
import org.apache.tapestry.services.ComponentConstructor;
import org.apache.tapestry.spec.IComponentSpecification;
import org.easymock.MockControl;
@@ -71,6 +75,23 @@
}
}
+ public abstract static class UnclaimedAbstractPropertiesFixture
+ {
+ public abstract String getReadOnly();
+
+ public abstract void setWriteOnly(String value);
+
+ public void setConcrete(int i)
+ {
+ //
+ }
+
+ public int getConcrete()
+ {
+ return -1;
+ }
+ }
+
public void testClaimedProperty()
{
EnhancementOperationImpl eo = new EnhancementOperationImpl();
@@ -416,6 +437,189 @@
BaseComponent.class, cf);
eo.forceEnhancement();
+
+ verifyControls();
+ }
+
+ public void testFindUnclaimedAbstractProperties()
+ {
+ ClassResolver cr = (ClassResolver) newMock(ClassResolver.class);
+ IComponentSpecification spec = (IComponentSpecification) newMock(IComponentSpecification.class);
+ ClassFactory cf = (ClassFactory) newMock(ClassFactory.class);
+
+ replayControls();
+
+ EnhancementOperation eo = new EnhancementOperationImpl(cr, spec,
+ UnclaimedAbstractPropertiesFixture.class, cf);
+
+ List l = eo.findUnclaimedAbstractProperties();
+
+ assertEquals(2, l.size());
+ assertEquals(true, l.contains("readOnly"));
+ assertEquals(true, l.contains("writeOnly"));
+
+ eo.claimProperty("readOnly");
+
+ l = eo.findUnclaimedAbstractProperties();
+
+ assertEquals(1, l.size());
+ assertEquals(true, l.contains("writeOnly"));
+
+ eo.claimProperty("writeOnly");
+
+ l = eo.findUnclaimedAbstractProperties();
+
+ assertEquals(true, l.isEmpty());
+
+ verifyControls();
+ }
+
+ public void testGetNewMethod()
+ {
+ ClassResolver cr = new DefaultClassResolver();
+ MockControl specc = newControl(IComponentSpecification.class);
+ IComponentSpecification spec = (IComponentSpecification) specc.getMock();
+
+ MockControl cfc = newControl(ClassFactory.class);
+ ClassFactory cf = (ClassFactory) cfc.getMock();
+ MockControl fabc = newControl(ClassFab.class);
+ ClassFab fab = (ClassFab) fabc.getMock();
+
+ fab.addInterface(PageDetachListener.class);
+
+ cf.newClass("$BaseComponent_97", BaseComponent.class, cr.getClassLoader());
+ cfc.setReturnValue(fab);
+
+ replayControls();
+
+ EnhancementOperationImpl eo = new EnhancementOperationImpl(cr, spec, BaseComponent.class,
+ cf);
+
+ MethodSignature sig = EnhanceUtils.PAGE_DETACHED_SIGNATURE;
+
+ BodyBuilder b = eo.getBodyBuilderForMethod(PageDetachListener.class, sig);
+
+ assertEquals("{\n", b.toString());
+
+ verifyControls();
+
+ replayControls();
+
+ // Check that repeated calls return the same body builder and do not
+ // keep adding methods.
+
+ assertSame(b, eo.getBodyBuilderForMethod(PageDetachListener.class, sig));
+
+ verifyControls();
+
+ fab.addMethod(Modifier.PUBLIC, sig, "{\n}\n");
+ fabc.setReturnValue(null);
+
+ fab.createClass();
+ fabc.setReturnValue(BaseComponent.class);
+
+ spec.getLocation();
+ specc.setReturnValue(null);
+
+ replayControls();
+
+ eo.getConstructor();
+
+ assertEquals("{\n}\n", b.toString());
+
+ verifyControls();
+ }
+
+ public void testGetExistingMethod()
+ {
+ ClassResolver cr = new DefaultClassResolver();
+ MockControl specc = newControl(IComponentSpecification.class);
+ IComponentSpecification spec = (IComponentSpecification) specc.getMock();
+
+ MockControl cfc = newControl(ClassFactory.class);
+ ClassFactory cf = (ClassFactory) cfc.getMock();
+ MockControl fabc = newControl(ClassFab.class);
+ ClassFab fab = (ClassFab) fabc.getMock();
+
+ replayControls();
+
+ EnhancementOperationImpl eo = new EnhancementOperationImpl(cr, spec, BaseComponent.class,
+ cf);
+
+ MethodSignature sig = EnhanceUtils.FINISH_LOAD_SIGNATURE;
+
+ BodyBuilder b = eo.getBodyBuilderForMethod(IComponent.class, sig);
+
+ assertEquals("{\n super.finishLoad($$);\n", b.toString());
+
+ verifyControls();
+
+ cf.newClass("$BaseComponent_97", BaseComponent.class, cr.getClassLoader());
+ cfc.setReturnValue(fab);
+
+ fab.addMethod(Modifier.PUBLIC, sig, "{\n super.finishLoad($$);\n}\n");
+ fabc.setReturnValue(null);
+
+ fab.createClass();
+ fabc.setReturnValue(BaseComponent.class);
+
+ spec.getLocation();
+ specc.setReturnValue(null);
+
+ replayControls();
+
+ eo.getConstructor();
+
+ verifyControls();
+ }
+
+ public static abstract class ExistingAbstractMethodFixture extends BaseComponent implements
+ PageDetachListener
+ {
+ }
+
+ public void getExistingAbstractMethod()
+ {
+ ClassResolver cr = new DefaultClassResolver();
+ MockControl specc = newControl(IComponentSpecification.class);
+ IComponentSpecification spec = (IComponentSpecification) specc.getMock();
+
+ MockControl cfc = newControl(ClassFactory.class);
+ ClassFactory cf = (ClassFactory) cfc.getMock();
+ MockControl fabc = newControl(ClassFab.class);
+ ClassFab fab = (ClassFab) fabc.getMock();
+
+ replayControls();
+
+ EnhancementOperationImpl eo = new EnhancementOperationImpl(cr, spec,
+ ExistingAbstractMethodFixture.class, cf);
+
+ MethodSignature sig = EnhanceUtils.PAGE_DETACHED_SIGNATURE;
+
+ BodyBuilder b = eo.getBodyBuilderForMethod(PageDetachListener.class, sig);
+
+ assertEquals("{\n", b.toString());
+
+ verifyControls();
+
+ cf.newClass("$ExitingAbstractMethodFixture_97", ExistingAbstractMethodFixture.class, cr
+ .getClassLoader());
+ cfc.setReturnValue(fab);
+
+ fab.addMethod(Modifier.PUBLIC, sig, "{\n}\n");
+ fabc.setReturnValue(null);
+
+ fab.createClass();
+ fabc.setReturnValue(BaseComponent.class);
+
+ spec.getLocation();
+ specc.setReturnValue(null);
+
+ replayControls();
+
+ eo.getConstructor();
+
+ assertEquals("{\n}\n", b.toString());
verifyControls();
}
1.1 jakarta-tapestry/framework/src/test/org/apache/tapestry/enhance/TestAbstractPropertyWorker.java
Index: TestAbstractPropertyWorker.java
===================================================================
// Copyright 2004 The Apache Software Foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package org.apache.tapestry.enhance;
import java.lang.reflect.Modifier;
import java.util.Collections;
import org.apache.hivemind.ApplicationRuntimeException;
import org.apache.hivemind.ErrorLog;
import org.apache.hivemind.Location;
import org.apache.hivemind.service.BodyBuilder;
import org.apache.hivemind.service.MethodSignature;
import org.apache.hivemind.test.HiveMindTestCase;
import org.apache.tapestry.BaseComponent;
import org.apache.tapestry.IComponent;
import org.apache.tapestry.event.PageDetachListener;
import org.apache.tapestry.spec.IComponentSpecification;
import org.easymock.MockControl;
/**
* Tests {@link org.apache.tapestry.enhance.AbstractPropertyWorker}.
*
* @author Howard M. Lewis Ship
* @since 3.1
*/
public class TestAbstractPropertyWorker extends HiveMindTestCase
{
public void testSuccess()
{
MockControl opc = newControl(EnhancementOperation.class);
EnhancementOperation op = (EnhancementOperation) opc.getMock();
BodyBuilder finishLoadBody = new BodyBuilder();
BodyBuilder pageDetachedBody = new BodyBuilder();
op.findUnclaimedAbstractProperties();
opc.setReturnValue(Collections.singletonList("fred"));
op.getPropertyType("fred");
opc.setReturnValue(String.class);
op.addField("_$fred", String.class);
op.addField("_$fred$defaultValue", String.class);
op.getAccessorMethodName("fred");
opc.setReturnValue("getFred");
op.addMethod(
Modifier.PUBLIC,
new MethodSignature(String.class, "getFred", null, null),
"return _$fred;");
op.addMethod(Modifier.PUBLIC, new MethodSignature(void.class, "setFred", new Class[]
{ String.class }, null), "_$fred = $1;");
op.getBodyBuilderForMethod(IComponent.class, EnhanceUtils.FINISH_LOAD_SIGNATURE);
opc.setReturnValue(finishLoadBody);
op.getBodyBuilderForMethod(PageDetachListener.class, EnhanceUtils.PAGE_DETACHED_SIGNATURE);
opc.setReturnValue(pageDetachedBody);
op.claimProperty("fred");
replayControls();
new AbstractPropertyWorker().performEnhancement(op);
assertEquals("_$fred$defaultValue = _$fred;\n", finishLoadBody.toString());
assertEquals("_$fred = _$fred$defaultValue;\n", pageDetachedBody.toString());
verifyControls();
}
public void testFailure()
{
MockControl opc = newControl(EnhancementOperation.class);
EnhancementOperation op = (EnhancementOperation) opc.getMock();
MockControl specc = newControl(IComponentSpecification.class);
IComponentSpecification spec = (IComponentSpecification) specc.getMock();
Location l = fabricateLocation(21);
ErrorLog log = (ErrorLog) newMock(ErrorLog.class);
op.findUnclaimedAbstractProperties();
opc.setReturnValue(Collections.singletonList("fred"));
Throwable ex = new ApplicationRuntimeException("Arbitrary error.");
op.getPropertyType("fred");
opc.setThrowable(ex);
op.getBaseClass();
opc.setReturnValue(BaseComponent.class);
op.getSpecification();
opc.setReturnValue(spec);
spec.getLocation();
specc.setReturnValue(l);
log.error(EnhanceMessages.errorAddingProperty("fred", BaseComponent.class, ex), l, ex);
replayControls();
AbstractPropertyWorker w = new AbstractPropertyWorker();
w.setErrorLog(log);
w.performEnhancement(op);
verifyControls();
}
}
1.4 +18 -3 jakarta-tapestry/framework/src/descriptor/META-INF/tapestry.enhance.xml
Index: tapestry.enhance.xml
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/descriptor/META-INF/tapestry.enhance.xml,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- tapestry.enhance.xml 2 Nov 2004 03:32:42 -0000 1.3
+++ tapestry.enhance.xml 3 Nov 2004 17:28:16 -0000 1.4
@@ -75,9 +75,14 @@
<!-- These can actually run in any order, so we don't specify before or after. -->
- <worker id="specified-property" object="service:SpecifiedPropertyWorker"/>
- <worker id="parameter" object="service:ParameterPropertyWorker"/>
- <worker id="inject" object="service:InjectWorker"/>
+ <worker id="specified-property" object="service:SpecifiedPropertyWorker" before="abstract-property"/>
+ <worker id="parameter" object="service:ParameterPropertyWorker" before="abstract-property"/>
+ <worker id="inject" object="service:InjectWorker" before="abstract-property"/>
+
+ <!-- This should be second to last, or at least, after all other workers have
+ added and claimed any properties they are going to. -->
+
+ <worker id="abstract-property" object="service:AbstractPropertyWorker"/>
<!-- This needs to be absolutely last -->
@@ -114,6 +119,16 @@
</construct>
</invoke-factory>
+ </service-point>
+
+ <service-point id="AbstractPropertyWorker" interface="org.apache.tapestry.enhance.EnhancementWorker">
+
+ Finds otherwise unclaimed abstract properties and converts them into concrete properties, as if
+ they were defined in the specification.
+
+ <invoke-factory>
+ <construct class="org.apache.tapestry.enhance.AbstractPropertyWorker"/>
+ </invoke-factory>
</service-point>
</module>
1.5 +6 -5 jakarta-tapestry/src/documentation/content/xdocs/UsersGuide/state.xml
Index: state.xml
===================================================================
RCS file: /home/cvs/jakarta-tapestry/src/documentation/content/xdocs/UsersGuide/state.xml,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- state.xml 3 Nov 2004 13:53:43 -0000 1.4
+++ state.xml 3 Nov 2004 17:28:16 -0000 1.5
@@ -397,11 +397,12 @@
</note>
<note>
-Properties defined this way may be either transient or persistent. It is useful to define
-even transient
-properties using the &spec.property; element because doing so ensures that
-the property will be properly reset at the end of the request (before the page
-is returned to the pool for later reuse).
+Properties defined this way may be either transient or persistent. For transient properties (properties
+which do not persist between requests), it is only necessary to specify the property
+if it has an initial value. Tapestry scans the component class looking for abstract properties that don't
+match up against component parameters or &spec.property; elements; for each of these unclaimed properties,
+a concrete property is created. The property is a transient property, as if a &spec.property; element <em>did</em>
+exist for it.
</note>
<p>
1.2 +20 -20 jakarta-tapestry/examples/Workbench/src/context/WEB-INF/Chart.page
Index: Chart.page
===================================================================
RCS file: /home/cvs/jakarta-tapestry/examples/Workbench/src/context/WEB-INF/Chart.page,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Chart.page 28 Oct 2004 22:24:46 -0000 1.1
+++ Chart.page 3 Nov 2004 17:28:16 -0000 1.2
@@ -15,8 +15,8 @@
limitations under the License.
-->
<!DOCTYPE page-specification PUBLIC
- "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
+ "-//Apache Software Foundation//Tapestry Specification 3.1//EN"
+ "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_1.dtd">
<page-specification class="org.apache.tapestry.workbench.chart.ChartPage">
@@ -32,45 +32,45 @@
</bean>
<component id="showError" type="ShowError">
- <binding name="delegate" expression="beans.delegate"/>
+ <binding name="delegate" value="ognl:beans.delegate"/>
</component>
<component id="form" type="Form">
- <binding name="listener" expression="listeners.submit"/>
- <binding name="delegate" expression="beans.delegate"/>
+ <binding name="listener" value="ognl:listeners.submit"/>
+ <binding name="delegate" value="ognl:beans.delegate"/>
</component>
<component id="plotValues" type="Foreach">
- <binding name="source" expression="plotValues"/>
- <binding name="value" expression="plotValue"/>
- <static-binding name="element" value="tr"/>
+ <binding name="source" value="ognl:plotValues"/>
+ <binding name="value" value="ognl:plotValue"/>
+ <binding name="element" value="tr"/>
</component>
<component id="inputName" type="ValidField">
- <static-binding name="displayName" value="Name"/>
- <binding name="value" expression="plotValue.name"/>
- <binding name="validator" expression="beans.required"/>
+ <binding name="displayName" value="Name"/>
+ <binding name="value" value="ognl:plotValue.name"/>
+ <binding name="validator" value="ognl:beans.required"/>
</component>
<component id="inputValue" type="ValidField">
- <static-binding name="displayName" value="Value"/>
- <binding name="value" expression="plotValue.value"/>
- <binding name="validator" expression="beans.intValidator"/>
- <static-binding name="type" value="int"/>
+ <binding name="displayName" value="Value"/>
+ <binding name="value" value="ognl:plotValue.value"/>
+ <binding name="validator" value="ognl:beans.intValidator"/>
+ <binding name="type" value="int"/>
</component>
<component id="inputMarked" type="Checkbox">
- <binding name="selected" expression="markedForDeletion"/>
+ <binding name="selected" value="ognl:markedForDeletion"/>
</component>
<component id="add" type="Submit">
- <binding name="listener" expression="listeners.add"/>
- <static-binding name="label" value="Update and Add"/>
+ <binding name="listener" value="ognl:listeners.add"/>
+ <binding name="label" value="Update and Add"/>
</component>
<component id="delete" type="Submit">
- <binding name="listener" expression="listeners.delete"/>
- <static-binding name="label" value="Delete Selected"/>
+ <binding name="listener" value="ognl:listeners.delete"/>
+ <binding name="label" value="Delete Selected"/>
</component>
</page-specification>
1.2 +13 -16 jakarta-tapestry/examples/Workbench/src/context/WEB-INF/Border.jwc
Index: Border.jwc
===================================================================
RCS file: /home/cvs/jakarta-tapestry/examples/Workbench/src/context/WEB-INF/Border.jwc,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- Border.jwc 28 Oct 2004 22:24:46 -0000 1.1
+++ Border.jwc 3 Nov 2004 17:28:16 -0000 1.2
@@ -15,40 +15,37 @@
limitations under the License.
-->
<!DOCTYPE component-specification PUBLIC
- "-//Apache Software Foundation//Tapestry Specification 3.0//EN"
- "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_0.dtd">
+ "-//Apache Software Foundation//Tapestry Specification 3.1//EN"
+ "http://jakarta.apache.org/tapestry/dtd/Tapestry_3_1.dtd">
<component-specification
class="org.apache.tapestry.workbench.components.Border"
allow-informal-parameters="no">
- <property-specification name="pageName" type="java.lang.String"/>
- <property-specification name="activePageName" type="java.lang.String"/>
-
<component id="tabCell" type="Any">
- <static-binding name="element" value="td"/>
- <binding name="background" expression="midTabAsset"/>
+ <binding name="element" value="td"/>
+ <binding name="background" value="ognl:midTabAsset"/>
</component>
<component id="pageLink" type="DirectLink">
- <binding name="listener" expression="listeners.selectPage"/>
- <binding name="parameters" expression="pageName"/>
- <binding name="stateful" expression="false"/>
+ <binding name="listener" value="ognl:listeners.selectPage"/>
+ <binding name="parameters" value="ognl:pageName"/>
+ <binding name="stateful" value="ognl:false"/>
</component>
<component id="inputRequestDebug" type="Checkbox">
- <binding name="selected" expression="page.visit.requestDebug"/>
- <static-binding name="onclick">
+ <binding name="selected" value="ognl:page.visit.requestDebug"/>
+ <binding name="onclick">
javascript:this.form.submit();
- </static-binding>
+ </binding>
</component>
<component id="inputDisableInspector" type="Checkbox">
- <binding name="selected" expression="page.visit.disableInspector"/>
- <static-binding name="onclick">
+ <binding name="selected" value="ognl:page.visit.disableInspector"/>
+ <binding name="onclick">
javascript:this.form.submit();
- </static-binding>
+ </binding>
</component>
<context-asset name="activeLeft" path="images/tab-active-left.gif"/>
1.4 +11 -14 jakarta-tapestry/framework/src/java/org/apache/tapestry/html/ExceptionDisplay.java
Index: ExceptionDisplay.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/html/ExceptionDisplay.java,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- ExceptionDisplay.java 31 Oct 2004 22:57:46 -0000 1.3
+++ ExceptionDisplay.java 3 Nov 2004 17:28:16 -0000 1.4
@@ -15,7 +15,6 @@
package org.apache.tapestry.html;
import org.apache.tapestry.BaseComponent;
-import org.apache.tapestry.IBinding;
import org.apache.tapestry.IMarkupWriter;
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.bean.EvenOdd;
@@ -28,15 +27,19 @@
* @author Howard Lewis Ship
*/
-public class ExceptionDisplay extends BaseComponent
+public abstract class ExceptionDisplay extends BaseComponent
{
+ public abstract ExceptionDescription[] getExceptions();
+
private ExceptionDescription _exception;
- private int _count;
+ private EvenOdd _evenOdd;
+
+ public abstract int getIndex();
- private int _index;
+ public abstract int getCount();
- private EvenOdd _evenOdd;
+ public abstract void setCount(int count);
/**
* Each time the current exception is set, as a side effect, the evenOdd helper bean is reset to
@@ -57,10 +60,9 @@
protected void renderComponent(IMarkupWriter writer, IRequestCycle cycle)
{
- ExceptionDescription[] exceptions = (ExceptionDescription[]) getBinding("exceptions")
- .getObject("exceptions", ExceptionDescription[].class);
+ ExceptionDescription[] exceptions = getExceptions();
- _count = exceptions.length;
+ setCount(exceptions.length);
try
{
@@ -75,13 +77,8 @@
}
}
- public void setIndex(int value)
- {
- _index = value;
- }
-
public boolean isLast()
{
- return _index == (_count - 1);
+ return getIndex() == (getCount() - 1);
}
}
1.8 +2 -2 jakarta-tapestry/framework/src/java/org/apache/tapestry/AbstractComponent.java
Index: AbstractComponent.java
===================================================================
RCS file: /home/cvs/jakarta-tapestry/framework/src/java/org/apache/tapestry/AbstractComponent.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- AbstractComponent.java 2 Nov 2004 18:59:14 -0000 1.7
+++ AbstractComponent.java 3 Nov 2004 17:28:16 -0000 1.8
@@ -236,8 +236,8 @@
/**
* Registers this component as a listener of the page if it implements
- * {@link org.apache.tapestry.event.PageDetachListener}or
- * {@link org.apache.tapestry.event.PageRenderListener}.
+ * {@link org.apache.tapestry.event.PageDetachListener},
+ * {@link org.apache.tapestry.event.PageRenderListener}or {@link PageValidateListener}.
* <p>
* Invokes {@link #finishLoad()}. Subclasses may overide as needed, but must invoke this
* implementation. {@link BaseComponent}loads its HTML template.
1.17 +10 -32 jakarta-tapestry/eclipse/Tapestry-Workbench.launch
Index: Tapestry-Workbench.launch
===================================================================
RCS file: /home/cvs/jakarta-tapestry/eclipse/Tapestry-Workbench.launch,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- Tapestry-Workbench.launch 12 Oct 2004 12:42:34 -0000 1.16
+++ Tapestry-Workbench.launch 3 Nov 2004 17:28:16 -0000 1.17
@@ -3,7 +3,6 @@
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="false"/>
<stringAttribute key="org.eclipse.jdt.launching.MAIN_TYPE" value="org.mortbay.jetty.Server"/>
<stringAttribute key="org.eclipse.jdt.launching.PROGRAM_ARGUMENTS" value="jetty.xml"/>
-<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dorg.apache.tapestry.disable-caching=true"/>
<listAttribute key="org.eclipse.jdt.launching.SOURCE_PATH">
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry containerPath="JRE_LIB" path="2" sourceAttachmentPath="JRE_SRC" sourceRootPath="JRE_SRCROOT" type="3"/> "/>
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/jakarta-tapestry/config" path="3" type="2"/> "/>
@@ -33,44 +32,23 @@
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry containerPath="JDK_DIR/lib/tools.jar" path="3" type="3"/> "/>
<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry containerPath="JETTY_DIR/ext/ant.jar" path="3" type="3"/> "/>
</listAttribute>
+<stringAttribute key="org.eclipse.jdt.launching.VM_ARGUMENTS" value="-Dorg.apache.tapestry.disable-caching=true"/>
<listAttribute key="org.eclipse.debug.ui.favoriteGroups">
<listEntry value="org.eclipse.debug.ui.launchGroup.run"/>
<listEntry value="org.eclipse.debug.ui.launchGroup.debug"/>
</listAttribute>
-<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
<stringAttribute key="org.eclipse.jdt.launching.WORKING_DIRECTORY" value="jakarta-tapestry/examples/Workbench"/>
-<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_SOURCE_PATH" value="false"/>
+<booleanAttribute key="org.eclipse.debug.core.appendEnvironmentVariables" value="true"/>
<stringAttribute key="org.eclipse.debug.ui.target_run_perspective" value="perspective_default"/>
+<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_SOURCE_PATH" value="false"/>
+<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="jakarta-tapestry"/>
<listAttribute key="org.eclipse.jdt.launching.CLASSPATH">
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry containerPath="JRE_LIB" path="2" sourceAttachmentPath="JRE_SRC" sourceRootPath="JRE_SRCROOT" type="3"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/jakarta-tapestry/config" path="3" type="2"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry path="3" projectName="jakarta-tapestry" type="1"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/jakarta-tapestry/lib/ext/jakarta-oro-2.0.6.jar" path="3" type="2"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/jakarta-tapestry/lib/ext/commons-logging-1.0.2.jar" path="3" type="2"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry containerPath="JBOSS_DIR/client/jboss-j2ee.jar" path="3" type="3"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry containerPath="JBOSS_DIR/server/all/lib/mail.jar" path="3" type="3"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/jakarta-tapestry/lib/ext/commons-lang-1.0.jar" path="3" type="2"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/jakarta-tapestry/lib/ext/ognl-2.6.3.jar" path="3" type="2"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/jakarta-tapestry/lib/ext/bsf-2.3.0.jar" path="3" type="2"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry containerPath="JETTY_DIR/lib/javax.servlet.jar" path="3" type="3"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry containerPath="JETTY_DIR/ext/javax.xml.jaxp.jar" path="3" type="3"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry containerPath="JETTY_DIR/ext/crimson.jar" path="3" type="3"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/jakarta-tapestry/ext-dist/jdom-b8.jar" path="3" type="2"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/jakarta-tapestry/ext-dist/junit.jar" path="3" type="2"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/jakarta-tapestry/lib/ext/commons-beanutils-1.6.1.jar" path="3" type="2"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/jakarta-tapestry/lib/ext/commons-digester-1.5.jar" path="3" type="2"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/jakarta-tapestry/examples/Workbench/lib/jCharts-0.6.0.jar" path="3" type="2"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/jakarta-tapestry/lib/ext/commons-collections-2.1.jar" path="3" type="2"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/jakarta-tapestry/lib/runtime/log4j-1.2.6.jar" path="3" type="2"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry containerPath="JETTY_DIR/lib/org.mortbay.jetty-jdk1.2.jar" path="3" type="3"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry containerPath="JETTY_DIR/ext/jasper-compiler.jar" path="3" type="3"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry containerPath="JETTY_DIR/ext/jasper-runtime.jar" path="3" type="3"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry containerPath="JETTY_DIR/ext/ant.jar" path="3" type="3"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry containerPath="JDK_DIR/lib/tools.jar" path="3" type="3"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/jakarta-tapestry/lib/ext/commons-fileupload-1.0.jar" path="3" type="2"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/jakarta-tapestry/lib/ext/javassist-2.5.1.jar" path="3" type="2"/> "/>
-<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry internalArchive="/jakarta-tapestry/lib/ext/commons-codec-1.2.jar" path="3" type="2"/> "/>
+<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry type="3" path="1" containerPath="JRE_LIB"/> "/>
+<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry id="org.eclipse.jdt.launching.classpathentry.defaultClasspath"> <memento project="jakarta-tapestry"/> </runtimeClasspathEntry> "/>
+<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry type="3" path="3" containerPath="JETTY_DIR/lib/javax.servlet.jar"/> "/>
+<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry type="3" path="3" containerPath="JETTY_DIR/lib/org.mortbay.jetty.jar"/> "/>
+<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry type="3" path="3" containerPath="JETTY_DIR/lib/org.mortbay.jetty-jdk1.2.jar"/> "/>
+<listEntry value="<?xml version="1.0" encoding="UTF-8"?> <runtimeClasspathEntry type="3" path="3" containerPath="JETTY_DIR/lib/org.mortbay.jmx.jar"/> "/>
</listAttribute>
-<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="jakarta-tapestry"/>
<stringAttribute key="org.eclipse.debug.ui.target_debug_perspective" value="perspective_default"/>
</launchConfiguration>
---------------------------------------------------------------------
To unsubscribe, e-mail: tapestry-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tapestry-dev-help@jakarta.apache.org