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 2010/03/12 06:21:12 UTC
svn commit: r922145 - in /tapestry/tapestry5/trunk:
tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/
tapestry-core/src/main/java/org/apache/tapestry5/internal/services/
tapestry-core/src/main/java/org/apache/tapestry5/internal/util/ ...
Author: hlship
Date: Fri Mar 12 05:21:12 2010
New Revision: 922145
URL: http://svn.apache.org/viewvc?rev=922145&view=rev
Log:
TAP5-1013: Allow a limited set of IoC service implementations to automatically reload
Added:
tapestry/tapestry5/trunk/tapestry-core/src/test/app1/ReloadDemo.tml
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ReloadDemo.java
- copied, changed from r922144, tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/UninstantiableAutobuildServiceModule.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/Reloadable.java
- copied, changed from r922144, tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/UninstantiableAutobuildServiceModule.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/ReloadableImpl.java
- copied, changed from r922144, tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/UninstantiableAutobuildServiceModule.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreator.java (with props)
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreatorSource.java (with props)
Modified:
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AssetBinding.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ValidatorSpecification.java
tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/URLChangeTracker.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceBinderImpl.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/ClassFabUtils.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/MutlipleAutobuildServiceConstructorsModule.java
tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/UninstantiableAutobuildServiceModule.java
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AssetBinding.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AssetBinding.java?rev=922145&r1=922144&r2=922145&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AssetBinding.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/bindings/AssetBinding.java Fri Mar 12 05:21:12 2010
@@ -4,7 +4,7 @@
// 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
+// 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,
@@ -25,7 +25,7 @@ public class AssetBinding extends Abstra
private final Asset2 asset;
- AssetBinding(Location location, String description, Asset asset)
+ public AssetBinding(Location location, String description, Asset asset)
{
super(location);
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java?rev=922145&r1=922144&r2=922145&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ComponentInstantiatorSourceImpl.java Fri Mar 12 05:21:12 2010
@@ -1,10 +1,10 @@
-// Copyright 2006, 2007, 2008 The Apache Software Foundation
+// Copyright 2006, 2007, 2008, 2010 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
+// 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,
@@ -23,6 +23,7 @@ import org.apache.tapestry5.ioc.internal
import org.apache.tapestry5.ioc.internal.services.CtClassSourceImpl;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
import org.apache.tapestry5.ioc.internal.util.Defense;
+import org.apache.tapestry5.ioc.services.ClassFabUtils;
import org.apache.tapestry5.ioc.services.ClassFactory;
import org.apache.tapestry5.ioc.services.ClasspathURLConverter;
import org.apache.tapestry5.services.InvalidationEventHub;
@@ -37,7 +38,8 @@ import java.util.Set;
/**
* A wrapper around a Javassist class loader that allows certain classes to be modified as they are loaded.
*/
-public final class ComponentInstantiatorSourceImpl extends InvalidationEventHubImpl implements Translator, ComponentInstantiatorSource, UpdateListener
+public final class ComponentInstantiatorSourceImpl extends InvalidationEventHubImpl implements Translator,
+ ComponentInstantiatorSource, UpdateListener
{
/**
* Add -Djavassist-write-dir=target/transformed-classes to the command line to force output of transformed classes
@@ -78,10 +80,10 @@ public final class ComponentInstantiator
}
/**
- * Determines if the class name represents a component class from a controlled package. If so,
+ * Determines if the class name represents a component class from a controlled package. If so,
* super.findClass() will load it and transform it. Returns null if not in a controlled package, allowing the
* parent class loader to do the work.
- *
+ *
* @param className
* @return the loaded transformed Class, or null to force a load of the class from the parent class loader
* @throws ClassNotFoundException
@@ -89,10 +91,7 @@ public final class ComponentInstantiator
@Override
protected Class findClass(String className) throws ClassNotFoundException
{
- if (inControlledPackage(className))
- {
- return super.findClass(className);
- }
+ if (inControlledPackage(className)) { return super.findClass(className); }
// Returning null forces delegation to the parent class loader.
@@ -101,8 +100,7 @@ public final class ComponentInstantiator
}
public ComponentInstantiatorSourceImpl(Logger logger, ClassLoader parent, ComponentClassTransformer transformer,
- InternalRequestGlobals internalRequestGlobals,
- ClasspathURLConverter classpathURLConverter)
+ InternalRequestGlobals internalRequestGlobals, ClasspathURLConverter classpathURLConverter)
{
this.parent = parent;
this.transformer = transformer;
@@ -115,7 +113,8 @@ public final class ComponentInstantiator
public synchronized void checkForUpdates()
{
- if (!changeTracker.containsChanges()) return;
+ if (!changeTracker.containsChanges())
+ return;
changeTracker.clear();
classNameToInstantiator.clear();
@@ -220,12 +219,14 @@ public final class ComponentInstantiator
logger.debug(String.format("%5s onLoad %s", diag, classname));
- if (failure != null) throw failure;
+ if (failure != null)
+ throw failure;
}
private void writeClassToFileSystemForHardCoreDebuggingPurposesOnly(CtClass ctClass)
{
- if (JAVASSIST_WRITE_DIR == null) return;
+ if (JAVASSIST_WRITE_DIR == null)
+ return;
try
{
@@ -242,7 +243,7 @@ public final class ComponentInstantiator
private void addClassFileToChangeTracker(String classname)
{
- String path = classname.replace('.', '/') + ".class";
+ String path = ClassFabUtils.getPathForClassNamed(classname);
URL url = loader.getResource(path);
@@ -277,7 +278,7 @@ public final class ComponentInstantiator
// Note: this is really a create, and in fact, will create a new Class instance
// (it doesn't cache internally). This code is the only cache, which is why
- // the method is synchronized. We could use a ConcurrentBarrier, but I suspect
+ // the method is synchronized. We could use a ConcurrentBarrier, but I suspect
// that the overhead of that is greater on a typical invocation than
// the cost of the synchronization and the Map lookup.
@@ -312,7 +313,8 @@ public final class ComponentInstantiator
while (packageName != null)
{
- if (controlledPackageNames.contains(packageName)) return true;
+ if (controlledPackageNames.contains(packageName))
+ return true;
packageName = stripTail(packageName);
}
@@ -324,7 +326,8 @@ public final class ComponentInstantiator
{
int lastdot = input.lastIndexOf('.');
- if (lastdot < 0) return null;
+ if (lastdot < 0)
+ return null;
return input.substring(0, lastdot);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java?rev=922145&r1=922144&r2=922145&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ServicesMessages.java Fri Mar 12 05:21:12 2010
@@ -34,142 +34,142 @@ import java.util.Collection;
import java.util.List;
import java.util.Locale;
-class ServicesMessages
+public class ServicesMessages
{
private static final Messages MESSAGES = MessagesImpl.forClass(ServicesMessages.class);
- static String duplicateContribution(Object conflict, Class contributionType, Object existing)
+ public static String duplicateContribution(Object conflict, Class contributionType, Object existing)
{
return MESSAGES.format("duplicate-contribution", conflict, contributionType.getName(), existing);
}
- static String markupWriterNoCurrentElement()
+ public static String markupWriterNoCurrentElement()
{
return MESSAGES.get("markup-writer-no-current-element");
}
- static String errorAddingMethod(CtClass ctClass, String methodName, Throwable cause)
+ public static String errorAddingMethod(CtClass ctClass, String methodName, Throwable cause)
{
return MESSAGES.format("error-adding-method", ctClass.getName(), methodName, cause);
}
- static String classNotTransformed(String className)
+ public static String classNotTransformed(String className)
{
return MESSAGES.format("class-not-transformed", className);
}
- static String missingTemplateResource(Resource resource)
+ public static String missingTemplateResource(Resource resource)
{
return MESSAGES.format("missing-template-resource", resource);
}
- static String contentInsideBodyNotAllowed(Location location)
+ public static String contentInsideBodyNotAllowed(Location location)
{
return MESSAGES.format("content-inside-body-not-allowed", location);
}
- static String methodCompileError(TransformMethodSignature signature, String methodBody, Throwable cause)
+ public static String methodCompileError(TransformMethodSignature signature, String methodBody, Throwable cause)
{
return MESSAGES.format("method-compile-error", signature, methodBody, cause);
}
- static String renderQueueError(RenderCommand command, Throwable cause)
+ public static String renderQueueError(RenderCommand command, Throwable cause)
{
return MESSAGES.format("render-queue-error", command, cause);
}
- static String readOnlyField(String className, String fieldName)
+ public static String readOnlyField(String className, String fieldName)
{
return MESSAGES.format("read-only-field", className, fieldName);
}
- static String nonPrivateFields(String className, List<String> names)
+ public static String nonPrivateFields(String className, List<String> names)
{
return MESSAGES.format("non-private-fields", className, InternalUtils.joinSorted(names));
}
- static String bindingSourceFailure(String expression, Throwable cause)
+ public static String bindingSourceFailure(String expression, Throwable cause)
{
return MESSAGES.format("binding-source-failure", expression, cause);
}
- static String contextIndexOutOfRange(String methodDescription)
+ public static String contextIndexOutOfRange(String methodDescription)
{
return MESSAGES.format("context-index-out-of-range", methodDescription);
}
- static String pageNameUnresolved(String pageClassName)
+ public static String pageNameUnresolved(String pageClassName)
{
return MESSAGES.format("page-name-unresolved", pageClassName);
}
- static String exceptionInMethodParameter(String methodDescription, int index, Throwable cause)
+ public static String exceptionInMethodParameter(String methodDescription, int index, Throwable cause)
{
return MESSAGES.format("exception-in-method-parameter", methodDescription, index + 1, cause);
}
- static String componentEventIsAborted(String methodDescription)
+ public static String componentEventIsAborted(String methodDescription)
{
return MESSAGES.format("component-event-is-aborted", methodDescription);
}
- static String parameterNameMustBeUnique(String parameterName, String parameterValue)
+ public static String parameterNameMustBeUnique(String parameterName, String parameterValue)
{
return MESSAGES.format("parameter-name-must-be-unique", parameterName, parameterValue);
}
- static String pageIsDirty(Object page)
+ public static String pageIsDirty(Object page)
{
return MESSAGES.format("page-is-dirty", page);
}
- static String componentInstanceIsNotAPage(Component result)
+ public static String componentInstanceIsNotAPage(Component result)
{
return MESSAGES.format("component-instance-is-not-a-page", result.getComponentResources().getCompleteId());
}
- static String failureReadingMessages(Resource url, Throwable cause)
+ public static String failureReadingMessages(Resource url, Throwable cause)
{
return MESSAGES.format("failure-reading-messages", url, cause);
}
- static String unknownAssetPrefix(String path)
+ public static String unknownAssetPrefix(String path)
{
return MESSAGES.format("unknown-asset-prefix", path);
}
- static String assetDoesNotExist(Resource resource)
+ public static String assetDoesNotExist(Resource resource)
{
return MESSAGES.format("asset-does-not-exist", resource);
}
- static String wrongAssetDigest(Resource resource)
+ public static String wrongAssetDigest(Resource resource)
{
return MESSAGES.format("wrong-asset-digest", resource.getPath());
}
- static String unknownValidatorType(String validatorType, List<String> knownValidatorTypes)
+ public static String unknownValidatorType(String validatorType, List<String> knownValidatorTypes)
{
return MESSAGES.format("unknown-validator-type", validatorType, InternalUtils.join(knownValidatorTypes));
}
- static String unknownTranslatorType(String translatorType, List<String> knownTranslatorTypes)
+ public static String unknownTranslatorType(String translatorType, List<String> knownTranslatorTypes)
{
return MESSAGES.format("unknown-translator-type", translatorType, InternalUtils.join(knownTranslatorTypes));
}
- static String validatorSpecificationParseError(int cursor, String specification)
+ public static String validatorSpecificationParseError(int cursor, String specification)
{
return MESSAGES.format("validator-specification-parse-error", specification.charAt(cursor), cursor + 1,
specification);
}
- static String mixinsInvalidWithoutIdOrType(String elementName)
+ public static String mixinsInvalidWithoutIdOrType(String elementName)
{
return MESSAGES.format("mixins-invalid-without-id-or-type", elementName);
}
- static String missingFromEnvironment(Class type, Collection<Class> availableTypes)
+ public static String missingFromEnvironment(Class type, Collection<Class> availableTypes)
{
List<String> types = CollectionFactory.newList();
@@ -179,7 +179,7 @@ class ServicesMessages
return MESSAGES.format("missing-from-environment", type.getName(), InternalUtils.joinSorted(types));
}
- static String invalidComponentEventResult(Object result, Collection<Class> configuredResultTypes)
+ public static String invalidComponentEventResult(Object result, Collection<Class> configuredResultTypes)
{
List<String> classNames = CollectionFactory.newList();
@@ -190,112 +190,113 @@ class ServicesMessages
.getClass()), InternalUtils.joinSorted(classNames));
}
- static String undefinedTapestryAttribute(String elementName, String attributeName, String allowedAttributeName)
+ public static String undefinedTapestryAttribute(String elementName, String attributeName,
+ String allowedAttributeName)
{
return MESSAGES.format("undefined-tapestry-attribute", elementName, attributeName, allowedAttributeName);
}
- static String parameterElementNameRequired()
+ public static String parameterElementNameRequired()
{
return MESSAGES.get("parameter-element-name-required");
}
- static String missingApplicationStatePersistenceStrategy(String name, Collection<String> availableNames)
+ public static String missingApplicationStatePersistenceStrategy(String name, Collection<String> availableNames)
{
return MESSAGES.format("missing-application-state-persistence-strategy", name, InternalUtils
.joinSorted(availableNames));
}
- static String methodIsVoid(String methodName, Class inClass, String propertyExpression)
+ public static String methodIsVoid(String methodName, Class inClass, String propertyExpression)
{
return MESSAGES.format("method-is-void", methodName, inClass.getName(), propertyExpression);
}
- static String methodNotFound(String methodName, Class inClass, String propertyExpression)
+ public static String methodNotFound(String methodName, Class inClass, String propertyExpression)
{
return MESSAGES.format("method-not-found", methodName, inClass.getName(), propertyExpression);
}
- static String noSuchProperty(Class targetClass, String propertyName, String propertyExpression,
+ public static String noSuchProperty(Class targetClass, String propertyName, String propertyExpression,
Collection<String> propertyNames)
{
return MESSAGES.format("no-such-property", targetClass.getName(), propertyName, propertyExpression,
InternalUtils.joinSorted(propertyNames));
}
- static String writeOnlyProperty(String propertyName, Class clazz, String propertyExpression)
+ public static String writeOnlyProperty(String propertyName, Class clazz, String propertyExpression)
{
return MESSAGES.format("write-only-property", propertyName, clazz.getName(), propertyExpression);
}
- static String requestException(Throwable cause)
+ public static String requestException(Throwable cause)
{
return MESSAGES.format("request-exception", cause);
}
- static String componentRecursion(String componentClassName)
+ public static String componentRecursion(String componentClassName)
{
return MESSAGES.format("component-recursion", componentClassName);
}
- static String clientStateMustBeSerializable(Object newValue)
+ public static String clientStateMustBeSerializable(Object newValue)
{
return MESSAGES.format("client-state-must-be-serializable", newValue);
}
- static String corruptClientState()
+ public static String corruptClientState()
{
return MESSAGES.get("corrupt-client-state");
}
- static String unclosedAttributeExpression(String expression)
+ public static String unclosedAttributeExpression(String expression)
{
return MESSAGES.format("unclosed-attribute-expression", expression);
}
- static String noDisplayForDataType(String datatype)
+ public static String noDisplayForDataType(String datatype)
{
return MESSAGES.format("no-display-for-data-type", datatype);
}
- static String noEditForDataType(String datatype)
+ public static String noEditForDataType(String datatype)
{
return MESSAGES.format("no-edit-for-data-type", datatype);
}
- static String missingValidatorConstraint(String validatorType, Class type, String perFormMessageKey,
+ public static String missingValidatorConstraint(String validatorType, Class type, String perFormMessageKey,
String generalMessageKey)
{
return MESSAGES.format("missing-validator-constraint", validatorType, type.getName(), perFormMessageKey,
generalMessageKey);
}
- static String resourcesAccessForbidden(String URI)
+ public static String resourcesAccessForbidden(String URI)
{
return MESSAGES.format("resource-access-forbidden", URI);
}
- static String noMarkupFromPageRender(Page page)
+ public static String noMarkupFromPageRender(Page page)
{
return MESSAGES.format("no-markup-from-page-render", page.getName());
}
- static String baseClassInWrongPackage(String parentClassName, String className, String suggestedPackage)
+ public static String baseClassInWrongPackage(String parentClassName, String className, String suggestedPackage)
{
return MESSAGES.format("base-class-in-wrong-package", parentClassName, className, suggestedPackage);
}
- static String invalidId(String messageKey, String idValue)
+ public static String invalidId(String messageKey, String idValue)
{
return MESSAGES.format(messageKey, idValue);
}
- static String attributeNotAllowed(String elementName)
+ public static String attributeNotAllowed(String elementName)
{
return MESSAGES.format("attribute-not-allowed", elementName);
}
- static String pagePoolExausted(String pageName, Locale locale, int hardLimit)
+ public static String pagePoolExausted(String pageName, Locale locale, int hardLimit)
{
return MESSAGES.format("page-pool-exausted", pageName, locale.toString(), hardLimit);
}
@@ -306,27 +307,27 @@ class ServicesMessages
.joinSorted(typeNames));
}
- static String emptyBinding(String parameterName)
+ public static String emptyBinding(String parameterName)
{
return MESSAGES.format("parameter-binding-must-not-be-empty", parameterName);
}
- static String noSuchMethod(Class clazz, String methodName)
+ public static String noSuchMethod(Class clazz, String methodName)
{
return MESSAGES.format("no-such-method", ClassFabUtils.toJavaClassName(clazz), methodName);
}
- static String forbidInstantiateComponentClass(String className)
+ public static String forbidInstantiateComponentClass(String className)
{
return MESSAGES.format("forbid-instantiate-component-class", className);
}
- static String eventNotHandled(ComponentPageElement element, String eventName)
+ public static String eventNotHandled(ComponentPageElement element, String eventName)
{
return MESSAGES.format("event-not-handled", eventName, element.getCompleteId());
}
- static String documentMissingHTMLRoot(String rootElementName)
+ public static String documentMissingHTMLRoot(String rootElementName)
{
return MESSAGES.format("document-missing-html-root", rootElementName);
}
@@ -336,33 +337,34 @@ class ServicesMessages
return MESSAGES.format("add-new-method-conflict", signature);
}
- static String parameterElementDoesNotAllowAttributes()
+ public static String parameterElementDoesNotAllowAttributes()
{
return MESSAGES.get("parameter-element-does-not-allow-attributes");
}
- static String invalidPathForLibraryNamespace(String URI)
+ public static String invalidPathForLibraryNamespace(String URI)
{
return MESSAGES.format("invalid-path-for-library-namespace", URI);
}
- static String literalConduitNotUpdateable()
+ public static String literalConduitNotUpdateable()
{
return MESSAGES.get("literal-conduit-not-updateable");
}
- static String requestRewriteReturnedNull()
+ public static String requestRewriteReturnedNull()
{
return MESSAGES.get("request-rewrite-returned-null");
}
- static String linkRewriteReturnedNull()
+ public static String linkRewriteReturnedNull()
{
return MESSAGES.get("link-rewrite-returned-null");
}
public static String markupWriterAttributeNameOrValueOmitted(String element, Object[] namesAndValues)
{
- return MESSAGES.format("markup-writer-attribute-name-or-value-omitted", element, InternalUtils.join(Arrays.asList(namesAndValues)));
+ return MESSAGES.format("markup-writer-attribute-name-or-value-omitted", element, InternalUtils.join(Arrays
+ .asList(namesAndValues)));
}
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ValidatorSpecification.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ValidatorSpecification.java?rev=922145&r1=922144&r2=922145&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ValidatorSpecification.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/services/ValidatorSpecification.java Fri Mar 12 05:21:12 2010
@@ -1,10 +1,10 @@
-// Copyright 2006, 2008 The Apache Software Foundation
+// Copyright 2006, 2008, 2010 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
+// 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,
@@ -19,7 +19,7 @@ import org.apache.tapestry5.internal.Tap
/**
* Validator type and constraint values parsed from a validator specification.
*/
-class ValidatorSpecification
+public class ValidatorSpecification
{
private final String validatorType;
@@ -55,11 +55,13 @@ class ValidatorSpecification
@Override
public boolean equals(Object other)
{
- if (other == null || other.getClass() != getClass()) return false;
+ if (other == null || other.getClass() != getClass())
+ return false;
ValidatorSpecification ov = (ValidatorSpecification) other;
- if (!validatorType.equals(ov.validatorType)) return false;
+ if (!validatorType.equals(ov.validatorType))
+ return false;
return TapestryInternalUtils.isEqual(constraintValue, ov.constraintValue);
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/URLChangeTracker.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/URLChangeTracker.java?rev=922145&r1=922144&r2=922145&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/URLChangeTracker.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/main/java/org/apache/tapestry5/internal/util/URLChangeTracker.java Fri Mar 12 05:21:12 2010
@@ -15,11 +15,11 @@
package org.apache.tapestry5.internal.util;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
+import org.apache.tapestry5.ioc.services.ClassFabUtils;
import org.apache.tapestry5.ioc.services.ClasspathURLConverter;
import java.io.File;
import java.io.IOException;
-import java.net.URISyntaxException;
import java.net.URL;
import java.util.Map;
@@ -80,7 +80,7 @@ public class URLChangeTracker
if (!converted.getProtocol().equals("file")) return timestampForNonFileURL(converted);
- File resourceFile = toFile(converted);
+ File resourceFile = ClassFabUtils.toFileFromFileProtocolURL(converted);
if (fileToTimestamp.containsKey(resourceFile)) return fileToTimestamp.get(resourceFile);
@@ -119,20 +119,6 @@ public class URLChangeTracker
return applyGranularity(timestamp);
}
- private File toFile(URL url)
- {
- // http://weblogs.java.net/blog/kohsuke/archive/2007/04/how_to_convert.html
-
- try
- {
- return new File(url.toURI());
- }
- catch (URISyntaxException ex)
- {
- return new File(url.getPath());
- }
- }
-
/**
* Clears all URL and timestamp data stored in the tracker.
*/
Added: tapestry/tapestry5/trunk/tapestry-core/src/test/app1/ReloadDemo.tml
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/app1/ReloadDemo.tml?rev=922145&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/app1/ReloadDemo.tml (added)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/app1/ReloadDemo.tml Fri Mar 12 05:21:12 2010
@@ -0,0 +1,16 @@
+<html t:type="Border" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_0_0.xsd">
+
+ <h1>Service Implementation Reload Demo</h1>
+
+
+ <p>
+ Reloadable service status:
+ <strong id="status">${reloadable.status}</strong>
+ </p>
+
+ <p>
+ <t:pagelink page="reloaddemo">reload page</t:pagelink>
+ </p>
+
+</html>
+
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java?rev=922145&r1=922144&r2=922145&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/Index.java Fri Mar 12 05:21:12 2010
@@ -67,6 +67,9 @@ public class Index
private static final List<Item> ITEMS = CollectionFactory
.newList(
+ new Item("ReloadDemo", "Reloadable Service Implementation Demo",
+ "Used when manually testing service reloads"),
+
new Item("QueryParameterDemo", "QueryParameter Annotation Demo",
"Use of @QueryParameter annotation on event handler method parameters"),
Copied: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ReloadDemo.java (from r922144, tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/UninstantiableAutobuildServiceModule.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ReloadDemo.java?p2=tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ReloadDemo.java&p1=tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/UninstantiableAutobuildServiceModule.java&r1=922144&r2=922145&rev=922145&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/UninstantiableAutobuildServiceModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/pages/ReloadDemo.java Fri Mar 12 05:21:12 2010
@@ -1,10 +1,10 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2010 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
+// 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,
@@ -12,14 +12,15 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry5.ioc.internal;
+package org.apache.tapestry5.integration.app1.pages;
-import org.apache.tapestry5.ioc.ServiceBinder;
+import org.apache.tapestry5.annotations.Property;
+import org.apache.tapestry5.integration.app1.services.Reloadable;
+import org.apache.tapestry5.ioc.annotations.Inject;
-public class UninstantiableAutobuildServiceModule
+public class ReloadDemo
{
- public static void bind(ServiceBinder binder)
- {
- binder.bind(Runnable.class, RunnableServiceImpl.class);
- }
+ @Property
+ @Inject
+ private Reloadable reloadable;
}
Modified: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java?rev=922145&r1=922144&r2=922145&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/AppModule.java Fri Mar 12 05:21:12 2010
@@ -4,7 +4,7 @@
// 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
+// 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,
@@ -22,6 +22,7 @@ import org.apache.tapestry5.internal.ser
import org.apache.tapestry5.ioc.Configuration;
import org.apache.tapestry5.ioc.MappedConfiguration;
import org.apache.tapestry5.ioc.OrderedConfiguration;
+import org.apache.tapestry5.ioc.ServiceBinder;
import org.apache.tapestry5.ioc.annotations.Marker;
import org.apache.tapestry5.ioc.annotations.Symbol;
import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
@@ -50,7 +51,7 @@ public class AppModule
* interface.
*/
@Target(
- { PARAMETER, FIELD })
+ { PARAMETER, FIELD })
@Retention(RUNTIME)
@Documented
public @interface Local
@@ -58,6 +59,11 @@ public class AppModule
}
+ public static void bind(ServiceBinder binder)
+ {
+ binder.bind(Reloadable.class);
+ }
+
public void contributeAlias(Configuration<AliasContribution> configuration)
{
BaseURLSource source = new BaseURLSource()
@@ -66,7 +72,7 @@ public class AppModule
{
String protocol = secure ? "https" : "http";
- // This is all a bit jury-rigged together. This is for running the app
+ // This is all a bit jury-rigged together. This is for running the app
// interactively; Selenium doesn't seem to handle the transition to https.
int port = secure ? JettyRunner.DEFAULT_SECURE_PORT : JettyRunner.DEFAULT_PORT;
@@ -102,7 +108,8 @@ public class AppModule
public void contributeRequestHandler(OrderedConfiguration<RequestFilter> configuration,
- @Local RequestFilter filter)
+ @Local
+ RequestFilter filter)
{
configuration.add("Timing", filter);
}
@@ -128,7 +135,7 @@ public class AppModule
configuration.add(SymbolConstants.SECURE_ENABLED, "true");
configuration.add("app.injected-symbol", "Symbol contributed to ApplicationDefaults");
-
+
configuration.add(SymbolConstants.BLACKBIRD_ENABLED, "true");
}
@@ -161,7 +168,8 @@ public class AppModule
{
Track result = idToTrack.get(id);
- if (result != null) return result;
+ if (result != null)
+ return result;
throw new IllegalArgumentException(String.format("No track with id #%d.", id));
}
@@ -179,7 +187,8 @@ public class AppModule
for (Track t : tracks)
{
- if (t.getTitle().toLowerCase().contains(titleLower)) result.add(t);
+ if (t.getTitle().toLowerCase().contains(titleLower))
+ result.add(t);
}
return result;
@@ -213,8 +222,7 @@ public class AppModule
}
public static void contributeValueEncoderSource(MappedConfiguration<Class, ValueEncoderFactory> configuration,
- final MusicLibrary library,
- final ToDoDatabase todoDatabase)
+ final MusicLibrary library, final ToDoDatabase todoDatabase)
{
ValueEncoder<Track> trackEncoder = new ValueEncoder<Track>()
{
@@ -231,7 +239,6 @@ public class AppModule
}
};
-
configuration.add(Track.class, GenericValueEncoderFactory.create(trackEncoder));
ValueEncoder<ToDoItem> todoEncoder = new ValueEncoder<ToDoItem>()
@@ -252,7 +259,6 @@ public class AppModule
configuration.add(ToDoItem.class, GenericValueEncoderFactory.create(todoEncoder));
}
-
public static void contributeComponentClassTransformWorker(
OrderedConfiguration<ComponentClassTransformWorker> configuration)
{
Copied: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/Reloadable.java (from r922144, tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/UninstantiableAutobuildServiceModule.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/Reloadable.java?p2=tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/Reloadable.java&p1=tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/UninstantiableAutobuildServiceModule.java&r1=922144&r2=922145&rev=922145&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/UninstantiableAutobuildServiceModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/Reloadable.java Fri Mar 12 05:21:12 2010
@@ -1,10 +1,10 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2010 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
+// 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,
@@ -12,14 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry5.ioc.internal;
+package org.apache.tapestry5.integration.app1.services;
-import org.apache.tapestry5.ioc.ServiceBinder;
-
-public class UninstantiableAutobuildServiceModule
+public interface Reloadable
{
- public static void bind(ServiceBinder binder)
- {
- binder.bind(Runnable.class, RunnableServiceImpl.class);
- }
+ String getStatus();
}
Copied: tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/ReloadableImpl.java (from r922144, tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/UninstantiableAutobuildServiceModule.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/ReloadableImpl.java?p2=tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/ReloadableImpl.java&p1=tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/UninstantiableAutobuildServiceModule.java&r1=922144&r2=922145&rev=922145&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/UninstantiableAutobuildServiceModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-core/src/test/java/org/apache/tapestry5/integration/app1/services/ReloadableImpl.java Fri Mar 12 05:21:12 2010
@@ -1,10 +1,10 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2010 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
+// 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,
@@ -12,14 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package org.apache.tapestry5.ioc.internal;
+package org.apache.tapestry5.integration.app1.services;
-import org.apache.tapestry5.ioc.ServiceBinder;
-
-public class UninstantiableAutobuildServiceModule
+public class ReloadableImpl implements Reloadable
{
- public static void bind(ServiceBinder binder)
+ public String getStatus()
{
- binder.bind(Runnable.class, RunnableServiceImpl.class);
+ return "Initial Value";
}
+
}
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java?rev=922145&r1=922144&r2=922145&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ModuleImpl.java Fri Mar 12 05:21:12 2010
@@ -4,7 +4,7 @@
// 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
+// 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,
@@ -70,7 +70,7 @@ public class ModuleImpl implements Modul
private final Logger logger;
/**
- * Lazily instantiated. Access is guarded by BARRIER.
+ * Lazily instantiated. Access is guarded by BARRIER.
*/
private Object moduleInstance;
@@ -93,7 +93,7 @@ public class ModuleImpl implements Modul
private final static ConcurrentBarrier BARRIER = new ConcurrentBarrier();
public ModuleImpl(InternalRegistry registry, ServiceActivityTracker tracker, ModuleDef moduleDef,
- ClassFactory classFactory, Logger logger)
+ ClassFactory classFactory, Logger logger)
{
this.registry = registry;
this.tracker = tracker;
@@ -111,7 +111,6 @@ public class ModuleImpl implements Modul
}
}
-
public <T> T getService(String serviceId, Class<T> serviceInterface)
{
Defense.notBlank(serviceId, "serviceId");
@@ -135,8 +134,8 @@ public class ModuleImpl implements Modul
// given that the return type of the method determines
// the service interface.
- throw new RuntimeException(IOCMessages.serviceWrongInterface(serviceId, def
- .getServiceInterface(), serviceInterface));
+ throw new RuntimeException(IOCMessages.serviceWrongInterface(serviceId, def.getServiceInterface(),
+ serviceInterface));
}
}
@@ -146,7 +145,8 @@ public class ModuleImpl implements Modul
for (DecoratorDef def : moduleDef.getDecoratorDefs())
{
- if (def.matches(serviceDef)) result.add(def);
+ if (def.matches(serviceDef))
+ result.add(def);
}
return result;
@@ -158,7 +158,8 @@ public class ModuleImpl implements Modul
for (AdvisorDef def : moduleDef.getAdvisorDefs())
{
- if (def.matches(serviceDef)) result.add(def);
+ if (def.matches(serviceDef))
+ result.add(def);
}
return result;
@@ -182,13 +183,14 @@ public class ModuleImpl implements Modul
/**
* Locates the service proxy for a particular service (from the service definition).
- *
- * @param def defines the service
- * @param eagerLoadProxies collection into which proxies for eager loaded services are added (or null)
+ *
+ * @param def
+ * defines the service
+ * @param eagerLoadProxies
+ * collection into which proxies for eager loaded services are added (or null)
* @return the service proxy
*/
- private Object findOrCreate(final ServiceDef2 def,
- final Collection<EagerLoadServiceProxy> eagerLoadProxies)
+ private Object findOrCreate(final ServiceDef2 def, final Collection<EagerLoadServiceProxy> eagerLoadProxies)
{
final String key = def.getServiceId();
@@ -239,7 +241,8 @@ public class ModuleImpl implements Modul
{
for (ServiceDef2 def : serviceDefs.values())
{
- if (def.isEagerLoad()) findOrCreate(def, proxies);
+ if (def.isEagerLoad())
+ findOrCreate(def, proxies);
}
}
};
@@ -247,11 +250,11 @@ public class ModuleImpl implements Modul
registry.run("Eager loading services", work);
}
-
/**
* Creates the service and updates the cache of created services.
- *
- * @param eagerLoadProxies a list into which any eager loaded proxies should be added
+ *
+ * @param eagerLoadProxies
+ * a list into which any eager loaded proxies should be added
*/
private Object create(final ServiceDef2 def, final Collection<EagerLoadServiceProxy> eagerLoadProxies)
{
@@ -272,9 +275,8 @@ public class ModuleImpl implements Modul
{
try
{
- ServiceBuilderResources resources = new ServiceResourcesImpl(registry, module, def,
- classFactory,
- logger);
+ ServiceBuilderResources resources = new ServiceResourcesImpl(registry, module, def, classFactory,
+ logger);
// Build up a stack of operations that will be needed to realize the service
// (by the proxy, at a later date).
@@ -285,7 +287,6 @@ public class ModuleImpl implements Modul
ServiceLifecycle2 lifecycle = registry.getServiceLifecycle(def.getServiceScope());
-
// For non-proxyable services, we immediately create the service implementation
// and return it. There's no interface to proxy, which throws out the possibility of
// deferred instantiation, service lifecycles, and decorators.
@@ -293,9 +294,11 @@ public class ModuleImpl implements Modul
if (!serviceInterface.isInterface())
{
if (lifecycle.requiresProxy())
- throw new IllegalArgumentException(String.format(
- "Service scope '%s' requires a proxy, but the service does not have a service interface (necessary to create a proxy). Provide a service interface or select a different service scope.",
- def.getServiceScope()));
+ throw new IllegalArgumentException(
+ String
+ .format(
+ "Service scope '%s' requires a proxy, but the service does not have a service interface (necessary to create a proxy). Provide a service interface or select a different service scope.",
+ def.getServiceScope()));
return creator.createObject();
}
@@ -308,7 +311,9 @@ public class ModuleImpl implements Modul
// TapestryIOCModule prevents decoration of its services. Note that all decorators will decorate
// around the aspect interceptor, which wraps around the core service implementation.
- if (!def.isPreventDecoration())
+ boolean allowDecoration = !def.isPreventDecoration();
+
+ if (allowDecoration)
{
creator = new AdvisorStackBuilder(def, creator, getAspectDecorator(), registry);
creator = new InterceptorStackBuilder(def, creator, registry);
@@ -326,11 +331,9 @@ public class ModuleImpl implements Modul
registry.addRegistryShutdownListener(delegate);
- // Occasionally service A may invoke service B from its service builder method; if
- // service B
- // is eager loaded, we'll hit this method but eagerLoadProxies will be null. That's OK
- // ... service B
- // is being realized anyway.
+ // Occasionally eager load service A may invoke service B from its service builder method; if
+ // service B is eager loaded, we'll hit this method but eagerLoadProxies will be null. That's OK
+ // ... service B is being realized anyway.
if (def.isEagerLoad() && eagerLoadProxies != null)
eagerLoadProxies.add(delegate);
@@ -351,15 +354,13 @@ public class ModuleImpl implements Modul
private AspectDecorator getAspectDecorator()
{
- return registry.invoke(
- "Obtaining AspectDecorator service",
- new Invokable<AspectDecorator>()
- {
- public AspectDecorator invoke()
- {
- return registry.getService(AspectDecorator.class);
- }
- });
+ return registry.invoke("Obtaining AspectDecorator service", new Invokable<AspectDecorator>()
+ {
+ public AspectDecorator invoke()
+ {
+ return registry.getService(AspectDecorator.class);
+ }
+ });
}
private final Runnable instantiateModule = new Runnable()
@@ -367,13 +368,13 @@ public class ModuleImpl implements Modul
public void run()
{
moduleInstance = registry.invoke("Constructing module class " + moduleDef.getBuilderClass().getName(),
- new Invokable()
- {
- public Object invoke()
- {
- return instantiateModuleInstance();
- }
- });
+ new Invokable()
+ {
+ public Object invoke()
+ {
+ return instantiateModuleInstance();
+ }
+ });
}
};
@@ -381,7 +382,8 @@ public class ModuleImpl implements Modul
{
public Object invoke()
{
- if (moduleInstance == null) BARRIER.withWrite(instantiateModule);
+ if (moduleInstance == null)
+ BARRIER.withWrite(instantiateModule);
return moduleInstance;
}
@@ -398,7 +400,8 @@ public class ModuleImpl implements Modul
Constructor[] constructors = moduleClass.getConstructors();
- if (constructors.length == 0) throw new RuntimeException(IOCMessages.noPublicConstructors(moduleClass));
+ if (constructors.length == 0)
+ throw new RuntimeException(IOCMessages.noPublicConstructors(moduleClass));
if (constructors.length > 1)
{
@@ -439,11 +442,9 @@ public class ModuleImpl implements Modul
{
insideConstructor = true;
- Object[] parameterValues = InternalUtils.calculateParameters(locator, resources,
- constructor.getParameterTypes(),
- constructor.getGenericParameterTypes(),
- constructor.getParameterAnnotations(),
- registry);
+ Object[] parameterValues = InternalUtils.calculateParameters(locator, resources, constructor
+ .getParameterTypes(), constructor.getGenericParameterTypes(),
+ constructor.getParameterAnnotations(), registry);
Object result = constructor.newInstance(parameterValues);
@@ -478,7 +479,7 @@ public class ModuleImpl implements Modul
}
private Object createProxyInstance(ObjectCreator creator, String serviceId, Class serviceInterface,
- String description)
+ String description)
{
ServiceProxyToken token = SerializationSupport.createToken(serviceId);
@@ -487,8 +488,8 @@ public class ModuleImpl implements Modul
classFab.addField("creator", Modifier.PRIVATE | Modifier.FINAL, ObjectCreator.class);
classFab.addField("token", Modifier.PRIVATE | Modifier.FINAL, ServiceProxyToken.class);
- classFab.addConstructor(new Class[] { ObjectCreator.class, ServiceProxyToken.class }, null,
- "{ creator = $1; token = $2; }");
+ classFab.addConstructor(new Class[]
+ { ObjectCreator.class, ServiceProxyToken.class }, null, "{ creator = $1; token = $2; }");
// Make proxies serializable by writing the token to the stream.
@@ -496,8 +497,8 @@ public class ModuleImpl implements Modul
// This is the "magic" signature that allows an object to substitute some other
// object for itself.
- MethodSignature writeReplaceSig = new MethodSignature(Object.class, "writeReplace", null,
- new Class[] { ObjectStreamException.class });
+ MethodSignature writeReplaceSig = new MethodSignature(Object.class, "writeReplace", null, new Class[]
+ { ObjectStreamException.class });
classFab.addMethod(Modifier.PRIVATE, writeReplaceSig, "return token;");
@@ -532,24 +533,25 @@ public class ModuleImpl implements Modul
for (ContributionDef next : moduleDef.getContributionDefs())
{
ContributionDef2 def = InternalUtils.toContributionDef2(next);
-
- if (serviceDef.getServiceId().equals(def.getServiceId()))
+
+ if (serviceDef.getServiceId().equals(def.getServiceId()))
{
result.add(def);
}
else
{
Set<Class> markers = CollectionFactory.newSet(def.getMarkers());
-
- if(markers.contains(Local.class))
+
+ if (markers.contains(Local.class))
{
- if(moduleDef.getServiceDef(serviceDef.getServiceId()) == null)
+ if (moduleDef.getServiceDef(serviceDef.getServiceId()) == null)
continue;
-
+
markers.remove(Local.class);
}
-
- if(serviceDef.getMarkers().equals(markers) && serviceDef.getServiceInterface() == def.getServiceInterface())
+
+ if (serviceDef.getMarkers().equals(markers)
+ && serviceDef.getServiceInterface() == def.getServiceInterface())
{
result.add(def);
}
@@ -558,7 +560,6 @@ public class ModuleImpl implements Modul
return result;
}
-
public ServiceDef2 getServiceDef(String serviceId)
{
@@ -575,4 +576,4 @@ public class ModuleImpl implements Modul
{
return String.format("ModuleImpl[%s]", moduleDef.getLoggerName());
}
-}
\ No newline at end of file
+}
Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreator.java?rev=922145&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreator.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreator.java Fri Mar 12 05:21:12 2010
@@ -0,0 +1,225 @@
+// Copyright 2010 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.tapestry5.ioc.internal;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Constructor;
+import java.net.URL;
+import java.security.ProtectionDomain;
+
+import org.apache.tapestry5.ioc.ObjectCreator;
+import org.apache.tapestry5.ioc.ServiceBuilderResources;
+import org.apache.tapestry5.ioc.internal.util.InternalUtils;
+import org.apache.tapestry5.ioc.services.ClassFabUtils;
+import org.apache.tapestry5.services.UpdateListener;
+import org.slf4j.Logger;
+
+/**
+ * Returns an {@link ObjectCreator} for lazily instantiation a given implementation class (with dependencies).
+ * Once an instance is instantiated, it is cached ... until the underlying .class file changes, at which point
+ * the class is reloaded and a new instance instantiated.
+ */
+public class ReloadableObjectCreator implements ObjectCreator, UpdateListener
+{
+ private class ReloadingClassLoader extends ClassLoader
+ {
+ private ReloadingClassLoader(ClassLoader parent)
+ {
+ super(parent);
+ }
+
+ @Override
+ public Class<?> loadClass(String name) throws ClassNotFoundException
+ {
+ if (isReloadingClass(name))
+ {
+ byte[] classData = readClassData(name);
+
+ return defineClass(name, classData, 0, classData.length);
+ }
+
+ return super.loadClass(name);
+ }
+
+ private boolean isReloadingClass(String name)
+ {
+ // This class loader exists to reload the implementation class and any inner classes of the
+ // implementation class.
+ return name.equals(implementationClassName) || name.startsWith(implementationClassName + "$");
+ }
+ }
+
+ private final ServiceBuilderResources resources;
+
+ private final ClassLoader baseClassLoader;
+
+ private final String implementationClassName;
+
+ private final ProtectionDomain protectionDomain;
+
+ private final String classFilePath;
+
+ private final Logger logger;
+
+ private Object instance;
+
+ private File classFile;
+
+ private long lastModifiedTimestamp = 0;
+
+ private boolean firstTime = true;
+
+ public ReloadableObjectCreator(ServiceBuilderResources resources, ClassLoader baseClassLoader,
+ String implementationClassName, ProtectionDomain protectionDomain)
+ {
+ this.resources = resources;
+ this.baseClassLoader = baseClassLoader;
+ this.implementationClassName = implementationClassName;
+ this.protectionDomain = protectionDomain;
+
+ this.classFilePath = ClassFabUtils.getPathForClassNamed(implementationClassName);
+
+ logger = resources.getLogger();
+ }
+
+ public synchronized void checkForUpdates()
+ {
+ if (instance == null)
+ return;
+
+ if (classFile.lastModified() == lastModifiedTimestamp)
+ return;
+
+ if (logger.isDebugEnabled())
+ logger.debug(String.format("Implementation class %s has changed and will be reloaded on next use.",
+ implementationClassName));
+
+ instance = null;
+ classFile = null;
+ lastModifiedTimestamp = 0;
+ }
+
+ public synchronized Object createObject()
+ {
+ if (instance == null)
+ instance = createInstance();
+
+ return instance;
+ }
+
+ private Object createInstance()
+ {
+ updateTrackingInfo();
+
+ Class reloadedClass = reloadImplementationClass();
+
+ final Constructor constructor = InternalUtils.findAutobuildConstructor(reloadedClass);
+
+ if (constructor == null)
+ throw new RuntimeException(String.format(
+ "Service implementation class %s does not have a suitable public constructor.",
+ implementationClassName));
+
+ ObjectCreator constructorServiceCreator = new ConstructorServiceCreator(resources, String.format(
+ "%s (last modified %tc)", constructor, lastModifiedTimestamp), constructor);
+
+ return constructorServiceCreator.createObject();
+ }
+
+ private Class reloadImplementationClass()
+ {
+ if (logger.isDebugEnabled())
+ logger.debug("%s class %s.", firstTime ? "Loading" : "Reloading", implementationClassName);
+
+ ClassLoader reloadingClassLoader = new ReloadingClassLoader(baseClassLoader);
+
+ try
+ {
+ Class result = reloadingClassLoader.loadClass(implementationClassName);
+
+ firstTime = false;
+
+ return result;
+ }
+ catch (ClassNotFoundException ex)
+ {
+ throw new RuntimeException(String.format("Unable to %s class %s: %s", firstTime ? "load" : "reload",
+ implementationClassName, InternalUtils.toMessage(ex)), ex);
+ }
+ }
+
+ private byte[] readClassData(String name) throws ClassNotFoundException
+ {
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+
+ byte[] buffer = new byte[10000];
+
+ URL url = getURLForClass(name);
+
+ InputStream in = null;
+
+ try
+ {
+ in = url.openStream();
+
+ while (true)
+ {
+ int length = in.read(buffer);
+
+ if (length < 0)
+ break;
+
+ baos.write(buffer, 0, length);
+ }
+
+ in.close();
+
+ in = null;
+ }
+ catch (IOException ex)
+ {
+ InternalUtils.close(in);
+
+ throw new ClassNotFoundException(InternalUtils.toMessage(ex), ex);
+ }
+
+ return baos.toByteArray();
+ }
+
+ private URL getURLForClass(String className) throws ClassNotFoundException
+ {
+ String path = ClassFabUtils.getPathForClassNamed(className);
+
+ URL result = baseClassLoader.getResource(path);
+
+ if (result == null)
+ throw new ClassNotFoundException(String.format("Unable to locate URL for class %s.", className));
+
+ return result;
+ }
+
+ private void updateTrackingInfo()
+ {
+ URL url = baseClassLoader.getResource(classFilePath);
+
+ classFile = ClassFabUtils.toFileFromFileProtocolURL(url);
+
+ lastModifiedTimestamp = classFile.lastModified();
+ }
+
+}
Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreator.java
------------------------------------------------------------------------------
svn:eol-style = native
Added: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreatorSource.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreatorSource.java?rev=922145&view=auto
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreatorSource.java (added)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreatorSource.java Fri Mar 12 05:21:12 2010
@@ -0,0 +1,73 @@
+// Copyright 2010 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.tapestry5.ioc.internal;
+
+import java.lang.reflect.Method;
+
+import org.apache.tapestry5.ioc.ObjectCreator;
+import org.apache.tapestry5.ioc.ServiceBuilderResources;
+import org.apache.tapestry5.ioc.services.ClassFactory;
+import org.apache.tapestry5.services.UpdateListenerHub;
+
+/**
+ * Responsible for creating a {@link ReloadableObjectCreator} for a service implementation.
+ */
+public class ReloadableObjectCreatorSource implements ObjectCreatorSource
+{
+ private final ClassFactory classFactory;
+
+ private final Method bindMethod;
+
+ private final Class serviceInterfaceClass;
+
+ private final Class serviceImplementationClass;
+
+ public ReloadableObjectCreatorSource(ClassFactory classFactory, Method bindMethod, Class serviceInterfaceClass,
+ Class serviceImplementationClass)
+ {
+ this.classFactory = classFactory;
+ this.bindMethod = bindMethod;
+ this.serviceInterfaceClass = serviceInterfaceClass;
+ this.serviceImplementationClass = serviceImplementationClass;
+ }
+
+ public ObjectCreator constructCreator(final ServiceBuilderResources resources)
+ {
+ return new ObjectCreator()
+ {
+ public Object createObject()
+ {
+ return createReloadableProxy(resources);
+ }
+ };
+ }
+
+ public String getDescription()
+ {
+ return String.format("Reloadable %s via %s", serviceImplementationClass.getName(), classFactory
+ .getMethodLocation(bindMethod));
+ }
+
+ private Object createReloadableProxy(ServiceBuilderResources resources)
+ {
+ ReloadableObjectCreator reloadableCreator = new ReloadableObjectCreator(resources, classFactory
+ .getClassLoader(), serviceImplementationClass.getName(), serviceImplementationClass
+ .getProtectionDomain());
+
+ resources.getService(UpdateListenerHub.class).addUpdateListener(reloadableCreator);
+
+ return classFactory.createProxy(serviceInterfaceClass, reloadableCreator, getDescription());
+ }
+}
Propchange: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ReloadableObjectCreatorSource.java
------------------------------------------------------------------------------
svn:eol-style = native
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceBinderImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceBinderImpl.java?rev=922145&r1=922144&r2=922145&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceBinderImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/ServiceBinderImpl.java Fri Mar 12 05:21:12 2010
@@ -4,7 +4,7 @@
// 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
+// 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,
@@ -25,11 +25,13 @@ import org.apache.tapestry5.ioc.internal
import org.apache.tapestry5.ioc.internal.util.Defense;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
import org.apache.tapestry5.ioc.internal.util.OneShotLock;
+import org.apache.tapestry5.ioc.services.ClassFabUtils;
import org.apache.tapestry5.ioc.services.ClassFactory;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
+import java.net.URL;
import java.util.Arrays;
import java.util.Set;
@@ -47,9 +49,8 @@ public class ServiceBinderImpl implement
private final boolean moduleDefaultPreventDecoration;
- public ServiceBinderImpl(ServiceDefAccumulator accumulator, Method bindMethod,
- ClassFactory classFactory,
- Set<Class> defaultMarkers, boolean moduleDefaultPreventDecoration)
+ public ServiceBinderImpl(ServiceDefAccumulator accumulator, Method bindMethod, ClassFactory classFactory,
+ Set<Class> defaultMarkers, boolean moduleDefaultPreventDecoration)
{
this.accumulator = accumulator;
this.bindMethod = bindMethod;
@@ -85,7 +86,8 @@ public class ServiceBinderImpl implement
protected void flush()
{
- if (serviceInterface == null) return;
+ if (serviceInterface == null)
+ return;
// source will be null when the implementation class is provided; non-null when using
// a ServiceBuilder callback
@@ -98,7 +100,7 @@ public class ServiceBinderImpl implement
markers.addAll(this.markers);
ServiceDef serviceDef = new ServiceDefImpl(serviceInterface, serviceId, markers, scope, eagerLoad,
- preventDecoration, source);
+ preventDecoration, source);
accumulator.addServiceDef(serviceDef);
@@ -119,6 +121,38 @@ public class ServiceBinderImpl implement
private ObjectCreatorSource createObjectCreatorSourceFromImplementationClass()
{
+ if (preventDecoration || !isProxiable() || !reloadableScope() || !isLocalFile(serviceImplementation))
+ return createStandardConstructorBasedObjectCreatorSource();
+
+ return createReloadableConstructorBasedObjectCreatorSource();
+ }
+
+ private boolean isProxiable()
+ {
+ return serviceInterface.isInterface();
+ }
+
+ private boolean reloadableScope()
+ {
+ return scope.equalsIgnoreCase(ScopeConstants.DEFAULT);
+ }
+
+ /**
+ * Determines if the indicated class is stored as a locally accessible file
+ * (and not, typically, as a file inside a JAR). This is related to automatic
+ * reloading of services.
+ */
+ private boolean isLocalFile(Class clazz)
+ {
+ String path = ClassFabUtils.getPathForClass(clazz);
+
+ URL classFileURL = clazz.getClassLoader().getResource(path);
+
+ return classFileURL != null && classFileURL.getProtocol().equals("file");
+ }
+
+ private ObjectCreatorSource createStandardConstructorBasedObjectCreatorSource()
+ {
final Constructor constructor = InternalUtils.findAutobuildConstructor(serviceImplementation);
if (constructor == null)
@@ -133,13 +167,17 @@ public class ServiceBinderImpl implement
public String getDescription()
{
- return String.format("%s via %s",
- classFactory.getConstructorLocation(constructor),
- classFactory.getMethodLocation(bindMethod));
+ return String.format("%s via %s", classFactory.getConstructorLocation(constructor), classFactory
+ .getMethodLocation(bindMethod));
}
};
}
+ private ObjectCreatorSource createReloadableConstructorBasedObjectCreatorSource()
+ {
+ return new ReloadableObjectCreatorSource(classFactory, bindMethod, serviceInterface, serviceImplementation);
+ }
+
public <T> ServiceBindingOptions bind(Class<T> serviceClass)
{
if (serviceClass.isInterface())
@@ -148,10 +186,8 @@ public class ServiceBinderImpl implement
{
Class<T> implementationClass = (Class<T>) Class.forName(serviceClass.getName() + "Impl");
- if (!implementationClass.isInterface() && serviceClass.isAssignableFrom(implementationClass))
- {
- return bind(serviceClass, implementationClass);
- }
+ if (!implementationClass.isInterface() && serviceClass.isAssignableFrom(implementationClass)) { return bind(
+ serviceClass, implementationClass); }
throw new RuntimeException(IOCMessages.noServiceMatchesType(serviceClass));
}
catch (ClassNotFoundException ex)
@@ -213,13 +249,12 @@ public class ServiceBinderImpl implement
this.serviceImplementation = serviceImplementation;
// Set defaults for the other properties.
-
-
+
eagerLoad = serviceImplementation.getAnnotation(EagerLoad.class) != null;
-
+
ServiceId serviceIdAnnotation = serviceImplementation.getAnnotation(ServiceId.class);
-
- if(serviceIdAnnotation != null)
+
+ if (serviceIdAnnotation != null)
{
serviceId = serviceIdAnnotation.value();
}
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/ClassFabUtils.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/ClassFabUtils.java?rev=922145&r1=922144&r2=922145&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/ClassFabUtils.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/ClassFabUtils.java Fri Mar 12 05:21:12 2010
@@ -15,11 +15,17 @@
package org.apache.tapestry5.ioc.services;
import org.apache.tapestry5.ioc.ObjectCreator;
+import org.apache.tapestry5.ioc.internal.util.Defense;
+
import static org.apache.tapestry5.ioc.internal.util.CollectionFactory.newMap;
import static java.lang.String.format;
+
+import java.io.File;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.net.URISyntaxException;
+import java.net.URL;
import java.util.Map;
import java.util.concurrent.atomic.AtomicLong;
@@ -292,4 +298,51 @@ public final class ClassFabUtils
throw new RuntimeException(ex.getMessage(), ex);
}
}
+
+ /**
+ * Given a Class instance, convert the name into a path that can be used to locate
+ * the underlying class file on the classpath.
+ *
+ * @since 5.2.0
+ */
+ public static String getPathForClass(Class clazz)
+ {
+ Defense.notNull(clazz, "clazz");
+
+ return getPathForClassNamed(clazz.getName());
+ }
+
+ /**
+ * Given a fully qualified class name, converts to a path on the classpath.
+ *
+ * @since 5.2.0
+ */
+ public static String getPathForClassNamed(String className)
+ {
+ return className.replace('.', '/') + ".class";
+ }
+
+ /**
+ * Converts a URL with protocol "file" to a File instance.
+ *
+ * @since 5.2.0
+ */
+ public static File toFileFromFileProtocolURL(URL url)
+ {
+ Defense.notNull(url, "url");
+
+ if (!url.getProtocol().equals("file"))
+ throw new IllegalArgumentException(String.format("URL %s does not use the 'file' protocol.", url));
+
+ // http://weblogs.java.net/blog/kohsuke/archive/2007/04/how_to_convert.html
+
+ try
+ {
+ return new File(url.toURI());
+ }
+ catch (URISyntaxException ex)
+ {
+ return new File(url.getPath());
+ }
+ }
}
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java?rev=922145&r1=922144&r2=922145&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/IntegrationTest.java Fri Mar 12 05:21:12 2010
@@ -426,8 +426,9 @@ public class IntegrationTest extends IOC
assertMessageContains(
ex,
"Error invoking constructor",
- "ExceptionInConstructorServiceImpl() (at ExceptionInConstructorServiceImpl.java",
- "for service 'Pingable'", "Yes, we have no tomatoes.");
+ "ExceptionInConstructorServiceImpl()",
+ "for service 'Pingable'",
+ "Yes, we have no tomatoes.");
}
r.shutdown();
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/MutlipleAutobuildServiceConstructorsModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/MutlipleAutobuildServiceConstructorsModule.java?rev=922145&r1=922144&r2=922145&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/MutlipleAutobuildServiceConstructorsModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/MutlipleAutobuildServiceConstructorsModule.java Fri Mar 12 05:21:12 2010
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2010 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.
@@ -16,7 +16,9 @@ package org.apache.tapestry5.ioc.interna
import org.apache.tapestry5.ioc.ServiceBinder;
import org.apache.tapestry5.ioc.StringHolder;
+import org.apache.tapestry5.ioc.annotations.PreventServiceDecoration;
+@PreventServiceDecoration
public class MutlipleAutobuildServiceConstructorsModule
{
public static void bind(ServiceBinder binder)
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/UninstantiableAutobuildServiceModule.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/UninstantiableAutobuildServiceModule.java?rev=922145&r1=922144&r2=922145&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/UninstantiableAutobuildServiceModule.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/test/java/org/apache/tapestry5/ioc/internal/UninstantiableAutobuildServiceModule.java Fri Mar 12 05:21:12 2010
@@ -1,4 +1,4 @@
-// Copyright 2007 The Apache Software Foundation
+// Copyright 2007, 2010 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.
@@ -15,7 +15,9 @@
package org.apache.tapestry5.ioc.internal;
import org.apache.tapestry5.ioc.ServiceBinder;
+import org.apache.tapestry5.ioc.annotations.PreventServiceDecoration;
+@PreventServiceDecoration
public class UninstantiableAutobuildServiceModule
{
public static void bind(ServiceBinder binder)