Skip to Content.
Sympa Menu

notify-dpml - svn commit: r2137 - development/main/metro/context/impl/src/main/net/dpml/context/impl

notify-dpml AT lists.ibiblio.org

Subject: DPML Notify

List archive

Chronological Thread  
  • From: mcconnell AT dpml.net
  • To: notify-dpml AT lists.ibiblio.org
  • Subject: svn commit: r2137 - development/main/metro/context/impl/src/main/net/dpml/context/impl
  • Date: Fri, 25 Mar 2005 17:15:36 -0500

Author: mcconnell AT dpml.net
Date: Fri Mar 25 17:15:36 2005
New Revision: 2137

Added:

development/main/metro/context/impl/src/main/net/dpml/context/impl/ContextInvocationHandler.java
Log:
add a context innvocation handler

Added:
development/main/metro/context/impl/src/main/net/dpml/context/impl/ContextInvocationHandler.java
==============================================================================
--- (empty file)
+++
development/main/metro/context/impl/src/main/net/dpml/context/impl/ContextInvocationHandler.java
Fri Mar 25 17:15:36 2005
@@ -0,0 +1,210 @@
+/*
+ * Copyright 2004 Stephen J. McConnell.
+ *
+ * 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 net.dpml.context.impl;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.UndeclaredThrowableException;
+import java.lang.reflect.Method;
+import java.util.Hashtable;
+import java.util.Map;
+
+import net.dpml.meta.info.Type;
+import net.dpml.meta.info.EntryDescriptor;
+
+/**
+ * This makes a dynamic proxy for an object. The object can be represented
+ * by one, some or all of it's interfaces.
+ *
+ * @author <a href="mailto:dev-dpml AT lists.ibiblio.org";>The Digital Product
Meta Library</a>
+ * @version $Id: ApplianceInvocationHandler.java 2106 2005-03-21 18:46:10Z
mcconnell AT dpml.net $
+ */
+public final class ContextInvocationHandler
+ implements InvocationHandler
+{
+ //-------------------------------------------------------------------
+ // state
+ //-------------------------------------------------------------------
+
+ /**
+ * A map of context entry key name and context entry values.
+ */
+ private final Map m_map;
+
+ /**
+ * A map of the entry descriptors published by the component type
+ * and keyed by entry key.
+ */
+ private final Map m_entries = new Hashtable();
+
+ /**
+ * The component type.
+ */
+ private final Type m_type;
+
+ //-------------------------------------------------------------------
+ // constructor
+ //-------------------------------------------------------------------
+
+ /**
+ * Create a context invocation handler.
+ *
+ * @param type the component type
+ * @param map a map of context values keyed by entry key
+ */
+ public ContextInvocationHandler( Type type, Map map )
+ throws NullPointerException
+ {
+ assertNotNull( map, "map" );
+ assertNotNull( type, "type" );
+
+ m_map = map;
+ m_type = type;
+
+ EntryDescriptor[] entries = type.getContext().getEntries();
+ for( int i=0; i<entries.length; i++ )
+ {
+ EntryDescriptor p = entries[i];
+ String key = p.getKey();
+ boolean required = p.isRequired();
+ m_entries.put( key, p );
+ if( required && ( false == map.containsKey( key ) ) )
+ {
+ final String error =
+ "The component type ["
+ + type.getInfo().getClassname()
+ + "] declares a required context entry under the key ["
+ + key
+ + "] however, no corresponding value has been supplied
within the context map.";
+ throw new IllegalArgumentException( error );
+ }
+ }
+ }
+
+ //-------------------------------------------------------------------
+ // implementation
+ //-------------------------------------------------------------------
+
+ /**
+ * Invoke the specified method on underlying object.
+ * This is called by the proxy object.
+ *
+ * @param proxy the proxy object
+ * @param method the method invoked on proxy object
+ * @param args the arguments supplied to method
+ * @return the return value of method
+ * @throws Throwable if an error occurs
+ * @exception NullPointerException if any one of the proxy or method
arguments
+ * is null, or if the object instance has been destroyed
earlier.
+ */
+ public Object invoke( final Object proxy, final Method method, final
Object[] args )
+ throws Throwable, NullPointerException
+ {
+ if( proxy == null )
+ throw new NullPointerException( "proxy" );
+ if( method == null )
+ throw new NullPointerException( "method" );
+
+ String name = method.getName();
+ String key = getKeyFromMethod( method );
+ EntryDescriptor entry = (EntryDescriptor) m_entries.get( key );
+
+ if( null == entry )
+ {
+ final String error =
+ "Illegal request for an undeclared context entry ["
+ + key
+ + "] withing the component type ["
+ + m_type.getInfo().getClassname()
+ + "].";
+ throw new IllegalArgumentException( error );
+ }
+
+ //
+ // we have a valid key
+ //
+
+ Object value = m_map.get( key );
+ if( null != value )
+ {
+ return returnClientSuppliedDefaultArgument( entry, args );
+ }
+ else
+ {
+ return value;
+ }
+ }
+
+ private String getKeyFromMethod( Method method )
+ {
+ String name = method.getName();
+ if( name.startsWith( "get" ) )
+ {
+ return formatKey( name.substring( 3 ) );
+ }
+ else
+ {
+ final String error =
+ "Invalid method accessor ["
+ + name
+ + "]";
+ throw new IllegalArgumentException( error );
+ }
+ }
+
+ private String formatKey( String key )
+ {
+ if( key.length() < 1 )
+ {
+ throw new IllegalArgumentException( "key" );
+ }
+ String first = key.substring( 0, 1 ).toLowerCase();
+ String remainder = key.substring( 1 );
+ return first + remainder;
+ }
+
+ private Object returnClientSuppliedDefaultArgument( EntryDescriptor
entry, Object[] args )
+ {
+ if( args.length < 1 )
+ {
+ final String error =
+ "Insuffient arguments to resolve a default value for the key ["
+ + entry.getKey()
+ + "] within the component type ["
+ + m_type.getInfo().getName()
+ + "].";
+ throw new IllegalArgumentException( error );
+ }
+ Object arg = args[0];
+ return arg;
+ }
+
+ //-------------------------------------------------------------------
+ // implementation
+ //-------------------------------------------------------------------
+
+ private void assertNotNull( Object object, String key )
+ throws NullPointerException
+ {
+ if( null == object )
+ {
+ throw new NullPointerException( key );
+ }
+ }
+}



  • svn commit: r2137 - development/main/metro/context/impl/src/main/net/dpml/context/impl, mcconnell, 03/25/2005

Archive powered by MHonArc 2.6.24.

Top of Page