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:02 UTC
svn commit: r922143 - in
/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc:
internal/RegistryImpl.java internal/services/ClassFactoryImpl.java
services/ClassFabUtils.java services/ClassFactory.java
Author: hlship
Date: Fri Mar 12 05:21:02 2010
New Revision: 922143
URL: http://svn.apache.org/viewvc?rev=922143&view=rev
Log:
TAP5-1013: Add new method createProxy() to ClassFactory
Modified:
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClassFactoryImpl.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/ClassFabUtils.java
tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/ClassFactory.java
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java?rev=922143&r1=922142&r2=922143&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/RegistryImpl.java Fri Mar 12 05:21:02 2010
@@ -195,53 +195,49 @@ public class RegistryImpl implements Reg
for (ContributionDef cd : contributionDefs)
{
String serviceId = cd.getServiceId();
-
+
ContributionDef2 cd2 = InternalUtils.toContributionDef2(cd);
-
+
if (cd2.getServiceId() != null)
{
- if (!serviceIdToModule.containsKey(serviceId))
- {
- throw new IllegalArgumentException(IOCMessages.contributionForNonexistentService(cd));
- }
- }
- else if(!isContributionForExistentService(cd2))
- {
- throw new IllegalArgumentException(IOCMessages.contributionForUnqualifiedService(cd2));
+ if (!serviceIdToModule.containsKey(serviceId)) { throw new IllegalArgumentException(IOCMessages
+ .contributionForNonexistentService(cd)); }
}
+ else if (!isContributionForExistentService(cd2)) { throw new IllegalArgumentException(IOCMessages
+ .contributionForUnqualifiedService(cd2)); }
}
-
+
}
-
+
private boolean isContributionForExistentService(ContributionDef2 cd)
{
Set<Class> markers = CollectionFactory.newSet(cd.getMarkers());
- markers.remove(Local.class);
+ markers.remove(Local.class);
for (Class markerClass : markers)
{
boolean exists = existsServiceDefWithTypeAndMarker(cd.getServiceInterface(), markerClass);
-
- if(!exists)
+
+ if (!exists)
return false;
}
-
+
return true;
}
-
+
private boolean existsServiceDefWithTypeAndMarker(Class serviceInterface, Class markerClass)
{
List<ServiceDef2> serviceDefs = markerToServiceDef.get(markerClass);
-
- if(serviceDefs == null)
+
+ if (serviceDefs == null)
return false;
-
+
for (ServiceDef2 serviceDef : serviceDefs)
{
- if(serviceDef.getServiceInterface() == serviceInterface)
+ if (serviceDef.getServiceInterface() == serviceInterface)
return true;
}
-
+
return false;
}
@@ -981,12 +977,8 @@ public class RegistryImpl implements Reg
}
};
- ClassFab cf = classFactory.newClass(interfaceClass);
-
- String description = String.format("<Autobuild proxy %s(%s)>", implementationClass.getName(), interfaceClass
- .getName());
-
- return ClassFabUtils.createObjectCreatorProxy(cf, interfaceClass, justInTime, description);
+ return classFactory.createProxy(interfaceClass, justInTime, String.format("<Autobuild proxy %s(%s)>",
+ implementationClass.getName(), interfaceClass.getName()));
}
public Object provideServiceProxy(String serviceId)
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClassFactoryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClassFactoryImpl.java?rev=922143&r1=922142&r2=922143&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClassFactoryImpl.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/internal/services/ClassFactoryImpl.java Fri Mar 12 05:21:02 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,
@@ -18,16 +18,21 @@ import javassist.CtClass;
import javassist.CtConstructor;
import javassist.CtMethod;
import org.apache.tapestry5.ioc.Location;
+import org.apache.tapestry5.ioc.ObjectCreator;
+
+import static java.lang.String.format;
import static org.apache.tapestry5.ioc.internal.util.Defense.notNull;
import org.apache.tapestry5.ioc.internal.util.InternalUtils;
import org.apache.tapestry5.ioc.services.ClassFab;
import org.apache.tapestry5.ioc.services.ClassFabUtils;
import org.apache.tapestry5.ioc.services.ClassFactory;
+import org.apache.tapestry5.ioc.services.MethodSignature;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
/**
* Implementation of {@link org.apache.tapestry5.ioc.services.ClassFactory}.
@@ -72,7 +77,7 @@ public class ClassFactoryImpl implements
}
public ClassFactoryImpl(ClassLoader classLoader, ClassFactoryClassPool pool, CtClassSource classSource,
- Logger logger)
+ Logger logger)
{
loader = classLoader;
@@ -83,7 +88,6 @@ public class ClassFactoryImpl implements
this.logger = logger;
}
-
public ClassFab newClass(Class serviceInterface)
{
String name = ClassFabUtils.generateClassName(serviceInterface);
@@ -98,8 +102,7 @@ public class ClassFactoryImpl implements
public ClassFab newClass(String name, Class superClass)
{
if (logger.isDebugEnabled())
- logger.debug(String.format("Create ClassFab for %s (extends %s)", name, superClass
- .getName()));
+ logger.debug(String.format("Create ClassFab for %s (extends %s)", name, superClass.getName()));
try
{
@@ -188,7 +191,8 @@ public class ClassFactoryImpl implements
{
Class parameterType = parameterTypes[i];
- if (i > 0) builder.append(", ");
+ if (i > 0)
+ builder.append(", ");
builder.append(parameterType.getSimpleName());
@@ -219,4 +223,37 @@ public class ClassFactoryImpl implements
return new StringLocation(builder.toString(), lineNumber);
}
+
+ public <T> T createProxy(Class<T> proxyInterface, ObjectCreator delegateCreator, String description)
+ {
+ ClassFab classFab = newClass(proxyInterface);
+
+ classFab.addField("_creator", Modifier.PRIVATE | Modifier.FINAL, ObjectCreator.class);
+
+ classFab.addConstructor(new Class[]
+ { ObjectCreator.class }, null, "_creator = $1;");
+
+ String body = format("return (%s) _creator.createObject();", proxyInterface.getName());
+
+ MethodSignature sig = new MethodSignature(proxyInterface, "_delegate", null, null);
+
+ classFab.addMethod(Modifier.PRIVATE, sig, body);
+
+ classFab.proxyMethodsToDelegate(proxyInterface, "_delegate()", description);
+ Class proxyClass = classFab.createClass();
+
+ try
+ {
+ Object proxy = proxyClass.getConstructors()[0].newInstance(delegateCreator);
+
+ return proxyInterface.cast(proxy);
+ }
+ catch (Exception ex)
+ {
+ // This should never happen, so we won't go to a lot of trouble
+ // reporting it.
+ throw new RuntimeException(ex.getMessage(), ex);
+ }
+ }
+
}
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=922143&r1=922142&r2=922143&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:02 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,
@@ -59,7 +59,8 @@ public final class ClassFabUtils
*/
public static String toJavaClassName(Class inputClass)
{
- if (inputClass.isArray()) return toJavaClassName(inputClass.getComponentType()) + "[]";
+ if (inputClass.isArray())
+ return toJavaClassName(inputClass.getComponentType()) + "[]";
return inputClass.getName();
}
@@ -70,9 +71,11 @@ public final class ClassFabUtils
*/
public static boolean isToString(Method method)
{
- if (!method.getName().equals("toString")) return false;
+ if (!method.getName().equals("toString"))
+ return false;
- if (method.getParameterTypes().length > 0) return false;
+ if (method.getParameterTypes().length > 0)
+ return false;
return method.getReturnType().equals(String.class);
}
@@ -132,7 +135,8 @@ public final class ClassFabUtils
public static String toJVMBinaryName(String type)
{
// if it is not an array, just return the type itself
- if (!type.endsWith("[]")) return type;
+ if (!type.endsWith("[]"))
+ return type;
// if it is an array, convert it to JavaVM-style format
StringBuilder buffer = new StringBuilder();
@@ -168,10 +172,11 @@ public final class ClassFabUtils
}
/**
- * Returns the wrapper type for an input type; for most types, this is the type. For primitive types, it is the
+ * Returns the wrapper type for an input type; for most types, this is the type. For primitive types, it is the
* corresponding wrapper type.
- *
- * @param type type to check
+ *
+ * @param type
+ * type to check
* @return type or corresponding wrapper type
*/
public static Class getWrapperType(Class type)
@@ -182,12 +187,14 @@ public final class ClassFabUtils
}
/**
- * Takes a reference and casts it to the desired type. If the desired type is a primitive type, then the reference
+ * Takes a reference and casts it to the desired type. If the desired type is a primitive type, then the reference
* is cast to the correct wrapper type and a call to the correct unwrapper method is added. The end result is code
* that can be assigned to a field or parameter of the desired type (even if desired type is a primitive).
- *
- * @param reference to be cast
- * @param desiredType desired object or primitive type
+ *
+ * @param reference
+ * to be cast
+ * @param desiredType
+ * desired object or primitive type
* @return Javassist code to peform the cast
*/
public static String castReference(String reference, String desiredType)
@@ -196,9 +203,7 @@ public final class ClassFabUtils
{
PrimitiveInfo info = PRIMITIVE_TYPE_NAME_TO_PRIMITIVE_INFO.get(desiredType);
- return String.format("((%s)%s).%s()",
- info.wrapperType.getName(), reference,
- info.unwrapMethod);
+ return String.format("((%s)%s).%s()", info.wrapperType.getName(), reference, info.unwrapMethod);
}
return String.format("(%s)%s", desiredType, reference);
@@ -206,7 +211,7 @@ public final class ClassFabUtils
/**
* Given a primitive type, finds the unwrap method of the corresponding wrapper type.
- *
+ *
* @param primitiveType
* @return method name
*/
@@ -215,7 +220,6 @@ public final class ClassFabUtils
return PRIMITIVE_TYPE_NAME_TO_PRIMITIVE_INFO.get(primitiveType.getName()).unwrapMethod;
}
-
/**
* Given a type name, determines if that is the name of a primitive type.
*/
@@ -229,11 +233,14 @@ public final class ClassFabUtils
*/
public static String getTypeCode(Class type)
{
- if (type.equals(void.class)) return "V";
+ if (type.equals(void.class))
+ return "V";
- if (type.isPrimitive()) return PRIMITIVE_TYPE_NAME_TO_PRIMITIVE_INFO.get(type.getName()).typeCode;
+ if (type.isPrimitive())
+ return PRIMITIVE_TYPE_NAME_TO_PRIMITIVE_INFO.get(type.getName()).typeCode;
- if (type.isArray()) return "[" + getTypeCode(type.getComponentType());
+ if (type.isArray())
+ return "[" + getTypeCode(type.getComponentType());
return "L" + type.getName().replace('.', '/') + ";";
}
@@ -242,20 +249,26 @@ public final class ClassFabUtils
* Creates a proxy for a given service interface around an {@link org.apache.tapestry5.ioc.ObjectCreator} that can
* provide (on demand) an object (implementing the service interface) to delegate to. The ObjectCreator will be
* invoked on every method invocation (if it is caching, that should be internal to its implementation).
- *
+ *
* @param <T>
- * @param classFab used to create the new class
- * @param serviceInterface the interface the proxy will implement
- * @param creator the createor which will provide an instance of the interface
- * @param description description to be returned from the proxy's toString() method
+ * @param classFab
+ * used to create the new class
+ * @param serviceInterface
+ * the interface the proxy will implement
+ * @param creator
+ * the createor which will provide an instance of the interface
+ * @param description
+ * description to be returned from the proxy's toString() method
* @return the instantiated proxy object
+ * @deprecated Use {@link ClassFactory#createProxy(Class, ObjectCreator, String)} instead
*/
public static <T> T createObjectCreatorProxy(ClassFab classFab, Class<T> serviceInterface, ObjectCreator creator,
- String description)
+ String description)
{
classFab.addField("_creator", Modifier.PRIVATE | Modifier.FINAL, ObjectCreator.class);
- classFab.addConstructor(new Class[] {ObjectCreator.class}, null, "_creator = $1;");
+ classFab.addConstructor(new Class[]
+ { ObjectCreator.class }, null, "_creator = $1;");
String body = format("return (%s) _creator.createObject();", serviceInterface.getName());
Modified: tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/ClassFactory.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/ClassFactory.java?rev=922143&r1=922142&r2=922143&view=diff
==============================================================================
--- tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/ClassFactory.java (original)
+++ tapestry/tapestry5/trunk/tapestry-ioc/src/main/java/org/apache/tapestry5/ioc/services/ClassFactory.java Fri Mar 12 05:21:02 2010
@@ -1,10 +1,10 @@
-// Copyright 2006, 2007 The Apache Software Foundation
+// Copyright 2006, 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.
// 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,
@@ -15,6 +15,7 @@
package org.apache.tapestry5.ioc.services;
import org.apache.tapestry5.ioc.Location;
+import org.apache.tapestry5.ioc.ObjectCreator;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
@@ -28,7 +29,7 @@ public interface ClassFactory
* Simplified version of {@link #newClass(String, Class)} that generates a name based on the service interface name,
* extends from java.lang.Object, and automatically adds the serviceInterface to the returned ClassFab. This is the
* most common use when creating the kinds of proxies used throughout Tapestry IoC.
- *
+ *
* @param serviceInterface
*/
ClassFab newClass(Class serviceInterface);
@@ -36,10 +37,12 @@ public interface ClassFactory
/**
* Creates a {@link ClassFab} object for the given name; the new class is a subclass of the indicated class. The new
* class is always public and concrete.
- *
- * @param name the full qualified name of the class to create (note that it is common to place created classes
- * in the default package)
- * @param superClass the parent class, which is often java.lang.Object
+ *
+ * @param name
+ * the full qualified name of the class to create (note that it is common to place created classes
+ * in the default package)
+ * @param superClass
+ * the parent class, which is often java.lang.Object
*/
ClassFab newClass(String name, Class superClass);
@@ -49,9 +52,9 @@ public interface ClassFactory
* class path. The class itself is returned, if its bytecode is available. If not, a search up the inhertance occurs
* until a proper class (that can be referenced in generated bytecode) is found. This is necessary to handle cases
* where a class is generated at runtime, outside of the class factory, and bytecode is not available for it.
- *
+ *
* @param clazz
- * @return a referencable super-class
+ * @return a referenceable super-class
*/
Class importClass(Class clazz);
@@ -69,15 +72,32 @@ public interface ClassFactory
/**
* Converts a method to a {@link Location}, which includes information about the source file name and line number.
- *
- * @param method to look up
+ *
+ * @param method
+ * to look up
* @return the location, or null if the necessary information is not available
*/
Location getMethodLocation(Method method);
/**
- * Return a string representation fo the constructor (including class and parameters) and (if available) file name
+ * Return a string representation for the constructor (including class and parameters) and (if available) file name
* and line number.
*/
Location getConstructorLocation(Constructor constructor);
+
+ /**
+ * Creates a proxy for an interface. All methods of the interface are delegated through the
+ * object returned from the {@link ObjectCreator} (which is accessed on each method invocation, so it
+ * is responsible for caching of the true delegate). The description will be used for the toString() method
+ * (unless toString() is part of the proxy interface).
+ *
+ * @param <T>
+ * type of proxy
+ * @param proxyInterface
+ * proxy interface class
+ * @param description
+ * used for the toString() method
+ * @since 5.2.0
+ */
+ <T> T createProxy(Class<T> proxyInterface, ObjectCreator delegateCreator, String description);
}