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. <Roboto>");
}
+
+ /**
+ * 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
+{
+}