You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tapestry.apache.org by hl...@apache.org on 2006/07/22 15:57:04 UTC
svn commit: r424577 - in /tapestry/tapestry5/tapestry-core/trunk/src:
main/java/org/apache/tapestry/annotations/
main/java/org/apache/tapestry/internal/ioc/
main/java/org/apache/tapestry/internal/ioc/services/
main/java/org/apache/tapestry/ioc/ test/ja...
Author: hlship
Date: Sat Jul 22 06:57:04 2006
New Revision: 424577
URL: http://svn.apache.org/viewvc?rev=424577&view=rev
Log:
Move TapestryIOCModule under src/main/java, where it belongs.
Move methods of IdUtils to IOCUtilities.
Add the @Match annotation, used to "target" decorators at services.
Start work on a LoggingDecorator service.
Added:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/Match.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/TapestryIOCModule.java
- copied, changed from r424052, tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/TapestryIOCModule.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/Logger.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/LoggingDecoratorImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/LoggingDecorator.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/IOCUtilitiesTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/LoggerTest.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IOCUtilitiesTest.java
- copied, changed from r424052, tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/TestIdUtils.java
Removed:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/IdUtils.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/TapestryIOCModule.java
tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/TestIdUtils.java
Modified:
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DecoratorDefImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCUtilities.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/RegistryImpl.java
tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/IOCUtilities.java
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/Match.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/Match.java?rev=424577&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/Match.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/annotations/Match.java Sat Jul 22 06:57:04 2006
@@ -0,0 +1,36 @@
+package org.apache.tapestry.annotations;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * Optional, but typically used, annotation for service decorator methods, used to define which
+ * services the decorator applies to. This annotation defines a number of <em>patterns</em> that
+ * allow services across multiple modules to be selected. A decorator is applied to a service if any
+ * of its patterns match the service.
+ * <p>
+ * TODO: Describe pattern glob-match syntax
+ * <p>
+ * When the Match annotation is not supplied, then the decorator only applies to a single service:
+ * the service whose id matches the decorators id; that is, method <code>decorateMyService()</code>
+ * would decorate only the service provided by the <code>buildMyService()</code> method, within
+ * the same module.
+ *
+ * @author Howard M. Lewis Ship
+ */
+@Target(METHOD)
+@Retention(RUNTIME)
+@Documented
+public @interface Match {
+
+ /**
+ * Defines a list of patterns matched against potential service ids to identify to which
+ * services the decorator applies. A decorator is applied if <em>any</em> of the patterns
+ * match.
+ */
+ String[] value();
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DecoratorDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DecoratorDefImpl.java?rev=424577&r1=424576&r2=424577&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DecoratorDefImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DecoratorDefImpl.java Sat Jul 22 06:57:04 2006
@@ -14,6 +14,8 @@
package org.apache.tapestry.internal.ioc;
+import static org.apache.tapestry.internal.ioc.IOCUtilities.decoratorMatch;
+import static org.apache.tapestry.ioc.IOCUtilities.extractModuleId;
import static org.apache.tapestry.util.Defense.notBlank;
import static org.apache.tapestry.util.Defense.notNull;
@@ -25,7 +27,6 @@
import org.apache.tapestry.ioc.ServiceResources;
import org.apache.tapestry.ioc.def.DecoratorDef;
import org.apache.tapestry.ioc.def.ServiceDef;
-import org.apache.tapestry.util.Defense;
/**
* @author Howard M. Lewis Ship
@@ -40,13 +41,17 @@
private final Method _decoratorMethod;
+ private final String[] _patterns;
+
@SuppressNullCheck
- public DecoratorDefImpl(String decoratorId, String before, String after, Method decoratorMethod)
+ public DecoratorDefImpl(String decoratorId, String before, String after,
+ Method decoratorMethod, String[] patterns)
{
_decoratorId = notBlank(decoratorId, "decoratorId");
_before = before;
_after = after;
_decoratorMethod = notNull(decoratorMethod, "decoratorMethod");
+ _patterns = notNull(patterns, "patterns");
}
@Override
@@ -72,12 +77,23 @@
public ServiceDecorator createDecorator(Object moduleBuilder, ServiceResources resources)
{
- return null;
+ return new ServiceDecoratorImpl(_decoratorMethod, moduleBuilder, resources);
}
- /** Currently just returns false. */
+ /**
+ * Returns true if <em>any</em> provided pattern matches the id of the service.
+ */
public boolean matches(ServiceDef serviceDef)
{
+ String serviceId = serviceDef.getServiceId();
+ String decoratorModuleId = extractModuleId(_decoratorId);
+
+ for (String pattern : _patterns)
+ {
+ if (decoratorMatch(serviceId, decoratorModuleId, pattern))
+ return true;
+ }
+
return false;
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImpl.java?rev=424577&r1=424576&r2=424577&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/DefaultModuleDefImpl.java Sat Jul 22 06:57:04 2006
@@ -17,6 +17,7 @@
import static org.apache.tapestry.internal.ioc.IOCMessages.buildMethodConflict;
import static org.apache.tapestry.internal.ioc.IOCMessages.buildMethodWrongReturnType;
import static org.apache.tapestry.internal.ioc.IOCMessages.decoratorMethodWrongReturnType;
+import static org.apache.tapestry.ioc.IOCUtilities.qualifySimpleIdList;
import static org.apache.tapestry.util.CollectionFactory.newMap;
import static org.apache.tapestry.util.CollectionFactory.newSet;
@@ -29,8 +30,8 @@
import java.util.Set;
import org.apache.commons.logging.Log;
+import org.apache.tapestry.annotations.Match;
import org.apache.tapestry.ioc.IOCConstants;
-import org.apache.tapestry.ioc.IdUtils;
import org.apache.tapestry.ioc.annotations.After;
import org.apache.tapestry.ioc.annotations.Before;
import org.apache.tapestry.ioc.annotations.Id;
@@ -41,16 +42,18 @@
import org.apache.tapestry.ioc.def.ServiceDef;
/**
- * Grinds through a module builder class, identifying all the services and contributions.
+ * Starting from the Class for a module builder, identifies all the services (service builder
+ * methods), decorators (service decorator methods) and (not yet implemented) contributions (service
+ * contributor methods).
*
* @author Howard M. Lewis Ship
*/
public class DefaultModuleDefImpl implements ModuleDef
{
- /** The prefix used to identify service building methods. */
+ /** The prefix used to identify service builder methods. */
private static final String BUILD_METHOD_NAME_PREFIX = "build";
- /** The prefix used to identify service decorating methods. */
+ /** The prefix used to identify service decorator methods. */
private static final String DECORATE_METHOD_NAME_PREFIX = "decorate";
private final Class _builderClass;
@@ -154,23 +157,24 @@
if (name.startsWith(BUILD_METHOD_NAME_PREFIX))
{
- addServiceBuildMethod(m);
+ addServiceDef(m);
continue;
}
if (name.startsWith(DECORATE_METHOD_NAME_PREFIX))
{
- addDecorateMethod(m);
+ addDecoratorDef(m);
continue;
}
}
}
- private void addDecorateMethod(Method method)
+ private void addDecoratorDef(Method method)
{
// TODO: methods just named "decorate"
- String id = _moduleId + "." + stripMethodPrefix(method, DECORATE_METHOD_NAME_PREFIX);
+ String simpleDecoratorId = stripMethodPrefix(method, DECORATE_METHOD_NAME_PREFIX);
+ String id = _moduleId + "." + simpleDecoratorId;
// TODO: Check for duplicates
@@ -193,15 +197,18 @@
After afterAnnotation = method.getAnnotation(After.class);
Before beforeAnnotation = method.getAnnotation(Before.class);
+ Match match = method.getAnnotation(Match.class);
- String after = afterAnnotation == null ? null : IdUtils.qualifyList(
+ String after = afterAnnotation == null ? null : qualifySimpleIdList(
_moduleId,
afterAnnotation.value());
- String before = beforeAnnotation == null ? null : IdUtils.qualifyList(
+ String before = beforeAnnotation == null ? null : qualifySimpleIdList(
_moduleId,
beforeAnnotation.value());
+ String[] patterns = match == null ? new String[]
+ { simpleDecoratorId } : match.value();
- DecoratorDef def = new DecoratorDefImpl(id, before, after, method);
+ DecoratorDef def = new DecoratorDefImpl(id, before, after, method, patterns);
_decoratorDefs.put(id, def);
}
@@ -226,13 +233,12 @@
}
/** Invoked for public methods that have the proper prefix. */
- private void addServiceBuildMethod(Method method)
+ private void addServiceDef(Method method)
{
// TODO: Methods named just "build"
String serviceId = _moduleId + "." + stripMethodPrefix(method, BUILD_METHOD_NAME_PREFIX);
ServiceDef existing = _serviceDefs.get(serviceId);
-
if (existing != null)
{
_log.warn(buildMethodConflict(method, existing.toString()), null);
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCUtilities.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCUtilities.java?rev=424577&r1=424576&r2=424577&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCUtilities.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/IOCUtilities.java Sat Jul 22 06:57:04 2006
@@ -28,9 +28,18 @@
* @author Howard M. Lewis Ship
*/
@Utility
-public class IOCUtilities
+public final class IOCUtilities
{
-
+ /**
+ * Finds a specific annotation type within an array of annotations.
+ *
+ * @param <T>
+ * @param annotations
+ * to search
+ * @param annotationClass
+ * to match
+ * @return the annotation instance, if found, or null otherwise
+ */
public static <T extends Annotation> T findAnnotation(Annotation[] annotations,
Class<T> annotationClass)
{
@@ -39,7 +48,7 @@
if (annotationClass.isInstance(a))
return annotationClass.cast(a);
}
-
+
return null;
}
@@ -49,25 +58,25 @@
Map<Class, Object> parameterDefaults)
{
InjectService is = findAnnotation(parameterAnnotations, InjectService.class);
-
+
if (is != null)
{
String serviceId = is.value();
-
+
return serviceResources.getService(serviceId, parameterType);
}
-
+
// See if we have any "pre-determined" parameter type to object mappings
-
+
Object result = parameterDefaults.get(parameterType);
-
+
// This will return a non-null value, or throw an exception
-
+
if (result == null)
result = serviceResources.getService(parameterType);
-
+
// ... so the result is never null
-
+
return result;
}
@@ -77,9 +86,9 @@
Class[] parameterTypes = method.getParameterTypes();
Annotation[][] annotations = method.getParameterAnnotations();
int parameterCount = parameterTypes.length;
-
+
Object[] parameters = new Object[parameterCount];
-
+
for (int i = 0; i < parameterCount; i++)
{
parameters[i] = calculateParameterValue(
@@ -88,7 +97,86 @@
serviceResources,
parameterDefaults);
}
+
return parameters;
+ }
+
+ /**
+ * Checks to see if a string matches against a "glob pattern". A glob pattern is a string to
+ * match that may contain a leading or trailing asterisk ("*"), or may consist of only an
+ * asterisk. The asterisk matches any sequence of characters (including the empty string). The
+ * term "glob" comes from POSIX tools, though this is a very limited subset.
+ * <p>
+ * I'm not happy with the efficiency and utility of this class, so for the moment, it's going to
+ * stay as internal.
+ *
+ * @param input
+ * @param pattern
+ * @return true if the input matches the pattern, false otherwise
+ */
+ public static boolean globMatch(String input, String pattern)
+ {
+ if (pattern.equals("*"))
+ return true;
+
+ boolean globPrefix = pattern.startsWith("*");
+ boolean globSuffix = pattern.endsWith("*");
+
+ if (globPrefix && globSuffix)
+ {
+ String substring = pattern.substring(1, pattern.length() - 1);
+ return input.contains(substring);
+ }
+
+ if (globPrefix)
+ return input.endsWith(pattern.substring(1));
+
+ if (globSuffix)
+ return input.startsWith(pattern.substring(0, pattern.length() - 1));
+
+ // No globs!
+
+ return input.equals(pattern);
+ }
+
+ /**
+ * Used by the default implementation of {@link org.apache.tapestry.ioc.def.DecoratorDef} to
+ * match a pattern against a prospective service id. The pattern is either simple or qualified.
+ * A simple pattern contains no '.' character, in which case the pattern is matched against just
+ * the simple id portion of the service id and a match can only occur within the same module as
+ * the decorator. Alternately, with a complex pattern, such as <code>foo.bar.*.*Data*</code>
+ * is really two matches: <code>foo.bar.*</code> against the module id portion of the
+ * service's id, and <code>*Data*</code> against the unqualified portion of the service id.
+ * The split occurs on the <em>last</em> period character.
+ *
+ * @param serviceId
+ * the fully qualified id of the service to match against
+ * @param decoratorModuleId
+ * the id of the module containing the decorator, used when the pattern is simple
+ * @param pattern
+ * the pattern to match against serviceId
+ * @return true if the service id matches the pattern, false otherwise
+ */
+ public static boolean decoratorMatch(String serviceId, String decoratorModuleId, String pattern)
+ {
+ int dotx = serviceId.lastIndexOf('.');
+
+ String serviceModuleId = serviceId.substring(0, dotx);
+ String serviceSimpleId = serviceId.substring(dotx + 1);
+
+ dotx = pattern.lastIndexOf('.');
+
+ // Simple patterns only match within their own module and the pattern
+ // matches the unqualified service id
+
+ if (dotx <= 0)
+ return serviceModuleId.equals(decoratorModuleId) && globMatch(serviceSimpleId, pattern);
+
+ String moduleIdPattern = pattern.substring(0, dotx);
+ String servicePattern = pattern.substring(dotx + 1);
+
+ return globMatch(serviceModuleId, moduleIdPattern)
+ && globMatch(serviceSimpleId, servicePattern);
}
}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/RegistryImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/RegistryImpl.java?rev=424577&r1=424576&r2=424577&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/RegistryImpl.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/RegistryImpl.java Sat Jul 22 06:57:04 2006
@@ -26,7 +26,7 @@
import org.apache.commons.logging.Log;
import org.apache.tapestry.internal.annotations.SuppressNullCheck;
import org.apache.tapestry.internal.util.Orderer;
-import org.apache.tapestry.ioc.IdUtils;
+import org.apache.tapestry.ioc.IOCUtilities;
import org.apache.tapestry.ioc.LogSource;
import org.apache.tapestry.ioc.Registry;
import org.apache.tapestry.ioc.ServiceDecorator;
@@ -87,7 +87,7 @@
private Module locateModuleForService(String serviceId)
{
- String moduleId = IdUtils.extractModule(serviceId);
+ String moduleId = IOCUtilities.extractModuleId(serviceId);
Module module = _modules.get(moduleId);
@@ -171,7 +171,7 @@
for (DecoratorDef dd : ordered)
{
- String decoratorModuleId = IdUtils.extractModule(dd.getDecoratorId());
+ String decoratorModuleId = IOCUtilities.extractModuleId(dd.getDecoratorId());
// Whenever the module id containing the decorator changes,
// "refresh" the resources, etc., to point to the (new) module.
@@ -222,7 +222,7 @@
private Set<DecoratorDef> findDecoratorsDefsForPrivateService(ServiceDef serviceDef)
{
- String moduleId = IdUtils.extractModule(serviceDef.getServiceId());
+ String moduleId = IOCUtilities.extractModuleId(serviceDef.getServiceId());
Module module = _modules.get(moduleId);
return module.findMatchingDecoratorDefs(serviceDef);
Copied: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/TapestryIOCModule.java (from r424052, tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/TapestryIOCModule.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/TapestryIOCModule.java?p2=tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/TapestryIOCModule.java&p1=tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/TapestryIOCModule.java&r1=424052&r2=424577&rev=424577&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/TapestryIOCModule.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/TapestryIOCModule.java Sat Jul 22 06:57:04 2006
@@ -15,10 +15,18 @@
package org.apache.tapestry.internal.ioc;
import org.apache.tapestry.internal.ioc.services.ClassFactoryImpl;
+import org.apache.tapestry.internal.ioc.services.LoggingDecoratorImpl;
+import org.apache.tapestry.ioc.LoggingDecorator;
import org.apache.tapestry.ioc.annotations.Id;
+import org.apache.tapestry.ioc.annotations.InjectService;
import org.apache.tapestry.ioc.annotations.Lifecycle;
import org.apache.tapestry.ioc.services.ClassFactory;
+/**
+ * Defines the base set of services for the Tapestry IOC container.
+ *
+ * @author Howard M. Lewis Ship
+ */
@Id("tapestry.ioc")
public class TapestryIOCModule
{
@@ -26,5 +34,11 @@
public ClassFactory buildClassFactory()
{
return new ClassFactoryImpl();
+ }
+
+ public LoggingDecorator buildLoggingDecorator(@InjectService("ClassFactory")
+ ClassFactory classFactory)
+ {
+ return new LoggingDecoratorImpl(classFactory);
}
}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/Logger.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/Logger.java?rev=424577&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/Logger.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/Logger.java Sat Jul 22 06:57:04 2006
@@ -0,0 +1,155 @@
+package org.apache.tapestry.internal.ioc.services;
+
+import static java.lang.String.format;
+
+import java.util.Iterator;
+
+import org.apache.commons.logging.Log;
+
+/**
+ * Used by {@link org.apache.tapestry.internal.ioc.services.LoggingDecoratorImpl} to delegate out
+ * logging behavior to a seperate object (helps ensure no naming conflicts).
+ *
+ * @author Howard M. Lewis Ship
+ */
+public final class Logger
+{
+ private final Log _log;
+
+ private static final String ENTER = "ENTER";
+
+ private static final String EXIT = " EXIT";
+
+ private static final String FAIL = " FAIL";
+
+ public Logger(Log log)
+ {
+ _log = log;
+ }
+
+ /** Returns true if the debugging is enabled for the underlying Log. */
+ public boolean isDebugEnabled()
+ {
+ return _log.isDebugEnabled();
+ }
+
+ /**
+ * Invoked when a method is first entered
+ *
+ * @param name
+ * of the method
+ * @param arguments
+ */
+ public void entry(String name, Object[] arguments)
+ {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append(format("[%s] %s(", ENTER, name));
+
+ for (int i = 0; i < arguments.length; i++)
+ {
+ if (i > 0)
+ buffer.append(", ");
+
+ convert(buffer, arguments[i]);
+ }
+
+ buffer.append(")");
+
+ _log.debug(buffer.toString());
+ }
+
+ private void convert(StringBuffer buffer, Object object)
+ {
+ if (object == null)
+ {
+ buffer.append("null");
+ return;
+ }
+
+ // Minimal, alas: Doesn't handle embedded quotes and other
+ // characters. Really want to convert the string back to what it
+ // would look like as source code.
+
+ if (object instanceof String)
+ {
+ buffer.append("\"");
+ buffer.append(object.toString());
+ buffer.append("\"");
+ return;
+ }
+
+ if (object instanceof Object[])
+ {
+ Object[] values = (Object[]) object;
+ buffer.append('{');
+
+ for (int i = 0; i < values.length; i++)
+ {
+ if (i > 0)
+ buffer.append(", ");
+
+ convert(buffer, values[i]);
+ }
+
+ buffer.append('}');
+ return;
+ }
+
+ if (object instanceof Iterable)
+ {
+ Iterable itr = (Iterable) object;
+ boolean first = true;
+
+ buffer.append('[');
+ Iterator i = itr.iterator();
+ while (i.hasNext())
+ {
+ if (!first)
+ buffer.append(", ");
+
+ convert(buffer, i.next());
+ first = false;
+ }
+ buffer.append(']');
+ return;
+ }
+
+ // Might need to add a few more, for things like character values ...
+
+ buffer.append(object.toString());
+ }
+
+ /**
+ * Invoked when a method returns a value
+ *
+ * @param name
+ * of the method
+ * @param result
+ * the return value for the method invocation
+ */
+ public void exit(String name, Object result)
+ {
+ StringBuffer buffer = new StringBuffer();
+
+ buffer.append(format("[%s] %s [", EXIT, name));
+
+ convert(buffer, result);
+
+ buffer.append(']');
+
+ _log.debug(buffer.toString());
+ }
+
+ /** Invoked when void method finishes succesfully. */
+ public void voidExit(String name)
+ {
+ _log.debug(format("[%s] %s", EXIT, name));
+ }
+
+ /** Invoked when method invocation instead throws an exception. */
+ public void fail(String name, Throwable t)
+ {
+ _log.debug(format("[%s] %s -- %s", FAIL, name, t.getClass().getName()), t);
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/LoggingDecoratorImpl.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/LoggingDecoratorImpl.java?rev=424577&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/LoggingDecoratorImpl.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/internal/ioc/services/LoggingDecoratorImpl.java Sat Jul 22 06:57:04 2006
@@ -0,0 +1,23 @@
+package org.apache.tapestry.internal.ioc.services;
+
+import org.apache.tapestry.ioc.LoggingDecorator;
+import org.apache.tapestry.ioc.services.ClassFactory;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class LoggingDecoratorImpl implements LoggingDecorator
+{
+ private final ClassFactory _classFactory;
+
+ public LoggingDecoratorImpl(ClassFactory classFactory)
+ {
+ _classFactory = classFactory;
+ }
+
+ public <T> T createLoggingInterceptor(Class<T> serviceInterface, T delegate)
+ {
+ return null;
+ }
+
+}
Modified: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/IOCUtilities.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/IOCUtilities.java?rev=424577&r1=424576&r2=424577&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/IOCUtilities.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/IOCUtilities.java Sat Jul 22 06:57:04 2006
@@ -21,10 +21,17 @@
import java.util.Enumeration;
import java.util.jar.Manifest;
+import org.apache.tapestry.internal.annotations.SuppressNullCheck;
import org.apache.tapestry.internal.annotations.Utility;
import static org.apache.tapestry.ioc.IOCConstants.MODULE_BUILDER_MANIFEST_ENTRY_NAME;
+/**
+ * A collection of utility methods for a couple of different areas, including creating the initial
+ * {@link org.apache.tapestry.ioc.Registry}.
+ *
+ * @author Howard M. Lewis Ship
+ */
@Utility
public final class IOCUtilities
{
@@ -125,5 +132,71 @@
// Ignore.
}
}
+ }
+
+ public static boolean match(String serviceId, String moduleId, String pattern)
+ {
+ return true;
+ }
+
+ /**
+ * Returns a fully qualfied id. If the id contains a '.', then it is returned unchanged.
+ * Otherwise, the module's id is prefixed (with a seperator '.') and returned;
+ */
+ public static String toQualifiedId(String moduleId, String id)
+ {
+ if (id.indexOf('.') > 0)
+ return id;
+
+ return moduleId + "." + id;
+ }
+
+ /**
+ * Qualifies a list of interceptor service ids provided for an interceptor contribution. The
+ * special value "*" is not qualified.
+ */
+ @SuppressNullCheck
+ public static String qualifySimpleIdList(String sourceModuleId, String list)
+ {
+ if (list == null || list.equals("") || list.equals("*"))
+ return list;
+
+ String[] items = list.split("\\s*,\\s*");
+
+ StringBuffer buffer = new StringBuffer();
+
+ for (int i = 0; i < items.length; i++)
+ {
+ if (i > 0)
+ buffer.append(",");
+
+ buffer.append(toQualifiedId(sourceModuleId, items[i]));
+ }
+
+ return buffer.toString();
+ }
+
+ /**
+ * Removes the module name from a fully qualified id
+ */
+ public static String toSimpleId(String id)
+ {
+ int lastPoint = id.lastIndexOf('.');
+ if (lastPoint > 0)
+ return id.substring(lastPoint + 1, id.length());
+
+ return id;
+ }
+
+ /**
+ * Extracts the module name from a fully qualified id Returns null if id contains no module
+ */
+ public static String extractModuleId(String id)
+ {
+ int lastPoint = id.lastIndexOf('.');
+ if (lastPoint > 0)
+ return id.substring(0, lastPoint);
+
+ return null;
}
}
Added: tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/LoggingDecorator.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/LoggingDecorator.java?rev=424577&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/LoggingDecorator.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/main/java/org/apache/tapestry/ioc/LoggingDecorator.java Sat Jul 22 06:57:04 2006
@@ -0,0 +1,23 @@
+package org.apache.tapestry.ioc;
+
+/**
+ * Service that can create a logging interceptor that wraps around a service implementation (or
+ * interceptor).
+ *
+ * @author Howard M. Lewis Ship
+ */
+public interface LoggingDecorator
+{
+ /**
+ * Creates the logging interceptor.
+ *
+ * @param <T>
+ * @param serviceInterface
+ * interface implemented by the delegate
+ * @param delegate
+ * existing object to be wrapped
+ * @return a new object implementing the interface that can be used in place of the delegate,
+ * providing logging behavior around each method call on the service interface
+ */
+ <T> T createLoggingInterceptor(Class<T> serviceInterface, T delegate);
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/IOCUtilitiesTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/IOCUtilitiesTest.java?rev=424577&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/IOCUtilitiesTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/IOCUtilitiesTest.java Sat Jul 22 06:57:04 2006
@@ -0,0 +1,78 @@
+package org.apache.tapestry.internal.ioc;
+
+import static org.apache.tapestry.internal.ioc.IOCUtilities.decoratorMatch;
+import static org.apache.tapestry.internal.ioc.IOCUtilities.globMatch;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import org.testng.annotations.Test;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class IOCUtilitiesTest
+{
+ @Test
+ public void glob_match_exact()
+ {
+ assertTrue(globMatch("fred", "fred"));
+ assertFalse(globMatch("xfred", "fred"));
+ assertFalse(globMatch("fredx", "fred"));
+ assertFalse(globMatch("fred", "xfred"));
+ assertFalse(globMatch("fred", "fredx"));
+ }
+
+ @Test
+ public void glob_match_wild()
+ {
+ assertTrue(globMatch("fred", "*"));
+ assertTrue(globMatch("", "*"));
+ }
+
+ @Test
+ public void glob_match_prefix()
+ {
+ assertTrue(globMatch("fred.Barney", "*Barney"));
+ assertFalse(globMatch("fred.Barneyx", "*Barney"));
+ assertFalse(globMatch("fred.Barney", "*Barneyx"));
+ assertFalse(globMatch("fred.Barney", "*xBarney"));
+ }
+
+ @Test
+ public void glob_match_suffix()
+ {
+ assertTrue(globMatch("fred.Barney", "fred*"));
+ assertFalse(globMatch("xfred.Barney", "fred*"));
+ assertFalse(globMatch("fred.Barney", "fredx*"));
+ assertFalse(globMatch("fred.Barney", "xfred*"));
+ }
+
+ @Test
+ public void glob_match_infix()
+ {
+ assertTrue(globMatch("fred.Barney", "*d.B*"));
+ assertTrue(globMatch("fred.Barney", "*Barney*"));
+ assertTrue(globMatch("fred.Barney", "*fred*"));
+ assertFalse(globMatch("fred.Barney", "*flint*"));
+ }
+
+ @Test
+ public void decorator_match_simple()
+ {
+ assertTrue(decoratorMatch("foo.bar.Baz", "foo.bar", "Baz"));
+ assertFalse(decoratorMatch("foo.bar.Baz", "fie.foo", "Baz"));
+ assertTrue(decoratorMatch("foo.bar.Baz", "foo.bar", "*az"));
+ assertTrue(decoratorMatch("foo.bar.Baz", "foo.bar", "Ba*"));
+ assertTrue(decoratorMatch("foo.bar.Baz", "foo.bar", "*a*"));
+ }
+
+ @Test
+ public void decorate_match_complex()
+ {
+ assertTrue(decoratorMatch("foo.bar.Baz", "foo.bar", "foo*.Baz"));
+ assertTrue(decoratorMatch("foo.bar.Baz", "foo.bar", "*.Baz"));
+ assertTrue(decoratorMatch("foo.bar.Baz", "foo.bar", "foo.bar.*az"));
+ assertFalse(decoratorMatch("foo.bar.Baz", "foo.bar", "*fie*.*az"));
+ assertFalse(decoratorMatch("foo.bar.Baz", "foo.bar", "*.Goop"));
+ }
+}
Added: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/LoggerTest.java
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/LoggerTest.java?rev=424577&view=auto
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/LoggerTest.java (added)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/internal/ioc/services/LoggerTest.java Sat Jul 22 06:57:04 2006
@@ -0,0 +1,96 @@
+package org.apache.tapestry.internal.ioc.services;
+
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+
+import java.util.Arrays;
+
+import org.apache.commons.logging.Log;
+import org.apache.tapestry.test.BaseTestCase;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+/**
+ * @author Howard M. Lewis Ship
+ */
+public class LoggerTest extends BaseTestCase
+{
+ private void try_entry(String methodName, String expected, Object... arguments)
+ {
+ Log log = newLog();
+
+ log.debug("[ENTER] " + expected);
+
+ replay();
+
+ new Logger(log).entry(methodName, arguments);
+
+ verify();
+
+ }
+
+ private void try_exit(String methodName, String expected, Object result)
+ {
+ Log log = newLog();
+
+ log.debug("[ EXIT] " + expected);
+
+ replay();
+
+ new Logger(log).exit(methodName, result);
+
+ verify();
+ }
+
+ @Test
+ public void entry_tests()
+ {
+ try_entry("fred", "fred()");
+ try_entry("barney", "barney(\"rubble\")", "rubble");
+ try_entry("yogi", "yogi(null, null)", null, null);
+ try_entry("wilma", "wilma(1, 2, 3)", 1, 2, 3);
+ try_entry("betty", "betty(\"rubble\", {1, 2, 3, \"four\"})", "rubble", new Object[]
+ { 1, 2, 3, "four" });
+ try_entry("betty", "betty(\"rubble\", [1, 2, 3, \"four\", [5, 6]])", "rubble", Arrays
+ .asList(1, 2, 3, "four", Arrays.asList(5, 6)));
+ }
+
+ @Test
+ public void exit_test()
+ {
+ try_exit("fred", "fred [true]", true);
+ try_exit("barney", "barney [\"rubble\"]", "rubble");
+ }
+
+ @Test
+ public void void_exit_test()
+ {
+ Log log = newLog();
+
+ log.debug("[ EXIT] wilma");
+
+ replay();
+
+ new Logger(log).voidExit("wilma");
+
+ verify();
+ }
+
+ @Test
+ public void debug_enabled()
+ {
+ Log log = newLog();
+
+ trainIsDebugEnabled(log, true);
+ trainIsDebugEnabled(log, false);
+
+ replay();
+
+ Logger logger = new Logger(log);
+
+ assertTrue(logger.isDebugEnabled());
+ assertFalse(logger.isDebugEnabled());
+
+ verify();
+ }
+}
\ No newline at end of file
Copied: tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IOCUtilitiesTest.java (from r424052, tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/TestIdUtils.java)
URL: http://svn.apache.org/viewvc/tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IOCUtilitiesTest.java?p2=tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IOCUtilitiesTest.java&p1=tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/TestIdUtils.java&r1=424052&r2=424577&rev=424577&view=diff
==============================================================================
--- tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/TestIdUtils.java (original)
+++ tapestry/tapestry5/tapestry-core/trunk/src/test/java/org/apache/tapestry/ioc/IOCUtilitiesTest.java Sat Jul 22 06:57:04 2006
@@ -14,50 +14,52 @@
package org.apache.tapestry.ioc;
+import static org.apache.tapestry.ioc.IOCUtilities.qualifySimpleIdList;
+import static org.apache.tapestry.ioc.IOCUtilities.toQualifiedId;
import static org.testng.Assert.assertEquals;
import static org.testng.Assert.assertNull;
import org.testng.annotations.Test;
/**
- * Tests for {@link org.apache.tapestry.ioc.IdUtils}.
+ * Tests for {@link org.apache.tapestry.ioc.IOCUtilities}.
*
* @author Howard M. Lewis Ship
*/
-public class TestIdUtils
+public class IOCUtilitiesTest
{
@Test
public void qualify_single_simple_id()
{
- assertEquals(IdUtils.qualify("module", "Fred"), "module.Fred");
+ assertEquals(toQualifiedId("module", "Fred"), "module.Fred");
}
@Test
public void qualify_single_qualified_id()
{
- assertEquals(IdUtils.qualify("zaphod", "module.Fred"), "module.Fred");
+ assertEquals(toQualifiedId("zaphod", "module.Fred"), "module.Fred");
}
@Test
public void qualify_id_list()
{
assertEquals(
- IdUtils.qualifyList("module", "Fred,othermodule.Barney,module.Wilma"),
+ qualifySimpleIdList("module", "Fred,othermodule.Barney,module.Wilma"),
"module.Fred,othermodule.Barney,module.Wilma");
}
@Test
public void qualify_list_as_star()
{
- assertEquals(IdUtils.qualifyList("module", "*"), "*");
+ assertEquals(qualifySimpleIdList("module", "*"), "*");
}
@Test
public void qualify_blank_or_null_list()
{
- assertNull(IdUtils.qualifyList("module", null));
+ assertNull(qualifySimpleIdList("module", null));
- assertEquals(IdUtils.qualifyList("module", ""), "");
+ assertEquals(qualifySimpleIdList("module", ""), "");
}
}