You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tapestry.apache.org by hl...@apache.org on 2007/12/05 20:25:27 UTC

svn commit: r601475 - in /tapestry/tapestry5/trunk/tapestry-core/src: main/java/org/apache/tapestry/internal/ main/java/org/apache/tapestry/internal/services/ main/resources/org/apache/tapestry/internal/services/ site/apt/guide/ test/java/org/apache/ta...

Author: hlship
Date: Wed Dec  5 11:25:26 2007
New Revision: 601475

URL: http://svn.apache.org/viewvc?rev=601475&view=rev
Log:
TAPESTRY-1934: Tapestry should enforce that component classes only extend from other (transformed) component classes, or java.lang.Object

Added:
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/WrongPackageForBaseClass.java
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InvalidSuperClass.java
Modified:
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalConstants.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassResolverImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformerImpl.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java
    tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties
    tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/component-classes.apt
    tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalConstants.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalConstants.java?rev=601475&r1=601474&r2=601475&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalConstants.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/InternalConstants.java Wed Dec  5 11:25:26 2007
@@ -50,6 +50,11 @@
 
     public static final String OBJECT_RENDER_DIV_SECTION = "t-env-data-section";
 
+    public static final String MIXINS_SUBPACKAGE = "mixins";
+    public static final String COMPONENTS_SUBPACKAGE = "components";
+    public static final String PAGES_SUBPACKAGE = "pages";
+    public static final String BASE_SUBPACKAGE = "base";
+
     private InternalConstants()
     {
     }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassResolverImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassResolverImpl.java?rev=601475&r1=601474&r2=601475&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassResolverImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassResolverImpl.java Wed Dec  5 11:25:26 2007
@@ -33,12 +33,6 @@
 {
     private static final String CORE_LIBRARY_PREFIX = "core/";
 
-    private static final String MIXINS_SUBPACKAGE = "mixins";
-
-    private static final String COMPONENTS_SUBPACKAGE = "components";
-
-    private static final String PAGES_SUBPACKAGE = "pages";
-
     private final Logger _logger;
 
     private final ComponentInstantiatorSource _componentInstantiatorSource;
@@ -138,10 +132,10 @@
 
     private void addPackagesToInstantiatorSource(String rootPackage)
     {
-        _componentInstantiatorSource.addPackage(rootPackage + ".pages");
-        _componentInstantiatorSource.addPackage(rootPackage + ".components");
-        _componentInstantiatorSource.addPackage(rootPackage + ".mixins");
-        _componentInstantiatorSource.addPackage(rootPackage + ".base");
+        _componentInstantiatorSource.addPackage(rootPackage + "." + InternalConstants.PAGES_SUBPACKAGE);
+        _componentInstantiatorSource.addPackage(rootPackage + "." + InternalConstants.COMPONENTS_SUBPACKAGE);
+        _componentInstantiatorSource.addPackage(rootPackage + "." + InternalConstants.MIXINS_SUBPACKAGE);
+        _componentInstantiatorSource.addPackage(rootPackage + "." + InternalConstants.BASE_SUBPACKAGE);
     }
 
     /**
@@ -268,16 +262,16 @@
 
     private void rebuild(String pathPrefix, String rootPackage)
     {
-        fillNameToClassNameMap(pathPrefix, rootPackage, PAGES_SUBPACKAGE, _pageToClassName);
-        fillNameToClassNameMap(pathPrefix, rootPackage, COMPONENTS_SUBPACKAGE, _componentToClassName);
-        fillNameToClassNameMap(pathPrefix, rootPackage, MIXINS_SUBPACKAGE, _mixinToClassName);
+        fillNameToClassNameMap(pathPrefix, rootPackage, InternalConstants.PAGES_SUBPACKAGE, _pageToClassName);
+        fillNameToClassNameMap(pathPrefix, rootPackage, InternalConstants.COMPONENTS_SUBPACKAGE, _componentToClassName);
+        fillNameToClassNameMap(pathPrefix, rootPackage, InternalConstants.MIXINS_SUBPACKAGE, _mixinToClassName);
     }
 
     private void fillNameToClassNameMap(String pathPrefix, String rootPackage, String subPackage,
                                         Map<String, String> logicalNameToClassName)
     {
         String searchPackage = rootPackage + "." + subPackage;
-        boolean isPage = subPackage.equals(PAGES_SUBPACKAGE);
+        boolean isPage = subPackage.equals(InternalConstants.PAGES_SUBPACKAGE);
 
         Collection<String> classNames = _classNameLocator.locateClassNames(searchPackage);
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformerImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformerImpl.java?rev=601475&r1=601474&r2=601475&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformerImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ComponentClassTransformerImpl.java Wed Dec  5 11:25:26 2007
@@ -17,6 +17,7 @@
 import javassist.CtClass;
 import javassist.CtConstructor;
 import javassist.NotFoundException;
+import org.apache.tapestry.internal.InternalConstants;
 import org.apache.tapestry.internal.events.InvalidationListener;
 import org.apache.tapestry.internal.model.MutableComponentModelImpl;
 import org.apache.tapestry.ioc.LoggerSource;
@@ -34,8 +35,7 @@
 /**
  * Implementation of {@link org.apache.tapestry.internal.services.ComponentClassTransformer}.
  */
-public class ComponentClassTransformerImpl implements ComponentClassTransformer,
-                                                      InvalidationListener
+public class ComponentClassTransformerImpl implements ComponentClassTransformer, InvalidationListener
 {
     /**
      * Map from class name to class transformation.
@@ -48,11 +48,15 @@
 
     private final LoggerSource _logSource;
 
+    private final String[] SUBPACKAGES = {"." + InternalConstants.PAGES_SUBPACKAGE + ".",
+                                          "." + InternalConstants.COMPONENTS_SUBPACKAGE + ".",
+                                          "." + InternalConstants.MIXINS_SUBPACKAGE + ".",
+                                          "." + InternalConstants.BASE_SUBPACKAGE + "."};
+
     /**
      * @param workerChain the ordered list of class transform works as a chain of command instance
      */
-    public ComponentClassTransformerImpl(ComponentClassTransformWorker workerChain,
-                                         LoggerSource logSource)
+    public ComponentClassTransformerImpl(ComponentClassTransformWorker workerChain, LoggerSource logSource)
     {
         _workerChain = workerChain;
         _logSource = logSource;
@@ -72,7 +76,7 @@
     {
         String parentClassname;
 
-        // Component classes must be public
+// Component classes must be public
 
         if (!Modifier.isPublic(ctClass.getModifiers())) return;
 
@@ -104,12 +108,20 @@
 
         Logger logger = _logSource.getLogger(classname);
 
-        // If the parent class is in a controlled package, it will already have been loaded and
-        // transformed (that is driven by the ComponentInstantiatorSource).
+// If the parent class is in a controlled package, it will already have been loaded and
+// transformed (that is driven by the ComponentInstantiatorSource).
 
         InternalClassTransformation parentTransformation = _nameToClassTransformation
                 .get(parentClassname);
 
+        if (parentTransformation == null && !parentClassname.equals(Object.class.getName()))
+        {
+            String suggestedPackageName = buildSuggestedPackageName(classname);
+
+            throw new RuntimeException(
+                    ServicesMessages.baseClassInWrongPackage(parentClassname, classname, suggestedPackageName));
+        }
+
         // TODO: Check that the name is not already in the map. But I think that can't happen,
         // because the classloader itself is synchronized.
 
@@ -117,15 +129,12 @@
 
         ComponentModel parentModel = _nameToComponentModel.get(parentClassname);
 
-        MutableComponentModel model = new MutableComponentModelImpl(classname, logger,
-                                                                    baseResource, parentModel);
+        MutableComponentModel model = new MutableComponentModelImpl(classname, logger, baseResource, parentModel);
 
         InternalClassTransformation transformation = parentTransformation == null ? new InternalClassTransformationImpl(
-                ctClass, classLoader, logger, model)
-                                                     : new InternalClassTransformationImpl(ctClass,
+                ctClass, classLoader, logger, model) : new InternalClassTransformationImpl(ctClass,
                                                                                            parentTransformation,
-                                                                                           classLoader,
-                                                                                           logger, model);
+                                                                                           classLoader, logger, model);
 
         try
         {
@@ -138,8 +147,7 @@
             throw new TransformationException(transformation, ex);
         }
 
-        if (logger.isDebugEnabled())
-            logger.debug("Finished class transformation: " + transformation);
+        if (logger.isDebugEnabled()) logger.debug("Finished class transformation: " + transformation);
 
         _nameToClassTransformation.put(classname, transformation);
         _nameToComponentModel.put(classname, model);
@@ -151,8 +159,7 @@
 
         InternalClassTransformation ct = _nameToClassTransformation.get(className);
 
-        if (ct == null)
-            throw new RuntimeException(ServicesMessages.classNotTransformed(className));
+        if (ct == null) throw new RuntimeException(ServicesMessages.classNotTransformed(className));
 
         try
         {
@@ -162,5 +169,22 @@
         {
             throw new TransformationException(ct, ex);
         }
+    }
+
+    private String buildSuggestedPackageName(String className)
+    {
+        for (String subpackage : SUBPACKAGES)
+        {
+            int pos = className.indexOf(subpackage);
+
+// Keep the leading '.' in the subpackage name and tack on "base".
+
+            if (pos > 0) return className.substring(0, pos + 1) + InternalConstants.BASE_SUBPACKAGE;
+        }
+
+        // Is this even reachable?  className should always be in a controlled package and so
+        // some subpackage above should have matched.
+
+        return null;
     }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java?rev=601475&r1=601474&r2=601475&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry/internal/services/ServicesMessages.java Wed Dec  5 11:25:26 2007
@@ -380,4 +380,9 @@
     {
         return MESSAGES.format("no-markup-from-page-render", page.getLogicalName());
     }
+
+    static String baseClassInWrongPackage(String parentClassName, String className, String suggestedPackage)
+    {
+        return MESSAGES.format("base-class-in-wrong-package", parentClassName, className, suggestedPackage);
+    }
 }

Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties?rev=601475&r1=601474&r2=601475&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/resources/org/apache/tapestry/internal/services/ServicesStrings.properties Wed Dec  5 11:25:26 2007
@@ -12,53 +12,53 @@
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-duplicate-contribution=Contribution %s (for type %s) conflicts with existing contribution %s and has been ignored.
-markup-writer-no-current-element=This markup writer does not have a current element. \
-  The current element is established with the first call to element() and is \
-  maintained across subsequent calls. 
-no-constructor-found=Unable to find an applicable constructor for class %s.
-missing-declared-field=Class %s does not contain a field named '%s'.
-error-adding-method=Error adding method %s to class %s: %s 
-field-already-claimed=Field %s of class %s is already claimed by %s and can not be claimed by %s.
-no-declared-method=Class %s does not declare method '%s'.
-incorrect-class-for-instantiator=Unable to create a component instantiator for class %s because class %s was provided instead.
-class-not-transformed=Class %s was not transformed for use as a component; this can happen if it is an interface, or was not in a package subject to component transformation.
-new-parser-error=Failure obtaining a SAX parser for resource %s: %s
-missing-template-resource=Template resource %s does not exist.
-template-parse-error=Failure parsing template %s: %s
-content-inside-body-not-allowed=Content inside a Tapestry body element is not allowed (at %s). The content has been ignored.
-may-not-nest-elements-inside-body=Element '%s' is nested within a Tapestry body element, which is not allowed.
-method-compile-error=Error compiling method %s (%s): %s
-render-queue-error=Render queue error in %s: %s
-read-only-field=Field %s.%s is read-only.
-non-private-fields=Class %s contains field(s) (%s) that are not private. Tapestry will ignore these fields, even if they \
-  have annotations. Runtime behavior, especially in production, may not be what you expect. \
-  You should change these fields to private, and add accessor methods if needed.  
-mixins-invalid-without-id-or-type=You may not specify mixins for element <%s> because it does not represent a component (which requires either an id attribute or a type attribute).
-comp-type-conflict=Embedded component '%s' provides a type attribute in the template ('%s') as well as in the component class ('%s'). \
-  You should not provide a type attribute in the template when defining an embedded component within the component class.
-no-type-for-embedded-component=Embedded component '%s' has no type. You should specify a type in the component template, \
-  or define the component inside class %s using the @Component annotation on a private instance variable.
-embedded-components-not-in-template=Embedded component(s) %s are defined within component class %s, but are not present in the component template.
-binding-source-failure=Could not convert '%s' into a component parameter binding: %s
-page-name-unresolved=Unable to resolve class name %s to a logical page name.
-context-index-out-of-range=Method %s has more parameters than there are context values for this component event.
-exception-in-method-parameter=Exception in method %s, parameter #%d: %s
-component-event-is-aborted=Can not store result from invoking method %s, because an event result value has already been obtained from some other event handler method.
-unknown-persistent-field-strategy='%s' is not a defined persistent strategy.  Defined strategies: %s.
+duplicate-contribution=Contribution %s (for type %s) conflicts with existing contribution %s and has been ignored.
+markup-writer-no-current-element=This markup writer does not have a current element. \
+  The current element is established with the first call to element() and is \
+  maintained across subsequent calls. 
+no-constructor-found=Unable to find an applicable constructor for class %s.
+missing-declared-field=Class %s does not contain a field named '%s'.
+error-adding-method=Error adding method %s to class %s: %s 
+field-already-claimed=Field %s of class %s is already claimed by %s and can not be claimed by %s.
+no-declared-method=Class %s does not declare method '%s'.
+incorrect-class-for-instantiator=Unable to create a component instantiator for class %s because class %s was provided instead.
+class-not-transformed=Class %s was not transformed for use as a component; this can happen if it is an interface, or was not in a package subject to component transformation.
+new-parser-error=Failure obtaining a SAX parser for resource %s: %s
+missing-template-resource=Template resource %s does not exist.
+template-parse-error=Failure parsing template %s: %s
+content-inside-body-not-allowed=Content inside a Tapestry body element is not allowed (at %s). The content has been ignored.
+may-not-nest-elements-inside-body=Element '%s' is nested within a Tapestry body element, which is not allowed.
+method-compile-error=Error compiling method %s (%s): %s
+render-queue-error=Render queue error in %s: %s
+read-only-field=Field %s.%s is read-only.
+non-private-fields=Class %s contains field(s) (%s) that are not private. Tapestry will ignore these fields, even if they \
+  have annotations. Runtime behavior, especially in production, may not be what you expect. \
+  You should change these fields to private, and add accessor methods if needed.  
+mixins-invalid-without-id-or-type=You may not specify mixins for element <%s> because it does not represent a component (which requires either an id attribute or a type attribute).
+comp-type-conflict=Embedded component '%s' provides a type attribute in the template ('%s') as well as in the component class ('%s'). \
+  You should not provide a type attribute in the template when defining an embedded component within the component class.
+no-type-for-embedded-component=Embedded component '%s' has no type. You should specify a type in the component template, \
+  or define the component inside class %s using the @Component annotation on a private instance variable.
+embedded-components-not-in-template=Embedded component(s) %s are defined within component class %s, but are not present in the component template.
+binding-source-failure=Could not convert '%s' into a component parameter binding: %s
+page-name-unresolved=Unable to resolve class name %s to a logical page name.
+context-index-out-of-range=Method %s has more parameters than there are context values for this component event.
+exception-in-method-parameter=Exception in method %s, parameter #%d: %s
+component-event-is-aborted=Can not store result from invoking method %s, because an event result value has already been obtained from some other event handler method.
+unknown-persistent-field-strategy='%s' is not a defined persistent strategy.  Defined strategies: %s.
 could-not-resolve-page-name=Unable to resolve '%s' to a page class name.  Available page names: %s.
-could-not-canonicalize-page-name=Unable to resolve '%s' to a known page name. Available page names: %s.
-could-not-resolve-component-type=Unable to resolve '%s' to a component class name.  Available component types: %s.
-could-not-resolve-mixin-type=Unable to resolve '%s' to a mixin class name.  Available mixin types: %s.
-parameter-name-must-be-unique=Parameter names are required to be unique.  Parameter '%s' already has the value '%s'.
-page-is-dirty=Page %s is dirty, and will be discarded (rather than returned to the page pool).
-component-instance-is-not-a-page=Method %s (for component %s) returned component %s, which is not a page component. The page containing the component will render the client response.
-failure-reading-messages=Unable to read message catalog from %s: %s
-unknown-asset-prefix=Unknown prefix for asset path '%s'.
-asset-does-not-exist=Unable to locate asset '%s' (the file does not exist).
-wrong-asset-digest=The asset digest in the request does not match the actual digest for asset '%s'. This indicates that the content of the asset has changed between requests. 
-component-not-assignable-to-field=Component %s is not assignable to field %s (of type %s).
-unknown-validator-type=Unknown validator type '%s'.  Configured validators are %s.
+could-not-canonicalize-page-name=Unable to resolve '%s' to a known page name. Available page names: %s.
+could-not-resolve-component-type=Unable to resolve '%s' to a component class name.  Available component types: %s.
+could-not-resolve-mixin-type=Unable to resolve '%s' to a mixin class name.  Available mixin types: %s.
+parameter-name-must-be-unique=Parameter names are required to be unique.  Parameter '%s' already has the value '%s'.
+page-is-dirty=Page %s is dirty, and will be discarded (rather than returned to the page pool).
+component-instance-is-not-a-page=Method %s (for component %s) returned component %s, which is not a page component. The page containing the component will render the client response.
+failure-reading-messages=Unable to read message catalog from %s: %s
+unknown-asset-prefix=Unknown prefix for asset path '%s'.
+asset-does-not-exist=Unable to locate asset '%s' (the file does not exist).
+wrong-asset-digest=The asset digest in the request does not match the actual digest for asset '%s'. This indicates that the content of the asset has changed between requests. 
+component-not-assignable-to-field=Component %s is not assignable to field %s (of type %s).
+unknown-validator-type=Unknown validator type '%s'.  Configured validators are %s.
 validator-specification-parse-error=Unexpected character '%s' at position %d of input string: %s
 unknown-translator-type=Unknown translator type '%s'.  Configured translators are %s.
 missing-from-environment=No object of type %s is available from the Environment.  Available types are %s.
@@ -85,4 +85,5 @@
 resource-access-forbidden=URI %s may not be accessed remotely.
 no-markup-from-page-render=Page %s did not generate any markup when rendered. This could be because its template file could not be located, or because a \
   render phase method in the page prevented rendering.
+base-class-in-wrong-package=Base class %s (super class of %s) is not in a controlled package and is therefore not valid. You should try moving the class to package %s.
 

Modified: tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/component-classes.apt
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/component-classes.apt?rev=601475&r1=601474&r2=601475&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/component-classes.apt (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/site/apt/guide/component-classes.apt Wed Dec  5 11:25:26 2007
@@ -180,7 +180,7 @@
   
 {Embedded Components}
 
-  Components often contain other components.  Components inside another components template are called <embedded components>.  
+  Components often contain other components.  Components inside another component's template are called <embedded components>.  
   The containing component's
   {{{templates.html}template}} will contain special elements, in the Tapestry namespace, identifying where the the embedded components go.
   

Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java?rev=601475&r1=601474&r2=601475&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/IntegrationTests.java Wed Dec  5 11:25:26 2007
@@ -1190,4 +1190,15 @@
 
         // assertTextPresent("Selected: Mr. &lt;Roboto&gt;");
     }
+
+    /**
+     * Tests TAPESTRY-1934.
+     */
+    public void base_class_must_be_in_controlled_package() throws Exception
+    {
+        open(BASE_URL + "invalidsuperclass");
+
+        assertTextPresent(
+                "Base class org.apache.tapestry.integration.app1.WrongPackageForBaseClass (super class of org.apache.tapestry.integration.app1.pages.InvalidSuperClass) is not in a controlled package and is therefore not valid. You should try moving the class to package org.apache.tapestry.integration.app1.base.");
+    }
 }

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/WrongPackageForBaseClass.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/WrongPackageForBaseClass.java?rev=601475&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/WrongPackageForBaseClass.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/WrongPackageForBaseClass.java Wed Dec  5 11:25:26 2007
@@ -0,0 +1,22 @@
+// Copyright 2007 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.integration.app1;
+
+/**
+ * Used in a test for TAPESTRY-1934; base classes should be in the .base package.
+ */
+public class WrongPackageForBaseClass
+{
+}

Added: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InvalidSuperClass.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InvalidSuperClass.java?rev=601475&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InvalidSuperClass.java (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry/integration/app1/pages/InvalidSuperClass.java Wed Dec  5 11:25:26 2007
@@ -0,0 +1,24 @@
+// Copyright 2007 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.integration.app1.pages;
+
+import org.apache.tapestry.integration.app1.WrongPackageForBaseClass;
+
+/**
+ * TAPESTRY-1934: Check for invalid base classes.
+ */
+public class InvalidSuperClass extends WrongPackageForBaseClass
+{
+}