svn commit: r2135 - in development/main/metro: composition/api/src/main/net/dpml/composition/data composition/control/src/main/net/dpml/composition/handlers meta/api/src/main/net/dpml/meta/info meta/api/src/test/net/dpml/meta/info/test

mcconnell at dpml.net mcconnell at dpml.net
Fri Mar 25 15:37:23 EST 2005


Author: mcconnell at dpml.net
Date: Fri Mar 25 15:37:23 2005
New Revision: 2135

Added:
   development/main/metro/composition/control/src/main/net/dpml/composition/handlers/
   development/main/metro/composition/control/src/main/net/dpml/composition/handlers/ContextInvocationHandler.java
   development/main/metro/meta/api/src/test/net/dpml/meta/info/test/ParameterDescriptorTestCase.java
   development/main/metro/meta/api/src/test/net/dpml/meta/info/test/PartDescriptorTestCase.java
Modified:
   development/main/metro/composition/api/src/main/net/dpml/composition/data/ValueDirective.java
   development/main/metro/meta/api/src/main/net/dpml/meta/info/InfoDescriptor.java
Log:


Modified: development/main/metro/composition/api/src/main/net/dpml/composition/data/ValueDirective.java
==============================================================================
--- development/main/metro/composition/api/src/main/net/dpml/composition/data/ValueDirective.java	(original)
+++ development/main/metro/composition/api/src/main/net/dpml/composition/data/ValueDirective.java	Fri Mar 25 15:37:23 2005
@@ -54,15 +54,14 @@
  * @author <a href="mailto:dev-dpml at lists.ibiblio.org">The Digital Product Meta Library</a>
  * @version $Id: Parameter.java 2119 2005-03-23 02:04:46Z mcconnell at dpml.net $
  */
-public class ValueDirective implements Serializable, Part
+public class ValueDirective extends EntryDirective implements Part
 {
     //--------------------------------------------------------------------------
     // state
     //--------------------------------------------------------------------------
 
-    private final String m_key;
     private final String m_classname;
-    private final String m_value;
+    private final String m_local;
     private final Value[] m_values;
 
     //--------------------------------------------------------------------------
@@ -71,37 +70,45 @@
 
     public ValueDirective( String key, String classname, String value )
     {
-        m_key = key;
+        super( key );
         m_classname = classname;
-        m_value = value;
+        m_local = value;
         m_values = new Value[0];
     }
 
     public ValueDirective( String key, String classname, Value[] values )
     {
-        m_key = key;
+        super( key );
         m_classname = classname;
-        m_value = null;
+        m_local = null;
         m_values = values;
     }
 
     //--------------------------------------------------------------------------
-    // ValueDirective
+    // Part
     //--------------------------------------------------------------------------
 
-    public String getKey()
-    {
-        return m_key;
-    }
+    /**
+     * Return the part handler uri.
+     * @return the uri of the part handler
+     */
+     public URI getPartHandlerURI()
+     {
+         return PART_HANDLER_URI;
+     }
+
+    //--------------------------------------------------------------------------
+    // ValueDirective
+    //--------------------------------------------------------------------------
 
     public String getClassname()
     {
         return m_classname;
     }
 
-    public String getValue()
+    public String getLocalValue()
     {
-        return m_value;
+        return m_local;
     }
 
     public Value[] getValues()
@@ -110,19 +117,6 @@
     }
 
     //--------------------------------------------------------------------------
-    // Part
-    //--------------------------------------------------------------------------
-
-    /**
-     * Return the part handler uri.
-     * @return the uri of the part handler
-     */
-     public URI getPartHandlerURI()
-     {
-         return PART_HANDLER_URI;
-     }
-
-    //--------------------------------------------------------------------------
     // static utils
     //--------------------------------------------------------------------------
 

Added: development/main/metro/composition/control/src/main/net/dpml/composition/handlers/ContextInvocationHandler.java
==============================================================================
--- (empty file)
+++ development/main/metro/composition/control/src/main/net/dpml/composition/handlers/ContextInvocationHandler.java	Fri Mar 25 15:37:23 2005
@@ -0,0 +1,225 @@
+/*
+ * 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.composition.handlers;
+
+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.composition.model.ComponentModel;
+
+import net.dpml.meta.info.Type;
+import net.dpml.meta.info.ParameterDescriptor;
+
+import net.dpml.lang.NullArgumentException;
+
+import net.dpml.logging.Logger;
+
+/**
+ * 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
+{
+    //-------------------------------------------------------------------
+    // immutable state
+    //-------------------------------------------------------------------
+
+   /**
+    * A map of context entry key name and context entry values.
+    */
+    private final Map m_map;
+
+   /**
+    * A map of the parameter descriptors published by the component type
+    * and keyed by the parameter key.
+    */
+    private final Map m_parameters = new Hashtable();
+
+   /**
+    * The component type.
+    */
+    private final Type m_type;
+
+    //-------------------------------------------------------------------
+    // immutable state
+    //-------------------------------------------------------------------
+
+    private boolean m_destroyed = false;
+
+    //-------------------------------------------------------------------
+    // constructor
+    //-------------------------------------------------------------------
+
+   /**
+    * Create a context invocation handler.
+    *
+    * @param appliance the runtime appliance
+    * @param logger the assigned logging channel
+    */
+    ContextInvocationHandler( Type type, Map map )
+        throws NullArgumentException
+    {
+        assertNotNull( map, "map" );
+        assertNotNull( type, "type" );
+
+        m_map = map;
+        m_type = type;
+
+        ParameterDescriptor[] parameters = type.getParameters();
+        for( int i=0; i<parameters.length; i++ )
+        {
+            ParameterDescriptor p = parameters[i];
+            String key = p.getKey();
+            boolean required = p.isRequired();
+            m_parameters.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 NullArgumentException 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, NullArgumentException
+    {
+        if( proxy == null )
+          throw new NullArgumentException( "proxy" );
+        if( method == null )
+          throw new NullArgumentException( "method" );
+        if( m_destroyed )
+          throw new NullArgumentException( "destroyed" );
+
+        String name = method.getName();
+        String key = getKeyFromMethod( method );
+        ParameterDescriptor param = (ParameterDescriptor) m_parameters.get( key );
+        
+        if( null == param )
+        {
+            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( param, 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( ParameterDescriptor param, Object[] args )
+    {
+        if( args.length < 1 )
+        {
+            final String error = 
+              "Insuffient arguments to resolve a default value for the key ["
+              + param.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 NullArgumentException
+    {
+        if( null == object )
+        {
+            throw new NullArgumentException( key );
+        }
+    }
+}

Modified: development/main/metro/meta/api/src/main/net/dpml/meta/info/InfoDescriptor.java
==============================================================================
--- development/main/metro/meta/api/src/main/net/dpml/meta/info/InfoDescriptor.java	(original)
+++ development/main/metro/meta/api/src/main/net/dpml/meta/info/InfoDescriptor.java	Fri Mar 25 15:37:23 2005
@@ -47,6 +47,10 @@
     // static
     //-------------------------------------------------------------------
 
+    public static final int TRANSIENT_LIFESTYLE = 0;
+    public static final int THREAD_LIFESTYLE = 1;
+    public static final int SINGLETON_LIFESTYLE = 2;
+
     public static final String TRANSIENT = "transient";
     public static final String SINGLETON = "singleton";
     public static final String THREAD = "thread";
@@ -462,6 +466,36 @@
     }
 
    /**
+    * Return a string value of a lifestyle preference.
+    * @param policy the lifestyle preference
+    * @return the value as a string
+    */
+    public static String getLifestylePreferenceKey( int policy )
+    {
+        if( policy == TRANSIENT_LIFESTYLE )
+        {
+            return TRANSIENT;
+        }
+        else if( policy == THREAD_LIFESTYLE )
+        {
+            return THREAD;
+        }
+        else if( policy == SINGLETON_LIFESTYLE )
+        {
+            return SINGLETON;
+        }
+        else
+        {
+            final String error = 
+              "Invalid lifestyle policy value ["
+              + policy
+              + "]";
+            throw new IllegalArgumentException( error );
+        }
+    }
+
+
+   /**
     * Return a string value of a collection policy.
     * @param policy the collection policy
     * @return the value as a string

Added: development/main/metro/meta/api/src/test/net/dpml/meta/info/test/ParameterDescriptorTestCase.java
==============================================================================
--- (empty file)
+++ development/main/metro/meta/api/src/test/net/dpml/meta/info/test/ParameterDescriptorTestCase.java	Fri Mar 25 15:37:23 2005
@@ -0,0 +1,95 @@
+/*
+ * Copyright 2004 Stephen J. McConnell.
+ * Copyright 1999-2004 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 net.dpml.meta.info.test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import junit.framework.TestCase;
+
+import net.dpml.meta.info.ParameterDescriptor;
+
+/**
+ * EntryDescriptorTestCase does XYZ
+ *
+ * @author <a href="mailto:dev-dpml at lists.ibiblio.org">The Digital Product Meta Library</a>
+ * @version $Id: EntryDescriptorTestCase.java 1874 2005-02-22 17:47:49Z mcconnell $
+ */
+public class ParameterDescriptorTestCase extends TestCase
+{
+    private static final String m_key = "key";
+    private static final String m_type = ParameterDescriptor.class.getName();
+    private static final boolean m_required = true;
+
+    public ParameterDescriptorTestCase( String name )
+    {
+        super( name );
+    }
+
+    public void testDescriptor()
+    {
+        ParameterDescriptor param = new ParameterDescriptor( m_key, m_type, m_required );
+        assertEquals( "key", m_key, param.getKey() );
+        assertEquals( "type", m_type, param.getType() );
+        assertTrue( "required", m_required == param.isRequired() );
+
+        try
+        {
+            new ParameterDescriptor( null, m_type );
+            fail("Did not throw expected NullPointerException ");
+        }
+        catch( NullPointerException npe)
+        {
+            // Success!!
+        }
+
+        try
+        {
+            new ParameterDescriptor( m_key, null );
+            fail( "Did not throw expected NullPointerException" );
+        }
+        catch ( NullPointerException npe )
+        {
+            // Success!!
+        }
+    }
+
+    public void testSerialization() throws IOException, ClassNotFoundException
+    {
+        ParameterDescriptor param = new ParameterDescriptor( m_key, m_type, m_required );
+
+        File file = new File( "test.out" );
+        ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream( file ) );
+        oos.writeObject( param );
+        oos.close();
+
+        ObjectInputStream ois = new ObjectInputStream( new FileInputStream( file ) );
+        ParameterDescriptor serialized = (ParameterDescriptor) ois.readObject();
+        ois.close();
+        file.delete();
+
+        assertEquals( param, serialized );
+        assertEquals( param.hashCode(), serialized.hashCode() );
+    }
+}

Added: development/main/metro/meta/api/src/test/net/dpml/meta/info/test/PartDescriptorTestCase.java
==============================================================================
--- (empty file)
+++ development/main/metro/meta/api/src/test/net/dpml/meta/info/test/PartDescriptorTestCase.java	Fri Mar 25 15:37:23 2005
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2004 Stephen J. McConnell.
+ * Copyright 1999-2004 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 net.dpml.meta.info.test;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+import junit.framework.TestCase;
+
+import net.dpml.meta.info.PartDescriptor;
+
+/**
+ * EntryDescriptorTestCase does XYZ
+ *
+ * @author <a href="mailto:dev-dpml at lists.ibiblio.org">The Digital Product Meta Library</a>
+ * @version $Id: EntryDescriptorTestCase.java 1874 2005-02-22 17:47:49Z mcconnell $
+ */
+public class PartDescriptorTestCase extends TestCase
+{
+    private static final String m_key = "key";
+    private static final String m_type = PartDescriptor.class.getName();
+    private static final int m_semantic = PartDescriptor.GET;
+
+    public void testDescriptor()
+    {
+        PartDescriptor part = new PartDescriptor( m_key, m_type, m_semantic );
+
+        assertEquals( "key", m_key, part.getKey() );
+        assertEquals( "type", m_type, part.getType() );
+        assertTrue( "semantic", m_semantic == part.getSemantic() );
+
+        try
+        {
+            new PartDescriptor( null, m_type );
+            fail("Did not throw expected NullPointerException ");
+        }
+        catch( NullPointerException npe)
+        {
+            // Success!!
+        }
+
+        try
+        {
+            new PartDescriptor( m_key, null );
+            fail( "Did not throw expected NullPointerException" );
+        }
+        catch ( NullPointerException npe )
+        {
+            // Success!!
+        }
+    }
+
+    public void testSerialization() throws IOException, ClassNotFoundException
+    {
+        PartDescriptor part = new PartDescriptor( m_key, m_type, m_semantic );
+
+        File file = new File( "test.out" );
+        ObjectOutputStream oos = new ObjectOutputStream( new FileOutputStream( file ) );
+        oos.writeObject( part );
+        oos.close();
+
+        ObjectInputStream ois = new ObjectInputStream( new FileInputStream( file ) );
+        PartDescriptor serialized = (PartDescriptor) ois.readObject();
+        ois.close();
+        file.delete();
+
+        assertEquals( part, serialized );
+        assertEquals( part.hashCode(), serialized.hashCode() );
+    }
+}



More information about the notify-dpml mailing list