[jboss-cvs] JBossAS SVN: r59139 - in projects/microcontainer/trunk: . metatype metatype/src metatype/src/etc metatype/src/main metatype/src/main/org metatype/src/main/org/jboss metatype/src/main/org/jboss/metatype metatype/src/main/org/jboss/metatype/api metatype/src/main/org/jboss/metatype/api/types metatype/src/main/org/jboss/metatype/api/values metatype/src/tests metatype/src/tests/org metatype/src/tests/org/jboss metatype/src/tests/org/jboss/test metatype/src/tests/org/jboss/test/metatype metatype/src/tests/org/jboss/test/metatype/types metatype/src/tests/org/jboss/test/metatype/types/support metatype/src/tests/org/jboss/test/metatype/types/test metatype/src/tests/org/jboss/test/metatype/values metatype/src/tests/org/jboss/test/metatype/values/test

jboss-cvs-commits at lists.jboss.org jboss-cvs-commits at lists.jboss.org
Tue Dec 19 08:01:25 EST 2006


Author: adrian at jboss.org
Date: 2006-12-19 08:01:12 -0500 (Tue, 19 Dec 2006)
New Revision: 59139

Added:
   projects/microcontainer/trunk/metatype/
   projects/microcontainer/trunk/metatype/.classpath
   projects/microcontainer/trunk/metatype/.project
   projects/microcontainer/trunk/metatype/build.bat
   projects/microcontainer/trunk/metatype/build.sh
   projects/microcontainer/trunk/metatype/build.xml
   projects/microcontainer/trunk/metatype/src/
   projects/microcontainer/trunk/metatype/src/etc/
   projects/microcontainer/trunk/metatype/src/etc/default.mf
   projects/microcontainer/trunk/metatype/src/main/
   projects/microcontainer/trunk/metatype/src/main/org/
   projects/microcontainer/trunk/metatype/src/main/org/jboss/
   projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/
   projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/
   projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/
   projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/AbstractMetaType.java
   projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/ArrayMetaType.java
   projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/CompositeMetaType.java
   projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/ImmutableCompositeMetaType.java
   projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/ImmutableTableMetaType.java
   projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/MetaType.java
   projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/SimpleMetaType.java
   projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/TableMetaType.java
   projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/
   projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/AbstractMetaValue.java
   projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/CompositeValue.java
   projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/CompositeValueSupport.java
   projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/MetaValue.java
   projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/SimpleValue.java
   projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/SimpleValueSupport.java
   projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/TableValue.java
   projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/TableValueSupport.java
   projects/microcontainer/trunk/metatype/src/tests/
   projects/microcontainer/trunk/metatype/src/tests/org/
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/AbstractMetaTypeTest.java
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/MetaTypeAllTestSuite.java
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/MockCompositeValue.java
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/MockMetaType.java
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/MockMetaValue.java
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/MockSimpleValue.java
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/MockTableValue.java
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/ArrayMetaTypeUnitTestCase.java
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/ImmutableCompositeMetaTypeUnitTestCase.java
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/ImmutableTableMetaTypeUnitTestCase.java
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/MetaTypeUnitTestCase.java
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/SimpleMetaTypeUnitTestCase.java
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/TypesTestSuite.java
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/values/
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/values/test/
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/values/test/CompositeValueSupportUnitTestCase.java
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/values/test/SimpleValueSupportUnitTestCase.java
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/values/test/TableValueSupportUnitTestCase.java
   projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/values/test/ValuesTestSuite.java
Log:
Start of metatype project

Added: projects/microcontainer/trunk/metatype/.classpath
===================================================================
--- projects/microcontainer/trunk/metatype/.classpath	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/.classpath	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="src" path="src/main"/>
+	<classpathentry kind="src" path="src/tests"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+	<classpathentry kind="lib" path="/thirdparty/jboss/common-core/lib/jboss-common-core.jar"/>
+	<classpathentry kind="lib" path="/thirdparty/jboss/common-logging-spi/lib/jboss-logging-spi.jar"/>
+	<classpathentry kind="lib" path="/thirdparty/jboss/common-logging-log4j/lib/jboss-logging-log4j.jar"/>
+	<classpathentry kind="lib" path="/thirdparty/junit/lib/junit.jar"/>
+	<classpathentry kind="lib" path="/thirdparty/jboss/test/lib/jboss-test.jar"/>
+	<classpathentry kind="lib" path="/thirdparty/apache-log4j/lib/log4j.jar"/>
+	<classpathentry kind="output" path="output/eclipse-classes"/>
+</classpath>

Added: projects/microcontainer/trunk/metatype/.project
===================================================================
--- projects/microcontainer/trunk/metatype/.project	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/.project	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,17 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>metatype</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+	</natures>
+</projectDescription>

Added: projects/microcontainer/trunk/metatype/build.bat
===================================================================
--- projects/microcontainer/trunk/metatype/build.bat	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/build.bat	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,89 @@
+ at echo off
+REM  ======================================================================
+REM
+REM  This is the main entry point for the build system.
+REM
+REM  Users should be sure to execute this file rather than 'ant' to ensure
+REM  the correct version is being used with the correct configuration.
+REM
+REM  ======================================================================
+REM
+REM $Id: build.bat 31497 2005-05-24 16:47:10Z adrian $
+REM
+REM Authors:
+REM     Jason Dillon <jason at planet57.com>
+REM     Sacha Labourey <sacha.labourey at cogito-info.ch>
+REM
+
+REM ******************************************************
+REM Ignore the ANT_HOME variable: we want to use *our*
+REM ANT version and associated JARs.
+REM ******************************************************
+REM Ignore the users classpath, cause it might mess
+REM things up
+REM ******************************************************
+
+SETLOCAL
+
+set CLASSPATH=
+set ANT_HOME=
+set ANT_OPTS=-Djava.protocol.handler.pkgs=org.jboss.net.protocol -Dbuild.script=build.bat
+
+REM ******************************************************
+REM - "for" loops have been unrolled for compatibility
+REM   with some WIN32 systems.
+REM ******************************************************
+
+set NAMES=tools;tools\ant;tools\apache\ant
+set SUBFOLDERS=..;..\..;..\..\..;..\..\..\..
+
+REM ******************************************************
+REM ******************************************************
+
+SET EXECUTED=FALSE
+for %%i in (%NAMES%) do call :subLoop %%i %1 %2 %3 %4 %5 %6
+
+goto :EOF
+
+
+REM ******************************************************
+REM ********* Search for names in the subfolders *********
+REM ******************************************************
+
+:subLoop
+for %%j in (%SUBFOLDERS%) do call :testIfExists %%j\%1\bin\ant.bat %2 %3 %4 %5 %6 %7
+
+goto :EOF
+
+
+REM ******************************************************
+REM ************ Test if ANT Batch file exists ***********
+REM ******************************************************
+
+:testIfExists
+if exist %1 call :BatchFound %1 %2 %3 %4 %5 %6 %7 %8
+
+goto :EOF
+
+
+REM ******************************************************
+REM ************** Batch file has been found *************
+REM ******************************************************
+
+:BatchFound
+if (%EXECUTED%)==(FALSE) call :ExecuteBatch %1 %2 %3 %4 %5 %6 %7 %8
+set EXECUTED=TRUE
+
+goto :EOF
+
+REM ******************************************************
+REM ************* Execute Batch file only once ***********
+REM ******************************************************
+
+:ExecuteBatch
+echo Calling %1 %2 %3 %4 %5 %6 %7 %8
+call %1 %2 %3 %4 %5 %6 %7 %8
+
+:end
+
+if "%NOPAUSE%" == "" pause


Property changes on: projects/microcontainer/trunk/metatype/build.bat
___________________________________________________________________
Name: svn:executable
   + 

Added: projects/microcontainer/trunk/metatype/build.sh
===================================================================
--- projects/microcontainer/trunk/metatype/build.sh	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/build.sh	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,172 @@
+#!/bin/sh
+### ====================================================================== ###
+##                                                                          ##
+##  This is the main entry point for the build system.                      ##
+##                                                                          ##
+##  Users should be sure to execute this file rather than 'ant' to ensure   ##
+##  the correct version is being used with the correct configuration.       ##
+##                                                                          ##
+### ====================================================================== ###
+
+# $Id: build.sh 31497 2005-05-24 16:47:10Z adrian $
+
+PROGNAME=`basename $0`
+DIRNAME=`dirname $0`
+GREP="grep"
+ROOT="/"
+
+# Ignore user's ANT_HOME if it is set
+ANT_HOME=""
+
+# the default search path for ant
+ANT_SEARCH_PATH="\
+    tools
+    tools/ant \
+    tools/apache/ant \
+    ant"
+
+# the default build file name
+ANT_BUILD_FILE="build.xml"
+
+# the default arguments
+ANT_OPTIONS="-find $ANT_BUILD_FILE"
+
+# Use the maximum available, or set MAX_FD != -1 to use that
+MAX_FD="maximum"
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false;
+darwin=false;
+case "`uname`" in
+    CYGWIN*)
+        cygwin=true
+        ;;
+
+    Darwin*)
+        darwin=true
+        ;;
+esac
+
+#
+# Helper to complain.
+#
+die() {
+    echo "${PROGNAME}: $*"
+    exit 1
+}
+
+#
+# Helper to complain.
+#
+warn() {
+    echo "${PROGNAME}: $*"
+}
+
+#
+# Helper to source a file if it exists.
+#
+maybe_source() {
+    for file in $*; do
+	if [ -f "$file" ]; then
+	    . $file
+	fi
+    done
+}
+
+search() {
+    search="$*"
+    for d in $search; do
+	ANT_HOME="`pwd`/$d"
+	ANT="$ANT_HOME/bin/ant"
+	if [ -x "$ANT" ]; then
+	    # found one
+	    echo $ANT_HOME
+	    break
+	fi
+    done
+}
+
+#
+# Main function.
+#
+main() {
+    # if there is a build config file. then source it
+    maybe_source "$DIRNAME/build.conf" "$HOME/.build.conf"
+
+    # Increase the maximum file descriptors if we can
+    if [ $cygwin = "false" ]; then
+	MAX_FD_LIMIT=`ulimit -H -n`
+	if [ $? -eq 0 ]; then
+	    if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ]; then
+		# use the system max
+		MAX_FD="$MAX_FD_LIMIT"
+	    fi
+
+	    ulimit -n $MAX_FD
+	    if [ $? -ne 0 ]; then
+		warn "Could not set maximum file descriptor limit: $MAX_FD"
+	    fi
+	else
+	    warn "Could not query system maximum file descriptor limit: $MAX_FD_LIMIT"
+	fi
+    fi
+
+    # try the search path
+    ANT_HOME=`search $ANT_SEARCH_PATH`
+
+    # try looking up to root
+    if [ "x$ANT_HOME" = "x" ]; then
+	target="build"
+	_cwd=`pwd`
+
+	while [ "x$ANT_HOME" = "x" ] && [ "$cwd" != "$ROOT" ]; do
+	    cd ..
+	    cwd=`pwd`
+	    ANT_HOME=`search $ANT_SEARCH_PATH`
+	done
+
+	# make sure we get back
+	cd $_cwd
+
+	if [ "$cwd" != "$ROOT" ]; then
+	    found="true"
+	fi
+
+	# complain if we did not find anything
+	if [ "$found" != "true" ]; then
+	    die "Could not locate Ant; check \$ANT or \$ANT_HOME."
+	fi
+    fi
+
+    # make sure we have one
+    ANT=$ANT_HOME/bin/ant
+    if [ ! -x "$ANT" ]; then
+	die "Ant file is not executable: $ANT"
+    fi
+
+    # need to specify planet57/buildmagic protocol handler package
+    ANT_OPTS="-Djava.protocol.handler.pkgs=org.jboss.net.protocol"
+
+    # setup some build properties
+    ANT_OPTS="$ANT_OPTS -Dbuild.script=$0"
+
+    # change to the directory where the script lives so users are not forced
+    # to be in the same directory as build.xml
+    cd $DIRNAME
+
+    # export some stuff for ant
+    export ANT ANT_HOME ANT_OPTS
+
+    # execute in debug mode, or simply execute
+    if [ "x$ANT_DEBUG" != "x" ]; then
+	/bin/sh -x $ANT $ANT_OPTIONS "$@"
+    else
+	exec $ANT $ANT_OPTIONS "$@"
+    fi
+}
+
+##
+## Bootstrap
+##
+
+main "$@"


Property changes on: projects/microcontainer/trunk/metatype/build.sh
___________________________________________________________________
Name: svn:executable
   + 

Added: projects/microcontainer/trunk/metatype/build.xml
===================================================================
--- projects/microcontainer/trunk/metatype/build.xml	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/build.xml	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,159 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE project [
+   <!ENTITY buildmagic SYSTEM "../tools/etc/buildmagic/buildmagic.ent">
+   <!ENTITY libraries SYSTEM "../thirdparty/libraries.ent">
+   <!ENTITY targets SYSTEM "../tools/etc/buildmagic/targets.ent">
+]>
+
+<!-- ====================================================================== -->
+<!--                                                                        -->
+<!--  JBoss, the OpenSource J2EE webOS                                      -->
+<!--                                                                        -->
+<!--  Distributable under LGPL license.                                     -->
+<!--  See terms of license at http://www.gnu.org.                           -->
+<!--                                                                        -->
+<!-- ====================================================================== -->
+
+<!-- $Id: build.xml 58705 2006-11-28 16:24:22Z adrian at jboss.org $ -->
+
+<project default="main" name="JBoss/MetaType">
+
+  <!-- ================================================================== -->
+  <!-- Setup                                                              -->
+  <!-- ================================================================== -->
+
+  <!--
+     | Include the common Buildmagic elements.
+     |
+     | This defines several different targets, properties and paths.
+     | It also sets up the basic extention tasks amoung other things.
+   -->
+
+  &buildmagic;
+
+  <!--
+     | Include the normal targets.
+   -->
+  &targets;
+
+  <!-- ================================================================== -->
+  <!-- Configuration                                                      -->
+  <!-- ================================================================== -->
+
+  <!--
+     | Configure the build system.
+     |
+     | This target is invoked by the Buildmagic initialization logic and
+     | should contain module specific configuration elements.
+   -->
+
+  <target name="configure" unless="configure.disable">
+
+    <!-- =================== -->
+    <!-- Basic Configuration -->
+    <!-- =================== -->
+
+    <!-- Module name(s) & version -->
+    <property name="module.name" value="metatype"/>
+    <property name="module.Name" value="JBoss MetaType"/>
+    <property name="module.version" value="DEV"/>
+
+    <!-- ========= -->
+    <!-- Libraries -->
+    <!-- ========= -->
+
+    &libraries;
+
+    <!-- The combined library classpath -->
+    <path id="library.classpath">
+      <path refid="jboss/common.core.classpath"/>
+      <path refid="jboss/common.logging.spi.classpath"/>
+      <path refid="jboss/common.logging.log4j.classpath"/>
+    </path>
+
+    <!-- The combined dependant module classpath -->
+    <path id="dependentmodule.classpath">
+    </path>
+
+   <!-- ============================= -->
+   <!-- Paths etc. for the retro task -->
+   <!-- ============================= -->
+   <property name="build.classes.retro" value="${module.output}/classes-retro"/>
+   <property name="build.lib.retro" value="${module.output}/lib14"/>
+   <path id="jbossretro.classpath">
+     <path refid="apache.ant.classpath"/>
+     <path refid="jboss.jbossretro.classpath"/>
+     <path refid="jboss/backport.concurrent.classpath"/>
+     <path refid="javassist.classpath"/>
+   </path>
+
+     
+    <!-- ===== -->
+    <!-- Tasks -->
+    <!-- ===== -->
+
+    <property name="jar.prefix" value="jboss-metatype"/>
+    <property name="javac.target" value="1.5"/>
+    <property name="javac.source" value="1.5"/>
+
+    <call target="_default:task-init"/>
+
+  </target>
+
+  <!-- ================================================================== -->
+  <!-- Compile                                                            -->
+  <!-- ================================================================== -->
+
+  <!--
+     | Compile everything.
+     |
+     | This target should depend on other compile-* targets for each
+     | different type of compile that needs to be performed, short of
+     | documentation compiles.
+   -->
+
+  <target name="compile"
+	  description="Compile all source files."
+	  depends="_default:compile-classes,
+              _default:compile-etc,
+              retro"
+  />
+
+  <target name="retro">
+    <mkdir dir="${build.lib.retro}"/>
+    <taskdef name="retro" classname="org.jboss.ant.tasks.retro.Retro" classpathref="jbossretro.classpath"/>
+    <retro compilerclasspathref="jbossretro.classpath" destdir="${build.classes.retro}">
+      <classpath refid="jbossretro.classpath"/>
+      <classpath refid="library.classpath"/>
+      <classpath refid="dependentmodule.classpath"/>
+      <classpath>
+        <pathelement path="${build.classes}"/>
+      </classpath>
+      <src path="${build.classes}"/>
+    </retro>      
+  </target> 
+   
+  <!-- ================================================================== -->
+  <!-- Archives                                                           -->
+  <!-- ================================================================== -->
+
+  <!-- 
+     |  Build all jar files.
+    -->
+  <target name="module-jars" depends="init">
+    
+    <jar jarfile="${build.lib}/${jar.prefix}.jar" manifest="${build.etc}/default.mf">
+      <fileset dir="${build.classes}"/>
+    </jar>
+    <jar jarfile="${build.lib.retro}/${jar.prefix}14.jar" manifest="${build.etc}/default.mf">
+      <fileset dir="${build.classes.retro}"/>
+    </jar>
+    <!-- Minimal source bundle -->
+    <zip destfile="${build.lib}/${jar.prefix}-src.zip">
+      <fileset dir="${source.java}">
+        <include name="**"/>
+      </fileset>
+    </zip>
+  </target>
+
+</project>

Added: projects/microcontainer/trunk/metatype/src/etc/default.mf
===================================================================
--- projects/microcontainer/trunk/metatype/src/etc/default.mf	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/etc/default.mf	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,10 @@
+Manifest-Version: 1.0
+Created-By: @java.vm.version@ (@java.vm.vendor@)
+Specification-Title: @specification.title@
+Specification-Version: @specification.version@
+Specification-Vendor: @specification.vendor@
+Implementation-Title: @implementation.title@
+Implementation-URL: @implementation.url@
+Implementation-Version: @implementation.version@
+Implementation-Vendor: @implementation.vendor@
+Implementation-Vendor-Id: @implementation.vendor.id@

Added: projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/AbstractMetaType.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/AbstractMetaType.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/AbstractMetaType.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,260 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.metatype.api.types;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamField;
+import java.io.Serializable;
+
+/**
+ * AbstractMetaType.
+ * 
+ * @param <T> the underlying type
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public abstract class AbstractMetaType<T extends Serializable> implements MetaType<T>
+{
+   /** The serialVersionUID */
+   private static final long serialVersionUID = 5786422588217893696L;
+
+   /** The peristent fields */
+   private static final ObjectStreamField[] serialPersistentFields =
+      new ObjectStreamField[]
+      {
+         new ObjectStreamField("className",   String.class),
+         new ObjectStreamField("description", String.class),
+         new ObjectStreamField("typeName",    String.class)
+      };
+
+   /** The type's class name */
+   private String className;
+
+   // TODO internationalization
+   /** The type's description */
+   private String description;
+
+   /** The type's name */
+   private String typeName;
+
+   /** Whether the class is an array */
+   private transient boolean array = false;
+
+   /**
+    * Construct a new MetaType.<p>
+    *
+    * The class name must be in {@link #ALLOWED_CLASSNAMES} or an
+    * array of those classes.
+    *
+    * @param className the name of the class implementing the meta type,
+    *        cannot be null
+    * @param typeName the name of the meta type, cannot be null
+    * @param description the human readable description of the type, cannot 
+    *        be null
+    * @throws IllegalArgumentException for a null argument or a class is not an allowed class
+    */
+   protected AbstractMetaType(String className, String typeName, String description)
+   {
+      init(className, typeName, description);
+   }
+
+   /**
+    * Construct a new MetaType.<p>
+    *
+    * The class name must be in {@link #ALLOWED_CLASSNAMES} or an
+    * array of those classes.
+    *
+    * @param className the name of the class implementing the meta type,
+    *        cannot be null
+    * @param description the human readable description of the type, cannot 
+    *        be null
+    * @throws IllegalArgumentException for a null argument or a class is not an allowed class
+    */
+   protected AbstractMetaType(String className, String description)
+   {
+      init(className, className, description);
+   }
+
+   /**
+    * Construct a new MetaType.
+    *
+    * The class name must be in {@link #ALLOWED_CLASSNAMES} or an
+    * array of those classes.
+    *
+    * @param className the name of the class implementing the meta type,
+    *        cannot be null
+    * @throws IllegalArgumentException for a null argument or a class is not an allowed class
+    */
+   protected AbstractMetaType(String className)
+   {
+      init(className, className, className);
+   }
+
+   public String getClassName()
+   {
+      return className;
+   }
+
+   public String getTypeName()
+   {
+      return typeName;
+   }
+
+   public String getDescription()
+   {
+      return description;
+   }
+
+   public boolean isArray()
+   {
+      return array;
+   }
+
+   public abstract boolean isValue(Object obj);
+
+   @Override
+   public abstract boolean equals(Object obj);
+
+   @Override
+   public abstract int hashCode();
+
+   @Override
+   public abstract String toString();
+
+   /**
+    * Initialise the object
+    *
+    * @param className the name of the class implementing the meta type,
+    *        cannot be null or an empty
+    * @param typeName the name of the meta type, cannot be null or an empty 
+    *        string
+    * @param description the human readable description of the type, cannot 
+    *        be null or an empty string
+    * @exception IllegalArgumentException for a null or empty argument or when class name is not allowed class
+    */
+   private void init(String className, String typeName, String description)
+   {
+      if (className == null || className.trim().equals(""))
+         throw new IllegalArgumentException("null or empty class name");
+      if (typeName == null || typeName.trim().equals(""))
+         throw new IllegalArgumentException("null or empty type name");
+      if (description == null || description.trim().equals(""))
+         throw new IllegalArgumentException("null or empty description");
+
+      // Calculate the underlying class and whether this is an array
+      String testClassName = getBaseClassName(className);
+      if (testClassName == null)
+         throw new IllegalArgumentException("Invalid array declaration (see the javadocs for java.lang.Class): " + className);
+      if (testClassName.equals(className) == false)
+         array = true;
+
+      // Check the underlying class
+      boolean ok = false;
+      for (int i = 0; i < ALLOWED_CLASSNAMES.length; i++)
+      {
+         if (testClassName.equals(ALLOWED_CLASSNAMES[i]))
+         {
+            ok = true;
+            break;
+         }
+      }
+      if (ok == false)
+         throw new IllegalArgumentException("Not a MetaType allowed class name: " + className);
+
+      // Looks ok
+      this.className = className;
+      this.typeName = typeName;
+      this.description = description;
+   }
+
+   /**
+    * Gets the base class name, either the passed class name
+    * or the underlying class name if it is an array.<p>
+    *
+    * NOTE: The class is not check for validity.<p>
+    *
+    * Null is returned when the array declaration is invalid.
+    *
+    * @param className the string to test
+    * @return the underlying class name or null
+    */
+   private static String getBaseClassName(String className)
+   {
+      final int length = className.length();
+      final int last = length - 1;
+      int i = 0;
+
+      // Eat the array dimensions
+      while (i < length && className.charAt(i) == '[')
+         ++i;
+
+      // It looks like an array
+      if (i > 0)
+      {
+         // But is it valid
+         char type = className.charAt(i);
+         // Primitive array
+         if (type == 'B' || type == 'C' || type == 'D' || type == 'F' ||
+             type == 'I' || type == 'J' || type == 'S' || type == 'Z' || type == 'V')
+         {
+            if (i != last)
+               return null;
+            return className.substring(last, length);
+         }
+         // Object Array
+         else if (className.charAt(i) != 'L' ||
+             i >= last-1 ||
+             className.charAt(last) != ';')
+            return null;
+
+         // Potentially valid array, class name might be rubbish
+         return className.substring(i+1, last);
+      }
+
+      // Not an array
+      return className;
+   }
+
+   /**
+    * Read the object from a stream
+    * 
+    * @param in the stream
+    * @throws IOException 
+    * @throws ClassNotFoundException
+    */
+   private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
+   {
+      ObjectInputStream.GetField getField = in.readFields();
+      String className = (String) getField.get("className", null);
+      String typeName = (String) getField.get("typeName", null);
+      String description = (String) getField.get("description", null);
+      try
+      {
+         init(className, typeName, description);
+      }
+      catch (Exception e)
+      {
+         throw new RuntimeException("Unexpected error deserializing MetaType: " + className, e);
+      }
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/ArrayMetaType.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/ArrayMetaType.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/ArrayMetaType.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,218 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.metatype.api.types;
+
+import java.io.Serializable;
+
+/**
+ * ArrayMetaType.
+ *
+ * @param <T> the underlying type
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ArrayMetaType<T extends Serializable> extends AbstractMetaType<T>
+{
+   /** The serialVersionUID */
+   private static final long serialVersionUID = -2062790692152055156L;
+
+   /** The number of dimensions in the array */
+   private int dimension = 0;
+
+   /** The element type for the array */
+   private MetaType elementType;
+
+   /** Cached hash code */
+   private transient int cachedHashCode = Integer.MIN_VALUE;
+
+   /** Cached string representation */
+   private transient String cachedToString = null;
+
+   /**
+    * Generate the class and type name
+    * 
+    * @param dimension the dimension
+    * @param elementType the element type
+    */
+   private static String genName(int dimension, MetaType elementType)
+   {
+      if (dimension < 1)
+         throw new IllegalArgumentException("negative dimension");
+      if (elementType == null)
+         throw new IllegalArgumentException("null element type");
+      if (elementType instanceof ArrayMetaType)
+         throw new IllegalArgumentException("array type cannot be an element of an array type");
+      StringBuilder buffer = new StringBuilder();
+      for (int i=0; i < dimension; i++)
+         buffer.append('[');
+      buffer.append('L');
+      buffer.append(elementType.getClassName());
+      buffer.append(';');
+      return buffer.toString();
+   }
+
+   /**
+    * Generate the description
+    * 
+    * @param dimension the dimension
+    * @param elementType the element type
+    */
+   private static String genDesc(int dimension, MetaType elementType)
+   {
+      StringBuilder buffer = new StringBuilder();
+      buffer.append(new Integer(dimension));
+      buffer.append("-dimension array of ");
+      buffer.append(elementType.getClassName());
+      return buffer.toString();
+   }
+
+   /**
+    * Construct an ArrayMetaType.
+    *
+    * @param dimension the number of dimensions in the array
+    * @param elementType the open type of the array elements
+    * @throws IllegalArgumentException for a null argument or non-negative dimension or when meta type is an ArrayMetaType
+    */
+   public ArrayMetaType(int dimension, MetaType elementType)
+   {
+      super(genName(dimension, elementType), genDesc(dimension, elementType));
+      this.dimension = dimension;
+      this.elementType = elementType;
+   }
+
+   /**
+    * Get the dimension of the array
+    *
+    * @return the dimension
+    */
+   public int getDimension()
+   {
+      return dimension;
+   }
+
+   /**
+    * Get the meta type of the array elements
+    *
+    * @return the element type
+    */
+   public MetaType getElementType()
+   {
+      return elementType;
+   }
+
+   @Override
+   @SuppressWarnings("unchecked")
+   public boolean isValue(Object obj)
+   {
+      if (obj == null)
+         return false;
+
+      Class clazz = obj.getClass();
+      if (clazz.isArray() == false)
+         return false;
+      
+      if (elementType instanceof SimpleMetaType)
+         return recursiveCheck((Object[]) obj, dimension);
+      
+      if (elementType instanceof TableMetaType || elementType instanceof CompositeMetaType)
+      {
+         Class thisClass = null;
+         try
+         {
+            thisClass = Thread.currentThread().getContextClassLoader().loadClass(getClassName());
+         }
+         catch (ClassNotFoundException e)
+         {
+            return false;
+         }
+         if (thisClass.isAssignableFrom(clazz) == false)
+            return false;
+         return recursiveCheck((Object[]) obj, dimension);
+      }
+      return false;
+   }
+
+   @Override
+   public boolean equals(Object obj)
+   {
+      if (this == obj)
+         return true;
+      if (obj == null || obj instanceof ArrayMetaType == false)
+         return false;
+      ArrayMetaType other = (ArrayMetaType) obj;
+      return getDimension() == other.getDimension() && getElementType().equals(other.getElementType());
+   }
+
+   @Override
+   public int hashCode()
+   {
+      if (cachedHashCode != Integer.MIN_VALUE)
+         return cachedHashCode;
+      cachedHashCode = getDimension() + getElementType().hashCode();
+      return cachedHashCode;
+   }
+
+   @Override
+   public String toString()
+   {
+      if (cachedToString != null)
+         return cachedToString;
+      StringBuilder buffer = new StringBuilder(ArrayMetaType.class.getSimpleName());
+      buffer.append("{type=");
+      buffer.append(getTypeName());
+      buffer.append(" dims=");
+      buffer.append(dimension);
+      buffer.append(" elementType=" + elementType);
+      cachedToString = buffer.toString();
+      return cachedToString;
+   }
+
+   /**
+    * Recursively check array elements
+    * 
+    * @param elements the elements
+    * @param dimension the dimension
+    */
+   private boolean recursiveCheck(Object[] elements, int dimension)
+   {
+      // Reached the end
+      if (dimension == 1)
+      {
+         // Check each element is the correct type
+         for (int i = 0; i < elements.length; i++)
+         {
+            if (elements[i] != null && elementType.isValue(elements[i]) == false)
+               return false;
+         }
+      }
+      else
+      {
+         // Check the array element in this array element
+         for (int i = 0; i < elements.length; i++)
+         {
+            if (recursiveCheck((Object[]) elements[i], dimension-1) == false)
+               return false;
+         }
+      }
+      return true;
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/CompositeMetaType.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/CompositeMetaType.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/CompositeMetaType.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,64 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.metatype.api.types;
+
+import java.util.Set;
+
+/**
+ * CompositeMetaType.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public interface CompositeMetaType extends MetaType
+{
+   /**
+    * Determine whether this CompositeMetaType contains the itemName
+    *
+    * @param itemName the item name
+    * @return true when it does, false otherwise
+    */
+   boolean containsKey(String itemName);
+
+   /**
+    * Retrieve the description for an item name
+    *
+    * @param itemName the item name
+    * @return the description or null when there is no such item name
+    */
+   String getDescription(String itemName);
+
+   /**
+    * Retrieve the meta type for an item name
+    *
+    * @param itemName the item name
+    * @return the open type or null when there is no such item name
+    */
+   MetaType getType(String itemName);
+
+   /**
+    * Retrieve an unmodifiable Set view of all the item names in ascending order.
+    *
+    * @return the Set
+    */
+   Set<String> keySet();
+}

Added: projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/ImmutableCompositeMetaType.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/ImmutableCompositeMetaType.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/ImmutableCompositeMetaType.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,215 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.metatype.api.types;
+
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Set;
+import java.util.TreeMap;
+
+import org.jboss.metatype.api.values.CompositeValue;
+
+/**
+ * ImmutableCompositeMetaType.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ImmutableCompositeMetaType extends AbstractMetaType implements CompositeMetaType
+{
+   /** The serialVersionUID */
+   private static final long serialVersionUID = 1133171306971861455L;
+
+   /** Item names to descriptions */
+   private TreeMap<String, String> nameToDescription;
+
+   /** Item names to meta types */
+   private TreeMap<String, MetaType> nameToType;
+
+   /** Cached hash code */
+   private transient int cachedHashCode = Integer.MIN_VALUE;
+
+   /** Cached string representation */
+   private transient String cachedToString = null;
+
+   /**
+    * Construct a composite meta type. The parameters are checked for validity.<p>
+    *
+    * The three arrays are internally copied. Future changes to these
+    * arrays do not alter the composite type.<p>
+    *
+    * getClassName() returns {@link CompositeValue}<p>
+    *
+    * @param typeName the name of the composite type, cannot be null or  empty
+    * @param description the human readable description of the composite type, cannot be null or empty
+    * @param itemNames the names of the items described by this type. Cannot
+    *        be null, must contain at least one element, the elements cannot
+    *        be null or empty. The order of the items is unimportant when
+    *        determining equality.
+    * @param itemDescriptions the human readable descriptions of the items
+    *        in the same order as the itemNames, cannot be null must have the
+    *        same number of elements as the itemNames. The elements cannot
+    *        be null or empty.
+    * @param itemTypes the MetaTypes of the items in the same order as the
+    *        item names, cannot be null must have the
+    *        same number of elements as the itemNames. The elements cannot
+    *        be null.
+    * @exception IllegalArgumentException when a parameter does not match
+    *            what is described above or when itemNames contains a duplicate name.
+    *            The names are case sensitive, leading and trailing whitespace
+    *            is ignored.
+    */
+   public ImmutableCompositeMetaType(String typeName, String description, String[] itemNames, String[] itemDescriptions, MetaType[] itemTypes)
+   {
+      super(CompositeValue.class.getName(), typeName, description);
+      if (itemNames == null || itemNames.length == 0)
+         throw new IllegalArgumentException("null or empty itemNames");
+      if (itemDescriptions == null || itemDescriptions.length == 0)
+         throw new IllegalArgumentException("null or empty itemDescriptions");
+      if (itemTypes == null || itemTypes.length == 0)
+         throw new IllegalArgumentException("null or empty itemTypes");
+      if (itemNames.length != itemDescriptions.length)
+         throw new IllegalArgumentException("wrong number of itemDescriptions");
+      if (itemNames.length != itemTypes.length)
+         throw new IllegalArgumentException("wrong number of itemTypes");
+      nameToDescription = new TreeMap<String, String>();
+      nameToType = new TreeMap<String, MetaType>();
+      for (int i = 0; i < itemNames.length; ++i)
+      {
+          if (itemNames[i] == null)
+             throw new IllegalArgumentException("null item name " + i);
+          String itemName = itemNames[i].trim();
+          if (itemName.length() == 0)
+             throw new IllegalArgumentException("empty item name " + i);
+          if (nameToDescription.containsKey(itemName))
+             throw new IllegalArgumentException("duplicate item name " + itemName);
+          if (itemDescriptions[i] == null)
+             throw new IllegalArgumentException("null item description " + i);
+          String itemDescription = itemDescriptions[i].trim();
+          if (itemDescription.length() == 0)
+             throw new IllegalArgumentException("empty item description " + i);
+          if (itemTypes[i] == null)
+             throw new IllegalArgumentException("null item type " + i);
+          nameToDescription.put(itemName, itemDescription);
+          nameToType.put(itemName, itemTypes[i]);
+      }
+   }
+
+   public boolean containsKey(String itemName)
+   {
+      if (itemName == null)
+         return false;
+      return nameToDescription.containsKey(itemName);
+   }
+
+   public String getDescription(String itemName)
+   {
+      if (itemName == null)
+         return null;
+      return nameToDescription.get(itemName);
+   }
+
+   public MetaType getType(String itemName)
+   {
+      if (itemName == null)
+         return null;
+      return nameToType.get(itemName);
+   }
+
+   public Set<String> keySet()
+   {
+      return Collections.unmodifiableSet(nameToDescription.keySet());
+   }
+
+   @Override
+   public boolean isValue(Object obj)
+   {
+      if (obj == null || obj instanceof CompositeValue == false)
+         return false;
+      return equals(((CompositeValue) obj).getMetaType());
+   }
+
+   @Override
+   public boolean equals(Object obj)
+   {
+      if (this == obj)
+         return true;
+      if (obj == null || obj instanceof ImmutableCompositeMetaType == false)
+         return false;
+
+      ImmutableCompositeMetaType other = (ImmutableCompositeMetaType) obj;
+      if (this.getTypeName().equals(other.getTypeName()) == false)
+         return false;
+      Iterator<String> thisNames = this.keySet().iterator();
+      Iterator<String> otherNames = other.keySet().iterator();
+      while(thisNames.hasNext() && otherNames.hasNext())
+      {
+         String thisName = thisNames.next();
+         String otherName = otherNames.next();
+         if (thisName.equals(otherName) == false)
+            return false;
+         if (this.getType(thisName).equals(other.getType(otherName)) == false)
+            return false;
+      }
+      if (thisNames.hasNext() || otherNames.hasNext())
+         return false;
+      
+      return true;
+   }
+
+   @Override
+   public int hashCode()
+   {
+      if (cachedHashCode != Integer.MIN_VALUE)
+         return cachedHashCode;
+      cachedHashCode = getTypeName().hashCode();
+      for (Iterator i = nameToType.values().iterator(); i.hasNext();)
+         cachedHashCode += i.next().hashCode();
+      for (Iterator i = nameToDescription.keySet().iterator(); i.hasNext();)
+         cachedHashCode += i.next().hashCode();
+      return cachedHashCode;
+   }
+
+   @Override
+   public String toString()
+   {
+      if (cachedToString != null)
+         return cachedToString;
+      StringBuilder buffer = new StringBuilder(getClass().getSimpleName());
+      buffer.append("{items=");
+      Iterator<String> thisNames = keySet().iterator();
+      while(thisNames.hasNext())
+      {
+         String thisName = thisNames.next();
+         buffer.append("[");
+         buffer.append("name=");
+         buffer.append(thisName);
+         buffer.append(" type=");
+         buffer.append(getType(thisName));
+         buffer.append("]");
+         if (thisNames.hasNext())
+           buffer.append(", ");
+      }
+      cachedToString = buffer.toString();
+      return cachedToString;
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/ImmutableTableMetaType.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/ImmutableTableMetaType.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/ImmutableTableMetaType.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,167 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.metatype.api.types;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.jboss.metatype.api.values.TableValue;
+
+public class ImmutableTableMetaType extends AbstractMetaType implements TableMetaType
+{
+   /** The serialVersionUID */
+   private static final long serialVersionUID = 5791103660662775558L;
+
+   /** The open type of the rows */
+   private CompositeMetaType rowType;
+
+   /** Index names */
+   private List<String> indexNames;
+
+   /** Cached hash code */
+   private transient int cachedHashCode = Integer.MIN_VALUE;
+
+   /** Cached string representation */
+   private transient String cachedToString = null;
+
+   /**
+    * Construct a tabe type. The parameters are checked for validity.
+    *
+    * @param typeName the name of the tabular type, cannot be null or empty
+    * @param description the human readable description of the tabular type, cannot be null or empty
+    * @param rowType the type of the row elements in the tabular data, cannot be null
+    * @param indexNames the names of the item values that uniquely index each
+    *        row element in the tabular data, cannot be null or empty. Each
+    *        element must be an item name in the rowType, nul or empty is not
+    *        allowed. The order of the item names in this parameter is used
+    *        by {@link TableValue#get} and {@link TableValue#remove} the 
+    *        TabularValue to match the array of values to items.
+    * @throws IllegalArgumentException when a parameter does not match
+    *         what is described above or when an element of indexNames is not defined
+    *         in rowType.
+    */
+   public ImmutableTableMetaType(String typeName, String description, CompositeMetaType rowType, String[] indexNames)
+   {
+      super(TableValue.class.getName(), typeName, description);
+      if (rowType == null)
+         throw new IllegalArgumentException("null rowType");
+      if (indexNames == null || indexNames.length == 0)
+         throw new IllegalArgumentException("null or empty indexNames");
+      this.rowType = rowType;
+      this.indexNames = new ArrayList<String>();
+      for (int i = 0; i < indexNames.length; i++)
+      {
+          if (indexNames[i] == null)
+             throw new IllegalArgumentException("null index name " + i);
+          String indexName = indexNames[i].trim();
+          if (indexName.length() == 0)
+             throw new IllegalArgumentException("empty index name " + i);
+          if (rowType.containsKey(indexName) == false)
+             throw new IllegalArgumentException("no item name " + indexName);
+          this.indexNames.add(indexName);
+      }
+   }
+
+   public CompositeMetaType getRowType()
+   {
+      return rowType;
+   }
+
+   public List<String> getIndexNames()
+   {
+      return Collections.unmodifiableList(indexNames);
+   }
+
+   @Override
+   public boolean isValue(Object obj)
+   {
+      if (obj == null || obj instanceof TableValue == false)
+         return false;
+      TableMetaType other = ((TableValue) obj).getMetaType();
+      return equals(other);
+   }
+   
+   @Override
+   public boolean equals(Object obj)
+   {
+      if (this == obj)
+         return true;
+      if (obj == null || obj instanceof TableMetaType == false)
+         return false;
+
+      TableMetaType other = (TableMetaType) obj;
+      if (this.getTypeName().equals(other.getTypeName()) == false)
+         return false;
+      if (this.getRowType().equals(other.getRowType()) == false)
+         return false;
+      Iterator<String> thisNames = this.getIndexNames().iterator();
+      Iterator<String> otherNames = other.getIndexNames().iterator();
+      while (thisNames.hasNext() && otherNames.hasNext())
+      {
+         String thisName = thisNames.next();
+         String otherName = otherNames.next();
+         if (thisName.equals(otherName) == false)
+            return false;
+      }
+      if (thisNames.hasNext() || otherNames.hasNext())
+         return false;
+
+      return true;
+   }
+
+   @Override
+   public int hashCode()
+   {
+      if (cachedHashCode != Integer.MIN_VALUE)
+         return cachedHashCode;
+      cachedHashCode = getTypeName().hashCode();
+      cachedHashCode += getRowType().hashCode();
+      for (Iterator i = indexNames.iterator(); i.hasNext();)
+         cachedHashCode += i.next().hashCode();
+      return cachedHashCode;
+   }
+
+   @Override
+   public String toString()
+   {
+      if (cachedToString != null)
+         return cachedToString;
+      StringBuilder buffer = new StringBuilder(getClass().getSimpleName());
+      buffer.append(": typeName=[");
+      buffer.append(getTypeName());
+      buffer.append("] rowType=[");
+      buffer.append(getRowType());
+      buffer.append("] indexNames=[");
+      Iterator thisNames = getIndexNames().iterator();
+      while(thisNames.hasNext())
+      {
+         buffer.append(thisNames.next());
+         if (thisNames.hasNext())
+            buffer.append(", ");
+      }
+      buffer.append("]");
+      cachedToString = buffer.toString();
+      return cachedToString;
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/MetaType.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/MetaType.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/MetaType.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,120 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.metatype.api.types;
+
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+
+import org.jboss.metatype.api.values.CompositeValue;
+import org.jboss.metatype.api.values.SimpleValue;
+import org.jboss.metatype.api.values.TableValue;
+
+/**
+ * MetaType.
+ * 
+ * @param <T> the underlying type
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public interface MetaType<T extends Serializable> extends Serializable
+{
+   /**
+    * The allowed classnames.<p>
+    *
+    * One of<br>
+    * java.lang.Void<br>
+    * java.lang.Boolean<br>
+    * java.lang.Character<br>
+    * java.lang.Byte<br>
+    * java.lang.Short<br>
+    * java.lang.Integer<br>
+    * java.lang.Long<br>
+    * java.lang.Float<br>
+    * java.lang.Double<br>
+    * java.lang.String<br>
+    * java.lang.Date<br>
+    * java.math.BigDecimal<br>
+    * java.math.BigInteger<br>
+    * {@link SimpleValue}<br>
+    * {@link CompositeValue}<br>
+    * {@link TableValue}
+    */
+   String[] ALLOWED_CLASSNAMES =
+   {
+      Void.class.getName(),
+      Boolean.class.getName(),
+      Character.class.getName(),
+      Byte.class.getName(),
+      Short.class.getName(),
+      Integer.class.getName(),
+      Long.class.getName(),
+      Float.class.getName(),
+      Double.class.getName(),
+      String.class.getName(),
+      Date.class.getName(),
+      BigDecimal.class.getName(),
+      BigInteger.class.getName(),
+      SimpleValue.class.getName(),
+      CompositeValue.class.getName(),
+      TableValue.class.getName()
+   };
+
+   /**
+    * Retrieve the class name of the values of this meta
+    * type. It is one of those listed in ALLOWED_CLASSNAMES or
+    * a (multi-dimensional) array of one of those classes.
+    *
+    * @return the class name
+    */
+   String getClassName();
+
+   /**
+    * Retrieve the name of the meta type
+    *
+    * @return the type name
+    */
+   String getTypeName();
+
+   /**
+    * Retrieve the description of the type
+    *
+    * @return the description
+    */
+   String getDescription();
+
+   /**
+    * Retrieve whether the class name of the type is an array
+    *
+    * @return true when it is an array or false otherwise
+    */
+   boolean isArray();
+
+   /**
+    * Whether the passed value is one of those described by this meta type.
+    *
+    * @param obj the object to test
+    * @return true when it is value for this meta type, false otherwise
+    */
+   boolean isValue(Object obj);
+}

Added: projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/SimpleMetaType.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/SimpleMetaType.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/SimpleMetaType.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,205 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.metatype.api.types;
+
+import java.io.ObjectStreamException;
+import java.io.Serializable;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+
+import org.jboss.metatype.api.values.SimpleValue;
+
+/**
+ * SimpleMetaType.
+ *
+ * @param <T> the underlying type
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class SimpleMetaType<T extends Serializable> extends AbstractMetaType<T>
+{
+   /** The serialVersionUID */
+   private static final long serialVersionUID = 6786422588217893696L;
+
+   /** Cached hash code */
+   private transient int cachedHashCode;
+
+   /** Cached string representation */
+   private transient String cachedToString;
+
+   /** The simple type for java.math.BigDecimal */
+   public static final SimpleMetaType<BigDecimal> BIGDECIMAL;
+
+   /** The simple type for java.math.BigInteger */
+   public static final SimpleMetaType<BigInteger> BIGINTEGER;
+
+   /** The simple type for java.lang.Boolean */
+   public static final SimpleMetaType<Boolean> BOOLEAN;
+
+   /** The simple type for java.lang.Byte */
+   public static final SimpleMetaType<Byte> BYTE;
+
+   /** The simple type for java.lang.Character */
+   public static final SimpleMetaType<Character> CHARACTER;
+
+   /** The simple type for java.lang.Date */
+   public static final SimpleMetaType<Date> DATE;
+
+   /** The simple type for java.lang.Double */
+   public static final SimpleMetaType<Double> DOUBLE;
+
+   /** The simple type for java.lang.Float */
+   public static final SimpleMetaType<Float> FLOAT;
+
+   /** The simple type for java.lang.Integer */
+   public static final SimpleMetaType<Integer> INTEGER;
+
+   /** The simple type for java.lang.Long */
+   public static final SimpleMetaType<Long> LONG;
+
+   /** The simple type for java.lang.Short */
+   public static final SimpleMetaType<Short> SHORT;
+
+   /** The simple type for java.lang.String */
+   public static final SimpleMetaType<String> STRING;
+
+   /** The simple type for java.lang.Void */
+   public static final SimpleMetaType VOID;
+
+   static
+   {
+      BIGDECIMAL = new SimpleMetaType<BigDecimal>(BigDecimal.class.getName());
+      BIGINTEGER = new SimpleMetaType<BigInteger>(BigInteger.class.getName());
+      BOOLEAN = new SimpleMetaType<Boolean>(Boolean.class.getName());
+      BYTE = new SimpleMetaType<Byte>(Byte.class.getName());
+      CHARACTER = new SimpleMetaType<Character>(Character.class.getName());
+      DATE = new SimpleMetaType<Date>(Date.class.getName());
+      DOUBLE = new SimpleMetaType<Double>(Double.class.getName());
+      FLOAT = new SimpleMetaType<Float>(Float.class.getName());
+      INTEGER = new SimpleMetaType<Integer>(Integer.class.getName());
+      LONG = new SimpleMetaType<Long>(Long.class.getName());
+      SHORT = new SimpleMetaType<Short>(Short.class.getName());
+      STRING = new SimpleMetaType<String>(String.class.getName());
+      VOID = new SimpleMetaType(Void.class.getName());
+   }
+
+   /**
+    * Resolve a simple type
+    *
+    * @param className the class name of the simple type
+    * @return the simple type
+    */
+   public static SimpleMetaType resolve(String className)
+   {
+      if (className == null)
+         throw new IllegalArgumentException("Null class name");
+      if (className.equals(STRING.getClassName()))
+         return STRING;
+      if (className.equals(INTEGER.getClassName()))
+         return INTEGER;
+      if (className.equals(BOOLEAN.getClassName()))
+         return BOOLEAN;
+      if (className.equals(LONG.getClassName()))
+         return LONG;
+      if (className.equals(BYTE.getClassName()))
+         return BYTE;
+      if (className.equals(CHARACTER.getClassName()))
+         return CHARACTER;
+      if (className.equals(DOUBLE.getClassName()))
+         return DOUBLE;
+      if (className.equals(FLOAT.getClassName()))
+         return FLOAT;
+      if (className.equals(SHORT.getClassName()))
+         return SHORT;
+      if (className.equals(BIGDECIMAL.getClassName()))
+         return BIGDECIMAL;
+      if (className.equals(BIGINTEGER.getClassName()))
+         return BIGINTEGER;
+      if (className.equals(VOID.getClassName()))
+         return VOID;
+      if (className.equals(DATE.getClassName()))
+         return DATE;
+      throw new IllegalArgumentException(className);
+   }
+
+   /**
+    * Construct an SimpleMetaType.<p>
+    *
+    * This constructor is used to construct the static simple meta types.
+    *
+    * @param className the name of the class implementing the type
+    */
+   private SimpleMetaType(String className)
+   {
+      super(className);
+      cachedHashCode = getClassName().hashCode();
+      StringBuilder buffer = new StringBuilder(SimpleMetaType.class.getSimpleName());
+      buffer.append(":");
+      buffer.append(getClassName());
+      cachedToString = buffer.toString();
+   }
+
+   @Override
+   public boolean isValue(Object obj)
+   {
+      if (obj == null || obj instanceof SimpleValue == false)
+         return false;
+
+      SimpleValue value = (SimpleValue) obj;
+      return equals(value.getMetaType());
+   }
+
+   @Override
+   public boolean equals(Object obj)
+   {
+      if (this == obj)
+         return true;
+      if (obj == null || obj instanceof SimpleMetaType == false)
+         return false;
+      SimpleMetaType other = (SimpleMetaType) obj;
+      return getClassName().equals(other.getClassName());
+   }
+
+   @Override
+   public int hashCode()
+   {
+      return cachedHashCode;
+   }
+
+   @Override
+   public String toString()
+   {
+      return cachedToString;
+   }
+
+   /**
+    * Resolve to the singletons
+
+    * @return the singletons
+    * @throws ObjectStreamException for a corrupted stream
+    */
+   private Object readResolve() throws ObjectStreamException
+   {
+      return resolve(getClassName());
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/TableMetaType.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/TableMetaType.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/types/TableMetaType.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,48 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.metatype.api.types;
+
+import java.util.List;
+
+/**
+ * TableMetaType.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public interface TableMetaType extends MetaType
+{
+   /**
+    * Retrieve the row type
+    *
+    * @return the row type
+    */
+   CompositeMetaType getRowType();
+
+   /**
+    * Retrieve an unmodifiable list of index names in the same order as
+    * passed to the constructor.
+    *
+    * @return the index names
+    */
+   List<String> getIndexNames();
+}

Added: projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/AbstractMetaValue.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/AbstractMetaValue.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/AbstractMetaValue.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,47 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.metatype.api.values;
+
+/**
+ * AbstractMetaValue.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public abstract class AbstractMetaValue implements MetaValue
+{
+   /** The serialVersionUID */
+   private static final long serialVersionUID = -2213622770885293629L;
+
+   @Override
+   public MetaValue clone()
+   {
+      try
+      {
+         return (AbstractMetaValue) super.clone();
+      }
+      catch (CloneNotSupportedException e)
+      {
+         throw new Error("Unexpected error in clone: ", e);
+      }
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/CompositeValue.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/CompositeValue.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/CompositeValue.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,114 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.metatype.api.values;
+
+import java.util.Collection;
+
+import org.jboss.metatype.api.types.CompositeMetaType;
+
+/**
+ * CompositeValue.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public interface CompositeValue extends MetaValue
+{
+   CompositeMetaType getMetaType();
+   
+   /**
+    * Retrieve the value for the item with the passed key
+    *
+    * @param key the key to the item
+    * @return the value
+    * @throws IllegalArgumentException when the key is null or the empty string or when the key does not exist 
+    */
+   MetaValue get(String key);
+
+   /**
+    * Retrieve the array of values for the item with the passed keys
+    *
+    * @param keys an array of key values
+    * @return the array of values
+    * @throws IllegalArgumentException when a key is null or the empty
+    *         string or the array is null or when a key does not exist 
+    */
+   MetaValue[] getAll(String[] keys);
+
+   /**
+    * Tests whether a key is part of this composite value
+    *
+    * @param key the key to test
+    * @return true when the key exists, false otherwise
+    */
+   boolean containsKey(String key);
+
+   /**
+    * Tests whether a item exists with the passed value
+    *
+    * @param value the value to test
+    * @return true when the value exists, false otherwise
+    */
+   boolean containsValue(MetaValue value);
+
+   /**
+    * The values of this composite value<p>
+    *
+    * An iterator over the returned collection returns result in ascending
+    * lexicographic order
+    *
+    * @return an unmodifiable Collection of the values of this CompositeMetaType.
+    */
+   Collection<MetaValue> values();
+
+   /**
+    * Tests whether two composite value objects are equal<p>
+    *
+    * The object is non-null<br>
+    * The object implements this interface<br>
+    * The composite meta types are equal<br>
+    * The values are equal
+    *
+    * @param obj the object to test
+    * @return true when the above conditions are satisfied, false otherwise.
+    */
+   boolean equals(Object obj);
+
+   /**
+    * Generates a hashcode for the implementation.<p>
+    *
+    * The sum of the hashCodes for the elements mentioned in the equals method
+    *
+    * @return the calculated hashcode
+    */
+   int hashCode();
+
+   /**
+    * A string representation of the open mbean operation info.<p>
+    *
+    * It is made up of implementation class and the values mentioned
+    * in the equals method
+    *
+    * @return the string
+    */
+   String toString();
+}

Added: projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/CompositeValueSupport.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/CompositeValueSupport.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/CompositeValueSupport.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,296 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.metatype.api.values;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamField;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.TreeMap;
+import java.util.Map.Entry;
+
+import org.jboss.metatype.api.types.CompositeMetaType;
+import org.jboss.metatype.api.types.MetaType;
+
+/**
+ * CompositeValueSupport.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class CompositeValueSupport extends AbstractMetaValue implements CompositeValue
+{
+   /** The serialVersionUID */
+   private static final long serialVersionUID = 6262188760975631870L;
+   
+   /** The serialized form */
+   private static final ObjectStreamField[] serialPersistentFields =
+      new ObjectStreamField[]
+      {
+         new ObjectStreamField("contents", SortedMap.class),
+         new ObjectStreamField("metaType", CompositeMetaType.class),
+      };
+
+   /** The contents */
+   private SortedMap<String, MetaValue> contents;
+
+   /** The composite type */
+   private CompositeMetaType metaType;
+
+   /** cached hashCode */
+   private transient int cachedHashCode = Integer.MIN_VALUE;
+
+   /**
+    * Construct Composite Value 
+    *
+    * @param metaType the composite meta type of the data
+    * @param itemNames the names of the values
+    * @param itemValues the values
+    * @throws IllegalArgumentException for a null or empty argument or when the items do not match the
+    *         CompositeType
+    */
+   public CompositeValueSupport(CompositeMetaType metaType, String[] itemNames, MetaValue[] itemValues)
+   {
+      if (metaType == null)
+         throw new IllegalArgumentException("null meta type");
+      if (itemNames == null)
+         throw new IllegalArgumentException("null itemNames");
+      if (itemValues == null)
+         throw new IllegalArgumentException("null itemValues");
+      if (itemNames.length == 0)
+         throw new IllegalArgumentException("empty itemNames");
+      if (itemValues.length == 0)
+         throw new IllegalArgumentException("empty itemValues");
+      if (itemNames.length != itemValues.length)
+         throw new IllegalArgumentException("itemNames has size " + itemNames.length + " but itemValues has size " + itemValues.length);
+
+      int compositeNameSize = metaType.keySet().size();
+      if (itemNames.length != compositeNameSize)
+         throw new IllegalArgumentException("itemNames has size " + itemNames.length + " but composite type has size " + compositeNameSize);
+
+      this.metaType = metaType;
+      contents = new TreeMap<String, MetaValue>();
+
+      for (int i = 0; i < itemNames.length; i++)
+      {
+         if (itemNames[i] == null || itemNames[i].length() == 0)
+            throw new IllegalArgumentException("Item name " + i + " is null or empty");
+         if (contents.get(itemNames[i]) != null)
+            throw new IllegalArgumentException("duplicate item name " + itemNames[i]);
+         MetaType itemType = metaType.getType(itemNames[i]);
+         if (itemType == null)
+            throw new IllegalArgumentException("item name not in composite type " + itemNames[i]);
+         if (itemValues[i] != null && itemType.isValue(itemValues[i]) == false)
+            throw new IllegalArgumentException("item value " + itemValues[i] + " for item name " + itemNames[i] + " is not a " + itemType);
+         contents.put(itemNames[i], itemValues[i]);
+      }
+   }
+
+   /**
+    * Construct Composite Value 
+    *
+    * @param compositeMetaType the composite type of the data
+    * @param items map of strings to values
+    * @throws IllegalArgumentException for a null or empty argument or when the items do not match the
+    *         CompositeType
+    */
+   public CompositeValueSupport(CompositeMetaType compositeMetaType, Map<String, MetaValue> items)
+   {
+      init(compositeMetaType, items);
+   }
+
+   public CompositeMetaType getMetaType()
+   {
+      return metaType;
+   }
+
+   public MetaValue get(String key)
+   {
+      validateKey(key);
+      return contents.get(key);
+   }
+
+   public MetaValue[] getAll(String[] keys)
+   {
+      if (keys == null)
+         throw new IllegalArgumentException("Null keys");
+
+      MetaValue[] result = new MetaValue[keys.length];
+      for (int i = 0; i < keys.length; i++)
+      {
+         validateKey(keys[i]);
+         result[i] = contents.get(keys[i]);
+      }
+      return result;
+   }
+
+   public boolean containsKey(String key)
+   {
+      if (key == null || key.length() == 0)
+         return false;
+      return contents.containsKey(key);
+   }
+
+   public boolean containsValue(MetaValue value)
+   {
+      return contents.containsValue(value);
+   }
+
+   public Collection<MetaValue> values()
+   {
+      return Collections.unmodifiableCollection(contents.values());
+   }
+
+   @Override
+   public boolean equals(Object obj)
+   {
+      if (obj == this)
+         return true;
+      if (obj == null || obj instanceof CompositeValue == false)
+         return false;
+
+      CompositeValue other = (CompositeValue) obj;
+      if (getMetaType().equals(other.getMetaType()) == false)
+         return false;
+      if (values().size() != other.values().size())
+         return false;
+
+      for (String key : contents.keySet())
+      {
+         Object thisValue = this.get(key);
+         Object otherValue = other.get(key);
+         if ((thisValue == null && otherValue == null || thisValue != null && thisValue.equals(otherValue)) == false)
+            return false;
+      }
+      return true;
+   }
+   
+   @Override
+   public int hashCode()
+   {
+      if (cachedHashCode != Integer.MIN_VALUE)
+         return cachedHashCode;
+
+      cachedHashCode = getMetaType().hashCode();
+      for (Object value : contents.values())
+      {
+         if (value != null)
+            cachedHashCode += value.hashCode();
+      }
+      
+      return cachedHashCode;
+   }
+
+   @Override
+   public String toString()
+   {
+      CompositeMetaType metaType = getMetaType();
+      StringBuilder buffer = new StringBuilder(getClass().getSimpleName());
+      buffer.append(": netaType=[");
+      buffer.append(metaType);
+      buffer.append("] mappings=[");
+      Iterator keys = metaType.keySet().iterator();
+      while(keys.hasNext())
+      {
+         Object key = keys.next();
+         buffer.append(key + "=" + contents.get(key));
+         if (keys.hasNext())
+            buffer.append(",");
+      }
+      buffer.append("]");
+      return buffer.toString();
+   }
+
+   /**
+    * Validates the key against the composite type
+    *
+    * @param key the key to check
+    * @throws IllegalArgumentException for a null or empty key or when 
+    *         the key not a valid item name for the composite type
+    */
+   private void validateKey(String key)
+   {
+      if (key == null || key.length() == 0)
+         throw new IllegalArgumentException("null or empty key");
+      CompositeMetaType metaType = getMetaType();
+      if (metaType.containsKey(key) == false)
+         throw new IllegalArgumentException("no such item name " + key + " for composite type " + metaType);
+   }
+
+   /**
+    * Construct Composite Value 
+    *
+    * @param metaType the composite type of the data
+    * @param items map of strings to values
+    * @throws IllegalArgumentException for a null or empty argument or when the items do not match the
+    *         CompositeType
+    */
+   private void init(CompositeMetaType metaType, Map<String, MetaValue> items)
+   {
+      if (metaType == null)
+         throw new IllegalArgumentException("null meta type");
+      if (items == null)
+         throw new IllegalArgumentException("null items");
+      if (items.size() == 0)
+         throw new IllegalArgumentException("empty items");
+      int compositeNameSize = metaType.keySet().size();
+      if (items.size() != compositeNameSize)
+         throw new IllegalArgumentException("items has size " + items.size() + " but composite type has size " + compositeNameSize);
+
+      this.metaType = metaType;
+      contents = new TreeMap<String, MetaValue>();
+
+      for (Entry<String, MetaValue> entry : items.entrySet())
+      {
+         String key = entry.getKey();
+         if (key == null || key.length() == 0)
+            throw new IllegalArgumentException("Key is null or empty");
+         MetaType itemType = metaType.getType(key);
+         if (itemType == null)
+            throw new IllegalArgumentException("item name not in composite type " + key);
+         MetaValue value = items.get(key);
+         if (value != null && itemType.isValue(value) == false)
+            throw new IllegalArgumentException("item value " + value + " for item name " + key + " is not a " + itemType);
+         contents.put(key, value);
+      }
+   }
+
+   @SuppressWarnings("unchecked")
+   private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
+   {
+      ObjectInputStream.GetField getField = in.readFields();
+      SortedMap contents = (SortedMap) getField.get("contents", null);
+      CompositeMetaType compositeType = (CompositeMetaType) getField.get("metaType", null);
+      try
+      {
+         init(compositeType, contents);
+      }
+      catch (Exception e)
+      {
+         throw new RuntimeException("Error deserializing composite value", e);
+      }
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/MetaValue.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/MetaValue.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/MetaValue.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,49 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.metatype.api.values;
+
+import java.io.Serializable;
+
+import org.jboss.metatype.api.types.MetaType;
+
+/**
+ * MetaValue.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public interface MetaValue extends Serializable, Cloneable
+{
+   /**
+    * Get the metatype for this value
+    * 
+    * @return the metatype
+    */
+   MetaType getMetaType();
+   
+   /**
+    * Clone the meta value
+    * 
+    * @return the cloned meta value
+    */
+   MetaValue clone();
+}

Added: projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/SimpleValue.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/SimpleValue.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/SimpleValue.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,45 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.metatype.api.values;
+
+import java.io.Serializable;
+
+import org.jboss.metatype.api.types.SimpleMetaType;
+
+/**
+ * SimpleValue.
+ * 
+ * @param <T> the underlying type 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public interface SimpleValue<T extends Serializable> extends MetaValue
+{
+   SimpleMetaType<T> getMetaType();
+   
+   /**
+    * Get the underlying value
+    * 
+    * @return the underlying value
+    */
+   public T getValue();
+}

Added: projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/SimpleValueSupport.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/SimpleValueSupport.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/SimpleValueSupport.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,137 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.metatype.api.values;
+
+import java.io.Serializable;
+
+import org.jboss.metatype.api.types.SimpleMetaType;
+
+/**
+ * SimpleValue.
+ * 
+ * @param <T> the underlying type 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class SimpleValueSupport<T extends Serializable> extends AbstractMetaValue implements SimpleValue<T>
+{
+   /** The serialVersionUID */
+   private static final long serialVersionUID = 8473043036261557127L;
+   
+   /** The simple meta type */
+   private SimpleMetaType<T> metaType;
+   
+   /** The value */
+   private T value;
+
+   /**
+    * Wrap a simple object in simple value
+    * 
+    * @param <T> the underlying type
+    * @param object the simple object
+    * @return the simple value
+    */
+   @SuppressWarnings("unchecked")
+   public static <T extends Serializable> SimpleValue<T> wrap(T object)
+   {
+      if (object == null)
+         return null;
+      String className = object.getClass().getName();
+      SimpleMetaType<T> metaType = SimpleMetaType.resolve(className);
+      return new SimpleValueSupport<T>(metaType, object);
+   }
+   
+   /**
+    * Create a new SimpleValueSupport.
+    * 
+    * @param metaType the simple meta type
+    * @param value the value
+    * @throws IllegalArgumentException for a null simpleMetaType
+    */
+   public SimpleValueSupport(SimpleMetaType<T> metaType, T value)
+   {
+      if (metaType == null)
+         throw new IllegalArgumentException("Null simple meta type");
+      this.metaType = metaType;
+      this.value = value;
+   }
+
+   public SimpleMetaType<T> getMetaType()
+   {
+      return metaType;
+   }
+
+   /**
+    * Get the value.
+    * 
+    * @return the value.
+    */
+   public T getValue()
+   {
+      return value;
+   }
+
+   /**
+    * Set the value.
+    * 
+    * @param value the value.
+    */
+   public void setValue(T value)
+   {
+      this.value = value;
+   } 
+
+   @Override
+   public boolean equals(Object obj)
+   {
+      if (obj == this)
+         return true;
+      
+      if (obj == null || obj instanceof SimpleValue == false)
+         return false;
+
+      SimpleValue other = (SimpleValue) obj;
+      if (metaType.equals(other.getMetaType()) == false)
+         return false;
+
+      Object otherValue = other.getValue();
+      if (value == null && otherValue == null)
+         return true;
+      if (value == null && otherValue != null)
+         return false;
+      return value.equals(otherValue);
+   }
+   
+   @Override
+   public int hashCode()
+   {
+      if (value == null)
+         return 0;
+      return value.hashCode();
+   }
+
+   @Override
+   public String toString()
+   {
+      return metaType + ":" + value;
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/TableValue.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/TableValue.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/TableValue.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,137 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.metatype.api.values;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import org.jboss.metatype.api.types.TableMetaType;
+
+public interface TableValue extends MetaValue
+{
+   TableMetaType getMetaType();
+
+   /**
+    * Calculate the index for the value passed if it were added to the
+    * table value. The validity of the passed value is checked. But the
+    * table value isn't checked to see whether the index is already used.
+    *
+    * @param value the value for which the index is calculated.
+    * @return the calculated index
+    * @throws IllegalArgumentException for a null value or when the passed value is not valid for the table value's row type.
+    */
+   MetaValue[] calculateIndex(CompositeValue value);
+
+   /**
+    * Retrieve the number of rows in the table value.
+    *
+    * @return the number of rows.
+    */
+   int size();
+
+   /**
+    * Determine whether the table value is empty.
+    *
+    * @return true when there are no rows, false otherwise
+    */
+   boolean isEmpty();
+
+   /**
+    * Determine whether the table value contains the passed value as a row.
+    * If the passed value is null or invalid, false is returned.
+    *
+    * @param key the value to check
+    * @return true when the value is a row index, false otherwise
+    */
+   boolean containsKey(MetaValue[] key);
+
+   /**
+    * Determine whether the table value contains the passed value.
+    * If the passed value is null or invalid, false is returned.
+    *
+    * @param value the value to check
+    * @return true when the value is a row index, false otherwise
+    */
+   boolean containsValue(CompositeValue value);
+
+   /**
+    * Retrieve the composite value for the passed index.
+    *
+    * @param key the index to retrieve
+    * @return the composite value
+    * @throws IllegalArgumentException when the passed key is null or when the passed key does match the row type of the table value.
+    */
+   CompositeValue get(MetaValue[] key);
+
+   /**
+    * Add a value to the table value. The value must have the same
+    * CompositeMetaType has the table value and there is no value already
+    * occupying the index for the value.
+    *
+    * @param value the value to add
+    * @throws IllegalArgumentException when the passed value is null or when the value is not valid for
+    *         the row type of the tabular data or when the index for the value is already occupied.
+    */
+   void put(CompositeValue value);
+
+   /**
+    * Removes the value for the passed and returns the removed value, or
+    * null if the key was not present.
+    *
+    * @param key the index of the value to remove
+    * @return the removed value
+    * @throws IllegalArgumentException when the passed key is null or when the key is not valid for the table value
+    */
+   CompositeValue remove(MetaValue[] key);
+      
+   /**
+    * Add all the passed values. All the values are checked before
+    * addition including any duplicates that might be added. Either all
+    * or no value is added.
+    *
+    * @param values the values to add
+    * @throws IllegalArgumentException when the passed values is null or an element of the values is null
+    *         or when one of value is not valid for the row type of the table value or when
+    *         the index for one of the values is already occupied.
+    */
+   void putAll(CompositeValue[] values);
+      
+   /**
+    * Removes all CompositeValues from the Table value
+    */
+   void clear();
+      
+   /**
+    * Returns a set view of the index values.
+    *
+    * @return the set of index values.
+    */
+   Set<List<MetaValue>> keySet();
+   
+   /**
+    * Returns a set view of the row values.
+    *
+    * @return the set of row values.
+    */
+   Collection<CompositeValue> values();
+}

Added: projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/TableValueSupport.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/TableValueSupport.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/main/org/jboss/metatype/api/values/TableValueSupport.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,317 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.metatype.api.values;
+
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectStreamField;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+import java.util.Map.Entry;
+
+import org.jboss.metatype.api.types.MetaType;
+import org.jboss.metatype.api.types.TableMetaType;
+
+/**
+ * TableValueSupport.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class TableValueSupport extends AbstractMetaValue implements TableValue
+{
+   /** The serialVersionUID */
+   private static final long serialVersionUID = -6862672408820383430L;
+
+   /** The serialized form */
+   private static final ObjectStreamField[] serialPersistentFields =
+      new ObjectStreamField[]
+      {
+         new ObjectStreamField("dataMap",  HashMap.class),
+         new ObjectStreamField("tableType", TableMetaType.class),
+      };
+
+   /** The data map of this tabular data */
+   private HashMap<List<MetaValue>, CompositeValue> dataMap;
+
+   /** The table meta data type */
+   private TableMetaType tableType;
+
+   /** The index names */
+   private transient String[] indexNames;
+
+   /**
+    * Construct Table Value with an initial capacity of 101 and a load
+    * factor of 0.75
+    *
+    * @param tableType the table type of the data
+    * @exception IllegalArgumentException for a null argument
+    */
+   public TableValueSupport(TableMetaType tableType)
+   {
+      this(tableType, 101, 0.75f);
+   }
+
+   /**
+    * Construct Table value
+    *
+    * @param tableType the table type
+    * @param initialCapacity the initial capacity of the map
+    * @param loadFactor the load factory of the map
+    * @exception IllegalArgumentException for a null argument
+    */
+   public TableValueSupport(TableMetaType tableType, int initialCapacity, float loadFactor)
+   {
+      init(new HashMap<List<MetaValue>, CompositeValue>(initialCapacity, loadFactor), tableType);
+   }
+
+   public TableMetaType getMetaType()
+   {
+      return tableType;
+   }
+
+   public MetaValue[] calculateIndex(CompositeValue value)
+   {
+      validateCompositeValue(value);
+      return value.getAll(indexNames);
+   }
+
+   public void clear()
+   {
+      dataMap.clear();
+   }
+
+   public boolean containsKey(MetaValue[] key)
+   {
+      if (key == null)
+         return false;
+      return dataMap.containsKey(Arrays.asList(key));
+   }
+
+   public boolean containsValue(CompositeValue value)
+   {
+      return dataMap.containsValue(value);
+   }
+
+   public CompositeValue get(MetaValue[] key)
+   {
+      validateKey(key);
+      return dataMap.get(Arrays.asList(key));
+   }
+
+   public boolean isEmpty()
+   {
+      return dataMap.isEmpty();
+   }
+
+   public Set<List<MetaValue>> keySet()
+   {
+      return dataMap.keySet();
+   }
+
+   public void put(CompositeValue value)
+   {
+      List<MetaValue> index = Arrays.asList(calculateIndex(value));
+      if (dataMap.containsKey(index))
+         throw new IllegalArgumentException("The index is already used " + index);
+      dataMap.put(index, value);
+   }
+
+   public void putAll(CompositeValue[] values)
+   {
+      if (values == null)
+         return;
+
+      HashSet<List<MetaValue>> keys = new HashSet<List<MetaValue>>();
+      for (int i = 0; i < values.length; ++i)
+      {
+         List<MetaValue> index = Arrays.asList(calculateIndex(values[i]));
+         if (keys.contains(index))
+            throw new IllegalArgumentException("Duplicate index in values " + index + " for value " + values[i]);
+         keys.add(index);
+         if (dataMap.containsKey(index))
+            throw new IllegalArgumentException("Index already used " + index + " for value " + values[i]);
+      }
+      for (int i = 0; i < values.length; i++)
+         put(values[i]);
+   }
+
+   public CompositeValue remove(MetaValue[] key)
+   {
+      validateKey(key);
+      return dataMap.remove(Arrays.asList(key));
+   }
+
+   public int size()
+   {
+      return dataMap.size();
+   }
+
+   public Collection<CompositeValue> values()
+   {
+      return dataMap.values();
+   }
+
+   @Override
+   public boolean equals(Object obj)
+   {
+      if (this == obj)
+         return true;
+      if (obj == null || (obj instanceof TableValue) == false)
+         return false;
+
+      TableValue other = (TableValue) obj;
+      if (tableType.equals(other.getMetaType()) == false)
+         return false;
+      if (size() != other.size())
+         return false;
+      for (Entry<List<MetaValue>, CompositeValue> entry : dataMap.entrySet())
+      {
+         List<MetaValue> list = entry.getKey();
+         MetaValue[] indexes = list.toArray(new MetaValue[list.size()]);
+         CompositeValue thisValue = entry.getValue();
+         CompositeValue otherValue = other.get(indexes);
+         if (thisValue == null && otherValue == null)
+            return true;
+         if (thisValue == null && otherValue != null)
+            return false;
+         if (thisValue.equals(otherValue) == false)
+            return false;
+      }
+      return true;
+   }
+
+   @Override
+   public int hashCode()
+   {
+      int hash = tableType.hashCode();
+      for (CompositeValue value : dataMap.values())
+         hash += value.hashCode();
+      return hash;
+   }
+
+   @Override
+   public String toString()
+   {
+      StringBuilder buffer = new StringBuilder(getClass().getSimpleName());
+      buffer.append(": tableType=[");
+      buffer.append(getMetaType());
+      buffer.append("] mappings=[");
+      Iterator<Entry<List<MetaValue>, CompositeValue>> entries = dataMap.entrySet().iterator();
+      while(entries.hasNext())
+      {
+         Entry entry = entries.next(); 
+         buffer.append(entry.getKey());
+         buffer.append("=");
+         buffer.append(entry.getValue());
+         if (entries.hasNext())
+            buffer.append(",");
+      }
+      buffer.append("]");
+      return buffer.toString();
+   }
+
+   @Override
+   @SuppressWarnings("unchecked")
+   public TableValueSupport clone()
+   {
+      TableValueSupport result = (TableValueSupport) super.clone();
+      result.dataMap = (HashMap<List<MetaValue>, CompositeValue>) dataMap.clone();
+      return result;
+   }
+
+   /**
+    * Initialise the table value
+    *
+    * @param dataMap the data
+    * @param tableType the table type
+    * @exception IllegalArgumentException for a null
+    */
+   private void init(HashMap<List<MetaValue>, CompositeValue> dataMap, TableMetaType tableType)
+   {
+      if (dataMap == null)
+         throw new IllegalArgumentException("null dataMap");
+      if (tableType == null)
+         throw new IllegalArgumentException("null table type");
+
+      this.dataMap = dataMap;
+      this.tableType = tableType;
+      List<String> indexNameList = tableType.getIndexNames();
+      this.indexNames = indexNameList.toArray(new String[indexNameList.size()]);
+   }
+
+   /**
+    * Validate the composite type against the row type
+    *
+    * @param value the composite value
+    * @throws IllegalArgumentException for a null value or if the value is not valid for the table value's row type
+    */
+   private void validateCompositeValue(CompositeValue value)
+   {
+      if (value == null)
+         throw new IllegalArgumentException("null value");
+      if (value.getMetaType().equals(tableType.getRowType()) == false)
+         throw new IllegalArgumentException("value has composite type " + value.getMetaType() + " expected row type " + tableType.getRowType());
+   }
+
+   /**
+    * Validate the key against the row type
+    *
+    * @param key the key to check
+    * @throws IllegalArgumentException for a null key or if the key is not valid for the table value's row type
+    */
+   private void validateKey(MetaValue[] key)
+   {
+      if (key == null || key.length == 0)
+         throw new IllegalArgumentException("null or empty key");
+
+      if (key.length != indexNames.length)
+         throw new IllegalArgumentException("key has " + key.length + " elements, " + "should be " + indexNames.length);
+      for (int i = 0; i < key.length; i++)
+      {
+         MetaType metaType = tableType.getRowType().getType(indexNames[i]);
+         if (key[i] != null && metaType.isValue(key[i]) == false)
+            throw new IllegalArgumentException("key element " + i + " " + key + " is not a value for " + metaType);
+      }
+   }
+
+   @SuppressWarnings("unchecked")
+   private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException
+   {
+      ObjectInputStream.GetField getField = in.readFields();
+      HashMap<List<MetaValue>, CompositeValue> dataMap = (HashMap<List<MetaValue>, CompositeValue>) getField.get("dataMap", null);
+      TableMetaType tableType = (TableMetaType) getField.get("tableType", null);
+      try
+      {
+         init(dataMap, tableType);
+      }
+      catch (Exception e)
+      {
+         throw new RuntimeException("Unexpected error during deserialization", e);
+      }
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/AbstractMetaTypeTest.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/AbstractMetaTypeTest.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/AbstractMetaTypeTest.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,182 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.metatype;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.TestSuite;
+
+import org.jboss.metatype.api.types.CompositeMetaType;
+import org.jboss.metatype.api.types.ImmutableCompositeMetaType;
+import org.jboss.metatype.api.types.MetaType;
+import org.jboss.metatype.api.types.SimpleMetaType;
+import org.jboss.metatype.api.values.MetaValue;
+import org.jboss.metatype.api.values.SimpleValue;
+import org.jboss.metatype.api.values.SimpleValueSupport;
+import org.jboss.test.BaseTestCase;
+
+/**
+ * AbstractMetaTypeTest.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public abstract class AbstractMetaTypeTest extends BaseTestCase
+{
+   /**
+    * Create a new testsuite for the class
+    * 
+    * TODO move to BaseTestCase
+    * @param clazz the class
+    * @return the suite
+    */
+   public static TestSuite suite(Class<?> clazz)
+   {
+      return new TestSuite(clazz);
+   }
+   
+   public AbstractMetaTypeTest(String name)
+   {
+      super(name);
+   }
+
+   protected SimpleValue<String> initStringValue1()
+   {
+      return SimpleValueSupport.wrap("value1");
+   }
+
+   protected SimpleValue<String> initStringValue2()
+   {
+      return SimpleValueSupport.wrap("value2");
+   }
+
+   protected SimpleValue<String> initStringName1()
+   {
+      return SimpleValueSupport.wrap("name1");
+   }
+
+   protected SimpleValue<String> initStringEmpty()
+   {
+      return SimpleValueSupport.wrap("");
+   }
+
+   protected SimpleValue<String> initStringNull()
+   {
+      return new SimpleValueSupport<String>(SimpleMetaType.STRING, null);
+   }
+
+   protected SimpleValue<String> initStringWrong()
+   {
+      return SimpleValueSupport.wrap("wrong");
+   }
+
+   protected SimpleValue<Integer> initInteger2()
+   {
+      return SimpleValueSupport.wrap(new Integer(2));
+   }
+
+   protected SimpleValue<Integer> initInteger3()
+   {
+      return SimpleValueSupport.wrap(new Integer(3));
+   }
+
+   protected SimpleValue<Integer> initInteger4()
+   {
+      return SimpleValueSupport.wrap(new Integer(4));
+   }
+
+   protected SimpleValue<Integer> initIntegerNull()
+   {
+      return new SimpleValueSupport<Integer>(SimpleMetaType.INTEGER, null);
+   }
+
+   protected Map<String, MetaValue> initMapValues()
+   {
+      Map<String, MetaValue> map = new HashMap<String, MetaValue>();
+      map.put("name1", initStringValue1());
+      map.put("name2", initInteger2());
+      return map;
+   }
+
+   protected Map<String, MetaValue> initMapValues2()
+   {
+      Map<String, MetaValue> map = new HashMap<String, MetaValue>();
+      map.put("name1", initStringValue1());
+      map.put("name2", initInteger3());
+      return map;
+   }
+
+   protected Map<String, MetaValue> initMapValues3()
+   {
+      Map<String, MetaValue> map = new HashMap<String, MetaValue>();
+      map.put("name1", initStringValue2());
+      map.put("name2", initInteger3());
+      return map;
+   }
+
+   protected Map<String, MetaValue> initMapValues4()
+   {
+      Map<String, MetaValue> map = new HashMap<String, MetaValue>();
+      map.put("name1", initStringValue1());
+      map.put("name2", initInteger4());
+      return map;
+   }
+   
+   protected String[] initKeys()
+   {
+      return new String[] { "name1", "name2" };
+   }
+
+   protected MetaValue[] initValues()
+   {
+      return new MetaValue[] { initStringValue1(), initInteger2() };
+   }
+
+   protected MetaValue[] initValues2()
+   {
+      return new MetaValue[] { initStringValue1(), initInteger3() };
+   }
+
+   protected MetaValue[] initValues4()
+   {
+      return new MetaValue[] { initStringValue1(), initInteger4() };
+   }
+
+   protected CompositeMetaType initCompositeMetaType()
+   {
+      String[] itemNames = new String[] { "name1", "name2" };
+      String[] itemDescriptions = new String[] { "desc1", "desc2" };
+      MetaType[] itemTypes = new MetaType[] { SimpleMetaType.STRING, SimpleMetaType.INTEGER };
+      CompositeMetaType compositeMetaType = new ImmutableCompositeMetaType("typeName", "description", itemNames, itemDescriptions, itemTypes);
+      return compositeMetaType;
+   }
+
+   protected CompositeMetaType initCompositeMetaType2()
+   {
+      String[] itemNames = new String[] { "name1", "name2" };
+      String[] itemDescriptions = new String[] { "desc1", "desc2" };
+      MetaType[] itemTypes = new MetaType[] { SimpleMetaType.STRING, SimpleMetaType.INTEGER };
+      CompositeMetaType compositeMetaType = new ImmutableCompositeMetaType("typeName2", "description", itemNames, itemDescriptions, itemTypes);
+      return compositeMetaType;
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/MetaTypeAllTestSuite.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/MetaTypeAllTestSuite.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/MetaTypeAllTestSuite.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,53 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.metatype;
+
+import org.jboss.test.metatype.types.test.TypesTestSuite;
+import org.jboss.test.metatype.values.test.ValuesTestSuite;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+/**
+ * MetaType All Test Suite.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 37459 $
+ */
+public class MetaTypeAllTestSuite extends TestSuite
+{
+   public static void main(String[] args)
+   {
+      TestRunner.run(suite());
+   }
+
+   public static Test suite()
+   {
+      TestSuite suite = new TestSuite("MetaType All Tests");
+
+      suite.addTest(TypesTestSuite.suite());
+      suite.addTest(ValuesTestSuite.suite());
+
+      return suite;
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/MockCompositeValue.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/MockCompositeValue.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/MockCompositeValue.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,75 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.metatype.types.support;
+
+import java.util.Collection;
+
+import org.jboss.metatype.api.types.CompositeMetaType;
+import org.jboss.metatype.api.values.CompositeValue;
+import org.jboss.metatype.api.values.MetaValue;
+
+/**
+ * MockCompositeValue.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class MockCompositeValue extends MockMetaValue implements CompositeValue
+{
+   /** The serialVersionUID */
+   private static final long serialVersionUID = 1L;
+
+   public MockCompositeValue(CompositeMetaType metaType)
+   {
+      super(metaType);
+   }
+   
+   public CompositeMetaType getMetaType()
+   {
+      return (CompositeMetaType) super.getMetaType();
+   }
+
+   public boolean containsKey(String key)
+   {
+      throw new org.jboss.util.NotImplementedException("containsKey");
+   }
+
+   public boolean containsValue(MetaValue value)
+   {
+      throw new org.jboss.util.NotImplementedException("containsValue");
+   }
+
+   public MetaValue get(String key)
+   {
+      throw new org.jboss.util.NotImplementedException("get");
+   }
+
+   public MetaValue[] getAll(String[] keys)
+   {
+      throw new org.jboss.util.NotImplementedException("getAll");
+   }
+
+   public Collection<MetaValue> values()
+   {
+      throw new org.jboss.util.NotImplementedException("values");
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/MockMetaType.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/MockMetaType.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/MockMetaType.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,68 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.metatype.types.support;
+
+import java.io.Serializable;
+
+import org.jboss.metatype.api.types.AbstractMetaType;
+
+/**
+ * MockMetaType.
+ * 
+ * @param <T> the underlying type
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class MockMetaType<T extends Serializable> extends AbstractMetaType<T>
+{
+   private static final long serialVersionUID = -1;
+
+   public MockMetaType(String className, String typeName, String description)
+   {
+      super(className, typeName, description);
+   }
+
+   @Override
+   public boolean equals(Object obj)
+   {
+      throw new org.jboss.util.NotImplementedException("equals");
+   }
+
+   @Override
+   public int hashCode()
+   {
+      throw new org.jboss.util.NotImplementedException("hashCode");
+   }
+
+   @Override
+   public boolean isValue(Object obj)
+   {
+      throw new org.jboss.util.NotImplementedException("isValue");
+   }
+
+   @Override
+   public String toString()
+   {
+      throw new org.jboss.util.NotImplementedException("toString");
+   }
+
+}

Added: projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/MockMetaValue.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/MockMetaValue.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/MockMetaValue.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,63 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.metatype.types.support;
+
+import org.jboss.metatype.api.types.MetaType;
+import org.jboss.metatype.api.values.MetaValue;
+
+/**
+ * MockMetaValue.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class MockMetaValue implements MetaValue
+{
+   /** The serialVersionUID */
+   private static final long serialVersionUID = 1L;
+   
+   private MetaType metaType;
+
+   public MockMetaValue(MetaType metaType)
+   {
+      this.metaType = metaType;
+   }
+   
+   public MetaType getMetaType()
+   {
+      return metaType;
+   }
+
+   public MetaValue clone()
+   {
+      try
+      {
+         return (MockMetaValue) super.clone();
+      }
+      catch (CloneNotSupportedException e)
+      {
+         throw new Error("unexpected", e);
+      }
+   }
+   
+   
+}

Added: projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/MockSimpleValue.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/MockSimpleValue.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/MockSimpleValue.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,55 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.metatype.types.support;
+
+import java.io.Serializable;
+
+import org.jboss.metatype.api.types.SimpleMetaType;
+import org.jboss.metatype.api.values.SimpleValue;
+
+/**
+ * MockSimpleValue.
+ * 
+ * @param <T> the underlying type
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class MockSimpleValue<T extends Serializable> extends MockMetaValue implements SimpleValue<T>
+{
+   /** The serialVersionUID */
+   private static final long serialVersionUID = 1L;
+
+   public MockSimpleValue(SimpleMetaType<T> metaType)
+   {
+      super(metaType);
+   }
+
+   public SimpleMetaType<T> getMetaType()
+   {
+      return (SimpleMetaType<T>) super.getMetaType();
+   }
+
+   public T getValue()
+   {
+      throw new org.jboss.util.NotImplementedException("getValue");
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/MockTableValue.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/MockTableValue.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/support/MockTableValue.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,113 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.metatype.types.support;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
+
+import org.jboss.metatype.api.types.TableMetaType;
+import org.jboss.metatype.api.values.CompositeValue;
+import org.jboss.metatype.api.values.MetaValue;
+import org.jboss.metatype.api.values.TableValue;
+
+/**
+ * MockTableValue.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class MockTableValue extends MockMetaValue implements TableValue
+{
+   /** The serialVersionUID */
+   private static final long serialVersionUID = 1L;
+ 
+   public MockTableValue(TableMetaType metaType)
+   {
+      super(metaType);
+   }
+
+   public TableMetaType getMetaType()
+   {
+      return (TableMetaType) super.getMetaType();
+   }
+
+   public MetaValue[] calculateIndex(CompositeValue value)
+   {
+      throw new org.jboss.util.NotImplementedException("calculateIndex");
+   }
+
+   public void clear()
+   {
+      throw new org.jboss.util.NotImplementedException("clear");
+   }
+
+   public boolean containsKey(MetaValue[] key)
+   {
+      throw new org.jboss.util.NotImplementedException("containsKey");
+   }
+
+   public boolean containsValue(CompositeValue value)
+   {
+      throw new org.jboss.util.NotImplementedException("containsValue");
+   }
+
+   public CompositeValue get(MetaValue[] key)
+   {
+      throw new org.jboss.util.NotImplementedException("get");
+   }
+
+   public boolean isEmpty()
+   {
+      throw new org.jboss.util.NotImplementedException("isEmpty");
+   }
+
+   public Set<List<MetaValue>> keySet()
+   {
+      throw new org.jboss.util.NotImplementedException("keySet");
+   }
+
+   public void put(CompositeValue value)
+   {
+      throw new org.jboss.util.NotImplementedException("put");
+   }
+
+   public void putAll(CompositeValue[] values)
+   {
+      throw new org.jboss.util.NotImplementedException("putAll");
+   }
+
+   public CompositeValue remove(MetaValue[] key)
+   {
+      throw new org.jboss.util.NotImplementedException("remove");
+   }
+
+   public int size()
+   {
+      throw new org.jboss.util.NotImplementedException("size");
+   }
+
+   public Collection<CompositeValue> values()
+   {
+      throw new org.jboss.util.NotImplementedException("values");
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/ArrayMetaTypeUnitTestCase.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/ArrayMetaTypeUnitTestCase.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/ArrayMetaTypeUnitTestCase.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,228 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.metatype.types.test;
+
+import junit.framework.Test;
+
+import org.jboss.metatype.api.types.ArrayMetaType;
+import org.jboss.metatype.api.types.CompositeMetaType;
+import org.jboss.metatype.api.types.ImmutableCompositeMetaType;
+import org.jboss.metatype.api.types.ImmutableTableMetaType;
+import org.jboss.metatype.api.types.MetaType;
+import org.jboss.metatype.api.types.SimpleMetaType;
+import org.jboss.metatype.api.types.TableMetaType;
+import org.jboss.metatype.api.values.TableValue;
+import org.jboss.test.metatype.AbstractMetaTypeTest;
+import org.jboss.test.metatype.types.support.MockCompositeValue;
+import org.jboss.test.metatype.types.support.MockSimpleValue;
+import org.jboss.test.metatype.types.support.MockTableValue;
+
+/**
+ * ArrayMetaTypeUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ArrayMetaTypeUnitTestCase extends AbstractMetaTypeTest
+{
+   public static Test suite()
+   {
+      return suite(ArrayMetaTypeUnitTestCase.class);
+   }
+   
+   public ArrayMetaTypeUnitTestCase(String name)
+   {
+      super(name);
+   }
+
+   public void testArrayTypeMetaType() throws Exception
+   {
+      ArrayMetaType arrayType = new ArrayMetaType(3, SimpleMetaType.STRING);
+      assertEquals("[[[Ljava.lang.String;", arrayType.getClassName());
+      assertEquals("3-dimension array of java.lang.String", arrayType.getDescription());
+      assertEquals("[[[Ljava.lang.String;", arrayType.getTypeName());
+      assertTrue("Type should be an array", arrayType.isArray());
+   }
+
+   public void testGetDimension() throws Exception
+   {
+      ArrayMetaType arrayType = new ArrayMetaType(3, SimpleMetaType.STRING);
+      assertEquals("Dimension should be 3", 3, arrayType.getDimension());
+   }
+
+   public void testElementOpenType() throws Exception
+   {
+      ArrayMetaType arrayType = new ArrayMetaType(3, SimpleMetaType.STRING);
+      assertEquals("Element MetaType should be " + SimpleMetaType.STRING, SimpleMetaType.STRING, arrayType.getElementType());
+   }
+
+   public void testIsValueSimpleValue() throws Exception
+   {
+      SimpleMetaType<String> simpleType = SimpleMetaType.STRING;
+      MockSimpleValue sv = new MockSimpleValue<String>(simpleType);
+      MockSimpleValue[][] compData1 = new MockSimpleValue[][]
+      {
+         { sv, null }, { sv, sv }
+      };
+            
+      ArrayMetaType compArrayType1 = new ArrayMetaType(2, SimpleMetaType.STRING);
+      assertTrue("compData1 should be a value of array type", compArrayType1.isValue(compData1));
+
+      ArrayMetaType compArrayType2 = new ArrayMetaType(1, SimpleMetaType.STRING);
+      assertFalse("compData1 should not be a value of array type, wrong dimension", compArrayType2.isValue(compData1));
+
+      SimpleMetaType<Integer> simpleType2 = SimpleMetaType.INTEGER;
+      ArrayMetaType compArrayType3 = new ArrayMetaType(2, simpleType2);
+      assertFalse("compData1 should not be a value of array type, wrong element type", compArrayType3.isValue(compData1));
+   }
+
+   public void testIsValueComposite() throws Exception
+   {
+      String[] itemNames = new String[] { "name1", "name2" };
+      String[] itemDescriptions = new String[] { "desc1", "desc2" };
+      MetaType[] itemTypes = new MetaType[] { SimpleMetaType.STRING, SimpleMetaType.INTEGER };
+      CompositeMetaType compositeType = new ImmutableCompositeMetaType("typeName", "description", itemNames, itemDescriptions, itemTypes);
+      MockCompositeValue cv = new MockCompositeValue(compositeType);
+      MockCompositeValue[][] compData1 = new MockCompositeValue[][]
+      {
+         { cv, null }, { cv, cv }
+      };
+
+      ArrayMetaType compArrayType1 = new ArrayMetaType(2, compositeType);
+      assertTrue("compData1 should be a value of array type", compArrayType1.isValue(compData1));
+
+      ArrayMetaType compArrayType2 = new ArrayMetaType(1, compositeType);
+      assertFalse("compData1 should not be a value of array type, wrong dimension", compArrayType2.isValue(compData1));
+
+      CompositeMetaType compositeType2 = new ImmutableCompositeMetaType("typeName2", "description", itemNames, itemDescriptions, itemTypes);
+      ArrayMetaType compArrayType3 = new ArrayMetaType(2, compositeType2);
+      assertFalse("compData1 should not be a value of array type, wrong element type", compArrayType3.isValue(compData1));
+   }
+
+   public void testIsValueTable() throws Exception
+   {
+      String[] itemNames = new String[] { "name1", "name2" };
+      String[] itemDescriptions = new String[] { "desc1", "desc2" };
+      MetaType[] itemTypes = new MetaType[] { SimpleMetaType.STRING, SimpleMetaType.INTEGER };
+      CompositeMetaType compositeType = new ImmutableCompositeMetaType("typeName", "description", itemNames, itemDescriptions, itemTypes);
+      TableMetaType tableType = new ImmutableTableMetaType("typeName", "description", compositeType, new String[] { "name1" });
+      TableValue tv = new MockTableValue(tableType);
+      TableValue[][] tabData1 = new TableValue[][]
+      {
+         { tv, null }, { tv, tv }
+      };
+
+      ArrayMetaType tabArrayType1 = new ArrayMetaType(2, tableType);
+      assertTrue("tabData1 should be a value of array type", tabArrayType1.isValue(tabData1));
+
+      ArrayMetaType tabArrayType2 = new ArrayMetaType(1, tableType);
+      assertFalse("tabData1 should not be a value of array type, wrong number of dimensions", tabArrayType2.isValue(tabData1));
+
+      TableMetaType tableType2 = new ImmutableTableMetaType("typeName2", "description", compositeType, new String[] { "name1" });
+      ArrayMetaType tabArrayType3 = new ArrayMetaType(2, tableType2);
+      assertFalse("tabData1 should not be a value of array type, wrong element type", tabArrayType3.isValue(tabData1));
+   }
+
+   public void testEquals() throws Exception
+   {
+      ArrayMetaType arrayType = new ArrayMetaType(3, SimpleMetaType.STRING);
+
+      assertNotSame("null is not an array type", null, arrayType);
+      assertNotSame("object is not an array type", new Object(), arrayType);
+
+      assertEquals("should be equal to itself", arrayType, arrayType);
+
+      ArrayMetaType arrayType2 = new ArrayMetaType(3, SimpleMetaType.STRING);
+      assertEquals("should be equal, even though different instances", arrayType, arrayType2);
+      assertEquals("should be equal, even though different instances", arrayType2, arrayType);
+
+      arrayType2 = new ArrayMetaType(2, SimpleMetaType.STRING);
+      assertNotSame("should not be equal, wrong number of dimensions", arrayType, arrayType2);
+      assertNotSame("should not be equal, wrong number of dimensions", arrayType2, arrayType);
+
+      arrayType2 = new ArrayMetaType(3, SimpleMetaType.INTEGER);
+      assertNotSame("should not be equal, wrong element type", arrayType, arrayType2);
+      assertNotSame("should not be equal, wrong element type", arrayType2, arrayType);
+   }
+
+   public void testHashCode() throws Exception
+   {
+      ArrayMetaType arrayType = new ArrayMetaType(3, SimpleMetaType.STRING);
+
+      int myHashCode = 3 + SimpleMetaType.STRING.hashCode();
+      assertTrue("Wrong hash code generated", myHashCode == arrayType.hashCode());
+   }
+
+   public void testToString() throws Exception
+   {
+      ArrayMetaType arrayType = new ArrayMetaType(3, SimpleMetaType.STRING);
+
+      String toString = arrayType.toString();
+
+      assertTrue("toString() should contain the array type class name", toString.indexOf(ArrayMetaType.class.getSimpleName()) != -1);
+      assertTrue("toString() should contain the dimension", toString.indexOf("3") != -1);
+      assertTrue("toString() should contain the element type", toString.indexOf(SimpleMetaType.STRING.toString()) != -1);
+   }
+
+   public void testSerialization() throws Exception
+   {
+      ArrayMetaType arrayType = new ArrayMetaType(3, SimpleMetaType.STRING);
+
+      byte[] bytes = serialize(arrayType);
+      Object result = deserialize(bytes);
+
+      assertEquals(arrayType, result);
+   }
+
+   public void testErrors() throws Exception
+   {
+      try
+      {
+         new ArrayMetaType(-1, SimpleMetaType.STRING);
+         fail("Excepted IllegalArgumentException for negative dimension");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new ArrayMetaType(1, new ArrayMetaType(2, SimpleMetaType.STRING));
+         fail("Excepted IllegalArgumentException for ArrayMetaType element type");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         new ArrayMetaType(1, null);
+         fail("Excepted IllegalArgumentException for null element type");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/ImmutableCompositeMetaTypeUnitTestCase.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/ImmutableCompositeMetaTypeUnitTestCase.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/ImmutableCompositeMetaTypeUnitTestCase.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,365 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.metatype.types.test;
+
+import java.util.Set;
+
+import junit.framework.Test;
+
+import org.jboss.metatype.api.types.CompositeMetaType;
+import org.jboss.metatype.api.types.ImmutableCompositeMetaType;
+import org.jboss.metatype.api.types.MetaType;
+import org.jboss.metatype.api.types.SimpleMetaType;
+import org.jboss.metatype.api.values.CompositeValue;
+import org.jboss.test.metatype.AbstractMetaTypeTest;
+
+/**
+ * CompositeMetaTypeUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ImmutableCompositeMetaTypeUnitTestCase extends AbstractMetaTypeTest
+{
+   public static Test suite()
+   {
+      return suite(ImmutableCompositeMetaTypeUnitTestCase.class);
+   }
+   
+   public ImmutableCompositeMetaTypeUnitTestCase(String name)
+   {
+      super(name);
+   }
+
+   public void testCompositeMetaTypeMetaType() throws Exception
+   {
+      CompositeMetaType compositeType = initCompositeMetaType();
+      assertEquals(CompositeValue.class.getName(), compositeType.getClassName());
+      assertEquals("description", compositeType.getDescription());
+      assertEquals("typeName", compositeType.getTypeName());
+      assertTrue("Composite meta type should not be an array", compositeType.isArray() == false);
+   }
+
+   public void testContainsKey() throws Exception
+   {
+      CompositeMetaType compositeType = initCompositeMetaType();
+      assertTrue("Composite type should contain key name1", compositeType.containsKey("name1") == true);
+      assertTrue("Composite type should contain key name2", compositeType.containsKey("name2") == true);
+      assertTrue("Composite type should not contain key nameX", compositeType.containsKey("nameX") == false);
+      assertTrue("Composite type should not contain key null", compositeType.containsKey(null) == false);
+      assertTrue("Composite type should not contain key <empty>", compositeType.containsKey("") == false);
+   }
+
+   public void testGetDescriptionForItemName() throws Exception
+   {
+      CompositeMetaType compositeType = initCompositeMetaType();
+      assertEquals("desc1", compositeType.getDescription("name1"));
+      assertEquals("desc2", compositeType.getDescription("name2"));
+   }
+
+   public void testGetTypeForItemName() throws Exception
+   {
+      CompositeMetaType compositeType = initCompositeMetaType();
+      assertEquals(SimpleMetaType.STRING, compositeType.getType("name1"));
+      assertEquals(SimpleMetaType.INTEGER, compositeType.getType("name2"));
+   }
+
+   public void testKeySet() throws Exception
+   {
+      CompositeMetaType compositeType = initCompositeMetaType();
+      Set<String> keys = compositeType.keySet();
+      assertTrue("Should be 2 items", keys.size() == 2);
+      assertTrue("Should contain name1", keys.contains("name1"));
+      assertTrue("Should contain name2", keys.contains("name2"));
+   }
+
+   public void testIsValue() throws Exception
+   {
+      // TODO testIsValue
+   }
+
+   public void testEquals() throws Exception
+   {
+      CompositeMetaType compositeType = initCompositeMetaType();;
+
+      assertTrue("null is not equal composite type", compositeType.equals(null) == false);
+      assertTrue("object is not equal composite type", compositeType.equals(new Object()) == false);
+
+      CompositeMetaType compositeType2 = initCompositeMetaType();
+      assertTrue("compositeType2 should be equal composite type, even though not the same object instance",
+         compositeType.equals(compositeType2));
+      assertTrue("compositeType2 should be equal composite type, even though not the same object instance",
+         compositeType2.equals(compositeType));
+
+      compositeType2 = initCompositeMetaTypeDifferentItemTypes();
+      assertTrue("compositeType2 should not be equal composite type, it has different types",
+         compositeType.equals(compositeType2) == false);
+      assertTrue("compositeType2 should not be equal composite type, it has different types",
+         compositeType2.equals(compositeType) == false);
+
+      compositeType2 = initCompositeMetaTypeDifferentTypeName();
+      assertTrue("compositeType2 should not be equal composite type, it has a different type name",
+         compositeType.equals(compositeType2) == false);
+      assertTrue("compositeType2 should not be equal composite type, it has a different type name",
+         compositeType2.equals(compositeType) == false);
+
+      compositeType2 = initCompositeMetaTypeDifferentItemNames();
+      assertTrue("compositeType2 should not be equal composite type, it has different item names",
+         compositeType.equals(compositeType2) == false);
+      assertTrue("compositeType2 should not be equal composite type, it has different item names",
+         compositeType2.equals(compositeType) == false);
+   }
+
+   public void testHashCode() throws Exception
+   {
+      CompositeMetaType compositeType = initCompositeMetaType();
+
+      int myHashCode = "typeName".hashCode();
+      myHashCode += SimpleMetaType.STRING.hashCode();
+      myHashCode += SimpleMetaType.INTEGER.hashCode();
+      myHashCode += "name1".hashCode();
+      myHashCode += "name2".hashCode();
+      assertTrue("Wrong hash code generated", myHashCode == compositeType.hashCode());
+   }
+
+   public void testToString() throws Exception
+   {
+      CompositeMetaType compositeType = initCompositeMetaType();
+
+      String toString = compositeType.toString();
+
+      assertTrue("toString() should contain the composite type class name", toString.indexOf(compositeType.getClass().getSimpleName()) != -1);
+      assertTrue("toString() should contain the item name name1", toString.indexOf("name1") != -1);
+      assertTrue("toString() should contain the item name name2", toString.indexOf("name2") != -1);
+      assertTrue("toString() should contain " + SimpleMetaType.STRING, toString.indexOf(SimpleMetaType.STRING.toString()) != -1);
+      assertTrue("toString() should contain " + SimpleMetaType.INTEGER, toString.indexOf(SimpleMetaType.INTEGER.toString()) != -1);
+   }
+
+   public void testSerialization() throws Exception
+   {
+      CompositeMetaType compositeType = initCompositeMetaType();
+      byte[] bytes = serialize(compositeType);
+      Object result = deserialize(bytes);
+      assertEquals(compositeType, result);
+   }
+
+   public void testErrors() throws Exception
+   {
+      String[] itemNames = new String[] { "name1", "name2" };
+      String[] itemDescriptions = new String[] { "desc1", "desc2" };
+      MetaType[] itemTypes = new MetaType[] { SimpleMetaType.STRING, SimpleMetaType.INTEGER };
+
+      try
+      {
+         new ImmutableCompositeMetaType(null, "description", itemNames, itemDescriptions, itemTypes);
+         fail("Excepted IllegalArgumentException for null typeName");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         new ImmutableCompositeMetaType("", "description", itemNames, itemDescriptions, itemTypes);
+         fail("Excepted IllegalArgumentException for empty typeName");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         new ImmutableCompositeMetaType("typeName", null, itemNames, itemDescriptions, itemTypes);
+         fail("Excepted IllegalArgumentException for null description");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         new ImmutableCompositeMetaType("typeName", "", itemNames, itemDescriptions, itemTypes);
+         fail("Excepted IllegalArgumentException for empty description");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         new ImmutableCompositeMetaType("typeName", "description", null, itemDescriptions, itemTypes);
+         fail("Excepted IllegalArgumentException for null item names");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         new ImmutableCompositeMetaType("typeName", "description", itemNames, null, itemTypes);
+         fail("Excepted IllegalArgumentException for null item descriptions");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         new ImmutableCompositeMetaType("typeName", "description", itemNames, itemDescriptions, null);
+         fail("Excepted IllegalArgumentException for null item types");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      String[] nullItemNames = new String[] { "name1", null };
+      try
+      {
+         new ImmutableCompositeMetaType("typeName", "description", nullItemNames, itemDescriptions, itemTypes);
+         fail("Excepted IllegalArgumentException for null element of item names");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      String[] nullItemDescriptions = new String[] { "desc1", null };
+      try
+      {
+         new ImmutableCompositeMetaType("typeName", "description", itemNames, nullItemDescriptions, itemTypes);
+         fail("Excepted IllegalArgumentException for null element of item descriptions");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      MetaType[] nullItemTypes = new MetaType[] { SimpleMetaType.STRING, null };
+      try
+      {
+         new ImmutableCompositeMetaType("typeName", "description", itemNames, itemDescriptions, nullItemTypes);
+         fail("Excepted IllegalArgumentException for null element of item types");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      String[] wrongItemNames = new String[] { "name1" };
+      try
+      {
+         new ImmutableCompositeMetaType("typeName", "description", wrongItemNames, itemDescriptions, itemTypes);
+         fail("Excepted IllegalArgumentException for wrong number of elements for item names");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      String[] wrongItemDescriptions = new String[] { "desc1"};
+      try
+      {
+         new ImmutableCompositeMetaType("typeName", "description", itemNames, wrongItemDescriptions, itemTypes);
+         fail("Excepted IllegalArgumentException for wrong number of elements for item descriptions");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      MetaType[] wrongItemTypes = new MetaType[] { SimpleMetaType.STRING };
+      try
+      {
+         new ImmutableCompositeMetaType("typeName", "description", itemNames, itemDescriptions, wrongItemTypes);
+         fail("Excepted IllegalArgumentException for wrong number of elements for item types");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      String[] duplicateItemNames = new String[] { "desc1", "desc1" };
+      try
+      {
+         new ImmutableCompositeMetaType("typeName", "description", duplicateItemNames, itemDescriptions, itemTypes);
+         fail("Excepted OpenDataException for duplicate item names");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      duplicateItemNames = new String[] { "desc1", " desc1 " };
+      try
+      {
+         new ImmutableCompositeMetaType("typeName", "description", duplicateItemNames, itemDescriptions, itemTypes);
+         fail("Excepted OpenDataException for duplicate item names");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+   }
+
+   protected CompositeMetaType initCompositeMetaType()
+   {
+      String[] itemNames = new String[] { "name1", "name2" };
+      String[] itemDescriptions = new String[] { "desc1", "desc2" };
+      MetaType[] itemTypes = new MetaType[] { SimpleMetaType.STRING, SimpleMetaType.INTEGER };
+      CompositeMetaType compositeType = new ImmutableCompositeMetaType("typeName", "description", itemNames, itemDescriptions, itemTypes);
+      return compositeType;
+   }
+
+   protected CompositeMetaType initCompositeMetaTypeDifferentItemTypes()
+   {
+      String[] itemNames = new String[] { "name1", "name2" };
+      String[] itemDescriptions = new String[] { "desc1", "desc2" };
+      MetaType[] itemTypes = new MetaType[] { SimpleMetaType.STRING, SimpleMetaType.LONG };
+      CompositeMetaType compositeType = new ImmutableCompositeMetaType("typeName", "description", itemNames, itemDescriptions, itemTypes);
+      return compositeType;
+   }
+
+   protected CompositeMetaType initCompositeMetaTypeDifferentTypeName()
+   {
+      String[] itemNames = new String[] { "name1", "name2" };
+      String[] itemDescriptions = new String[] { "desc1", "desc2" };
+      MetaType[] itemTypes = new MetaType[] { SimpleMetaType.STRING, SimpleMetaType.INTEGER };
+      CompositeMetaType compositeType = new ImmutableCompositeMetaType("typeName2", "description", itemNames, itemDescriptions, itemTypes);
+      return compositeType;
+   }
+
+   protected CompositeMetaType initCompositeMetaTypeDifferentItemNames()
+   {
+      String[] itemNames = new String[] { "nameX", "name2" };
+      String[] itemDescriptions = new String[] { "desc1", "desc2" };
+      MetaType[] itemTypes = new MetaType[] { SimpleMetaType.STRING, SimpleMetaType.INTEGER };
+      CompositeMetaType compositeType = new ImmutableCompositeMetaType("typeName", "description", itemNames, itemDescriptions, itemTypes);
+      return compositeType;
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/ImmutableTableMetaTypeUnitTestCase.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/ImmutableTableMetaTypeUnitTestCase.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/ImmutableTableMetaTypeUnitTestCase.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,305 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.metatype.types.test;
+
+import java.util.Iterator;
+import java.util.List;
+
+import junit.framework.Test;
+
+import org.jboss.metatype.api.types.CompositeMetaType;
+import org.jboss.metatype.api.types.ImmutableCompositeMetaType;
+import org.jboss.metatype.api.types.ImmutableTableMetaType;
+import org.jboss.metatype.api.types.MetaType;
+import org.jboss.metatype.api.types.SimpleMetaType;
+import org.jboss.metatype.api.types.TableMetaType;
+import org.jboss.metatype.api.values.TableValue;
+import org.jboss.test.metatype.AbstractMetaTypeTest;
+
+/**
+ * ImmutableMetaTypeUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class ImmutableTableMetaTypeUnitTestCase extends AbstractMetaTypeTest
+{
+   public static Test suite()
+   {
+      return suite(ImmutableTableMetaTypeUnitTestCase.class);
+   }
+   
+   public ImmutableTableMetaTypeUnitTestCase(String name)
+   {
+      super(name);
+   }
+
+   public void testTableMetaType() throws Exception
+   {
+      TableMetaType tableType = initTableMetaType();
+
+      assertEquals(TableValue.class.getName(), tableType.getClassName());
+      assertEquals("description", tableType.getDescription());
+      assertEquals("typeName", tableType.getTypeName());
+      assertTrue("Tabular type should not be an array", tableType.isArray() == false);
+   }
+
+   public void testGetRowType() throws Exception
+   {
+      CompositeMetaType rowType = initRowType();
+      TableMetaType tableType = initTableMetaType();
+
+      assertEquals(rowType, tableType.getRowType());
+   }
+
+   public void testIndexNames() throws Exception
+   {
+      TableMetaType tableType = initTableMetaType();
+
+      List<String> indexList = tableType.getIndexNames();
+      assertTrue("wrong number of index names", indexList.size() == 2);
+      assertTrue("index list should contain name1", indexList.contains("name1"));
+      assertTrue("index list should contain name2", indexList.contains("name2"));
+      Iterator<String> i = indexList.iterator();
+      assertTrue("first index is name1", i.next().equals("name1"));
+      assertTrue("second index is name2", i.next().equals("name2"));
+   }
+
+   public void testIsValue() throws Exception
+   {
+      // TODO testIsValue
+   }
+
+   public void testEquals() throws Exception
+   {
+      TableMetaType tableType = initTableMetaType();
+
+      assertNotSame("null is not equal to table type", tableType, null);
+      assertNotSame("object is not a equal to table type", tableType, new Object());
+
+      TableMetaType tableType2 = initTableMetaType();
+      assertEquals("Should be equal, even though the table type is a different instance", tableType, tableType2);
+      assertEquals("Should be equal, even though the table type is a different instance", tableType2, tableType);
+
+      tableType2 = initTableMetaTypeDifferentTypeName();
+      assertNotSame("should not be equal, they have different type names", tableType, tableType2);
+      assertNotSame("should not be equal, they have different type names", tableType2, tableType);
+
+      tableType2 = initTableMetaTypeDifferentRowTypes();
+      assertNotSame("should not be equal, they have different row types", tableType, tableType2);
+      assertNotSame("should not be equal, they have different row types", tableType2, tableType);
+
+      tableType2 = initTableMetaTypeDifferentIndexNames();
+      assertNotSame("should not be equal, they have different index names", tableType, tableType2);
+      assertNotSame("should not be equal, they have different index names", tableType2, tableType);
+   }
+
+   public void testHashCode() throws Exception
+   {
+      CompositeMetaType rowType = initRowType();
+      TableMetaType tableType = initTableMetaType();
+
+      int myHashCode = "typeName".hashCode() + rowType.hashCode() + "name1".hashCode() + "name2".hashCode();
+      assertTrue("Wrong hash code generated", myHashCode == tableType.hashCode());
+   }
+
+   public void testToString() throws Exception
+   {
+      CompositeMetaType rowType = initRowType();
+      TableMetaType tableType = initTableMetaType();
+
+      String toString = tableType.toString();
+
+      assertTrue("toString() should contain the tabular type class name", toString.indexOf(TableMetaType.class.getSimpleName()) != -1);
+      assertTrue("toString() should contain the type name", toString.indexOf("typeName") != -1);
+      assertTrue("toString() should contain the row type " + rowType, toString.indexOf(rowType.toString()) != -1);
+      assertTrue("toString() should contain the index name1", toString.indexOf("name1") != -1);
+      assertTrue("toString() should contain the index name2", toString.indexOf("name2") != -1);
+   }
+
+   public void testSerialization() throws Exception
+   {
+      TableMetaType tableType = initTableMetaType();
+      byte[] bytes = serialize(tableType);
+      Object result = deserialize(bytes);
+      assertEquals(tableType, result);
+   }
+
+   public void testErrors() throws Exception
+   {
+      CompositeMetaType rowType = initRowType();
+      String[] indexNames = new String[] { "name1", "name2" };
+
+      try
+      {
+         new ImmutableTableMetaType(null, "description", rowType, indexNames);
+         fail("Expected IllegalArgumentException for null type name");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new ImmutableTableMetaType("", "description", rowType, indexNames);
+         fail("Expected IllegalArgumentException for empty type name");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new ImmutableTableMetaType("typeName", null, rowType, indexNames);
+         fail("Expected IllegalArgumentException for null description");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new ImmutableTableMetaType("typeName", "", rowType, indexNames);
+         fail("Expected IllegalArgumentException for empty description");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new ImmutableTableMetaType("typeName", "description", null, indexNames);
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new ImmutableTableMetaType("typeName", "description", rowType, null);
+         fail("Expected IllegalArgumentException for null row type");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new ImmutableTableMetaType("typeName", "description", rowType, new String[0]);
+         fail("Expected IllegalArgumentException for empty index names");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new ImmutableTableMetaType("typeName", "description", rowType, new String[] { "name1", null });
+         fail("Expected IllegalArgumentException for null index name element");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new ImmutableTableMetaType("typeName", "description", rowType, new String[] { "name1", "" });
+         fail("Expected IllegalArgumentException for empty index name element");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new ImmutableTableMetaType("typeName", "description", rowType, new String[] { "name1", "nameX" });
+         fail("Expected IllegalArgumentException for invalid index name");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+   }
+
+   protected CompositeMetaType initRowType() throws Exception
+   {
+      String[] itemNames = new String[] { "name1", "name2" };
+      String[] itemDescriptions = new String[] { "desc1", "desc2" };
+      MetaType[] itemTypes = new MetaType[] { SimpleMetaType.STRING, SimpleMetaType.INTEGER };
+      CompositeMetaType rowType = new ImmutableCompositeMetaType("rowTypeName", "rowDescription", itemNames, itemDescriptions, itemTypes);
+      return rowType;
+   }
+
+   protected TableMetaType initTableMetaType() throws Exception
+   {
+      CompositeMetaType rowType = initRowType();
+
+      String[] indexNames = new String[] { "name1", "name2" };
+      TableMetaType tableType = new ImmutableTableMetaType("typeName", "description", rowType, indexNames);
+      return tableType;
+   }
+
+   protected TableMetaType initTableMetaTypeDifferentTypeName() throws Exception
+   {
+      CompositeMetaType rowType = initRowType();
+
+      String[] indexNames = new String[] { "name1", "name2" };
+      TableMetaType tableType = new ImmutableTableMetaType("typeName2", "description", rowType, indexNames);
+      return tableType;
+   }
+
+   protected CompositeMetaType initRowType2() throws Exception
+   {
+      String[] itemNames = new String[] { "name1", "name2" };
+      String[] itemDescriptions = new String[] { "desc1", "desc2" };
+      MetaType[] itemTypes = new MetaType[] { SimpleMetaType.STRING, SimpleMetaType.INTEGER };
+      CompositeMetaType rowType = new ImmutableCompositeMetaType("rowTypeName2", "rowDescription", itemNames, itemDescriptions, itemTypes);
+      return rowType;
+   }
+
+   protected TableMetaType initTableMetaTypeDifferentRowTypes() throws Exception
+   {
+      CompositeMetaType rowType = initRowType2();
+
+      String[] indexNames = new String[] { "name1", "name2" };
+      TableMetaType tableType = new ImmutableTableMetaType("typeName", "description", rowType, indexNames);
+      return tableType;
+   }
+
+   protected TableMetaType initTableMetaTypeDifferentIndexNames() throws Exception
+   {
+      CompositeMetaType rowType = initRowType();
+
+      String[] indexNames = new String[] { "name2", "name1" };
+      TableMetaType tableType = new ImmutableTableMetaType("typeName", "description", rowType, indexNames);
+      return tableType;
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/MetaTypeUnitTestCase.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/MetaTypeUnitTestCase.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/MetaTypeUnitTestCase.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,233 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.metatype.types.test;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+
+import junit.framework.Test;
+
+import org.jboss.metatype.api.types.MetaType;
+import org.jboss.metatype.api.values.CompositeValue;
+import org.jboss.metatype.api.values.SimpleValue;
+import org.jboss.metatype.api.values.TableValue;
+import org.jboss.test.metatype.AbstractMetaTypeTest;
+import org.jboss.test.metatype.types.support.MockMetaType;
+
+/**
+ * MetaTypeUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class MetaTypeUnitTestCase extends AbstractMetaTypeTest
+{
+   public static Test suite()
+   {
+      return suite(MetaTypeUnitTestCase.class);
+   }
+   
+   public MetaTypeUnitTestCase(String name)
+   {
+      super(name);
+   }
+   
+   public void testAllowedClasses() throws Exception
+   {
+      String[] allowedClassNames = MetaType.ALLOWED_CLASSNAMES;
+      assertEquals(16, allowedClassNames.length);
+      List<String> names = Arrays.asList(allowedClassNames);
+      checkMetaType(names, Void.class);
+      checkMetaType(names, Boolean.class);
+      checkMetaType(names, Character.class);
+      checkMetaType(names, Byte.class);
+      checkMetaType(names, Short.class);
+      checkMetaType(names, Integer.class);
+      checkMetaType(names, Long.class);
+      checkMetaType(names, Float.class);
+      checkMetaType(names, Double.class);
+      checkMetaType(names, String.class);
+      checkMetaType(names, Date.class);
+      checkMetaType(names, BigDecimal.class);
+      checkMetaType(names, BigInteger.class);
+      checkMetaType(names, SimpleValue.class);
+      checkMetaType(names, CompositeValue.class);
+      checkMetaType(names, TableValue.class);
+   }
+
+   public void testConstructorSimple() throws Exception
+   {
+      MetaType test = new MockMetaType("java.lang.Void", "type", "description");
+      assertEquals("java.lang.Void", test.getClassName());
+      assertEquals("type", test.getTypeName());
+      assertEquals("description", test.getDescription());
+      assertEquals(false, test.isArray());
+   }
+
+   public void testConstructorArray() throws Exception
+   {
+      MetaType test = new MockMetaType("[[Ljava.lang.Void;", "type", "description");
+      assertEquals("[[Ljava.lang.Void;", test.getClassName());
+      assertEquals("type", test.getTypeName());
+      assertEquals("description", test.getDescription());
+      assertEquals(true, test.isArray());
+   }
+
+   public void testSerializationSimple() throws Exception
+   {
+      testSerialization("java.lang.Void", "type", "description");
+   }
+ 
+   public void testSerializationArray() throws Exception
+   {
+      testSerialization("[[Ljava.lang.Void;", "type", "description");
+   }
+
+   public void testErrors() throws Exception
+   {
+      try
+      {
+         new MockMetaType(null, "dummy", "dummy");
+         fail("className cannot be null");
+      }
+      catch (Throwable e)
+      {
+         checkThrowable(IllegalArgumentException.class, e);
+      }
+
+      try
+      {
+         new MockMetaType("", "dummy", "dummy");
+         fail("className cannot be empty");
+      }
+      catch (Throwable e)
+      {
+         checkThrowable(IllegalArgumentException.class, e);
+      }
+
+      try
+      {
+         new MockMetaType("java.lang.Void", null, "dummy");
+         fail("typeName cannot be null");
+      }
+      catch (Throwable e)
+      {
+         checkThrowable(IllegalArgumentException.class, e);
+      }
+
+      try
+      {
+         new MockMetaType("java.lang.Void", null, "dummy");
+         fail("typeName cannot be empty");
+      }
+      catch (Throwable e)
+      {
+         checkThrowable(IllegalArgumentException.class, e);
+      }
+
+      try
+      {
+         new MockMetaType("java.lang.Void", "dummy", null);
+         fail("description cannot be null");
+      }
+      catch (Throwable e)
+      {
+         checkThrowable(IllegalArgumentException.class, e);
+      }
+
+      try
+      {
+         new MockMetaType("java.lang.Void", "dummy", "");
+         fail("description cannot be empty");
+      }
+      catch (Throwable e)
+      {
+         checkThrowable(IllegalArgumentException.class, e);
+      }
+
+      try
+      {
+         new MockMetaType("java.lang.Class", "dummy", "dummy");
+         fail("className must be a MetaType");
+      }
+      catch (Throwable e)
+      {
+         checkThrowable(IllegalArgumentException.class, e);
+      }
+
+      try
+      {
+         new MockMetaType("[Ljava.lang.Void", "dummy", "dummy");
+         fail("[Ljava.lang.Void is not a valid array");
+      }
+      catch (Throwable e)
+      {
+         checkThrowable(IllegalArgumentException.class, e);
+      }
+
+      try
+      {
+         new MockMetaType("[L", "dummy", "dummy");
+         fail("[L is not a valid array");
+      }
+      catch (Throwable e)
+      {
+         checkThrowable(IllegalArgumentException.class, e);
+      }
+
+      try
+      {
+         new MockMetaType("[Xjava.lang.Void;", "dummy", "dummy");
+         fail("FAILS IN RI: [Xjava.lang.Void; is not a valid array");
+      }
+      catch (Throwable e)
+      {
+         checkThrowable(IllegalArgumentException.class, e);
+      }
+   }
+   
+   private void testSerialization(String className, String type, String description) throws Exception
+   {
+      MetaType original = new MockMetaType(className, type, description);
+      byte[] bytes = serialize(original);
+      MetaType result = (MetaType) deserialize(bytes);
+      assertEquals(original.getClassName(), result.getClassName());
+      assertEquals(original.getTypeName(), result.getTypeName());
+      assertEquals(original.getDescription(), result.getDescription());
+      assertEquals(original.isArray(), result.isArray());
+   }
+
+   private void checkMetaType(List names, Class clazz) throws Exception
+   {
+      String name = clazz.getName();
+      assertTrue(name + " is a MetaType", names.contains(name));
+
+      new MockMetaType(name, "dummy", "dummy");
+
+      new MockMetaType("[L"+name+";", "dummy", "dummy");
+
+      new MockMetaType("[[[[[L"+name+";", "dummy", "dummy");
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/SimpleMetaTypeUnitTestCase.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/SimpleMetaTypeUnitTestCase.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/SimpleMetaTypeUnitTestCase.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,224 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.metatype.types.test;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.Date;
+
+import junit.framework.Test;
+
+import org.jboss.metatype.api.types.SimpleMetaType;
+import org.jboss.metatype.api.values.SimpleValue;
+import org.jboss.metatype.api.values.SimpleValueSupport;
+import org.jboss.test.metatype.AbstractMetaTypeTest;
+
+/**
+ * SimpleMetaTypeUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class SimpleMetaTypeUnitTestCase extends AbstractMetaTypeTest
+{
+   public static Test suite()
+   {
+      return suite(SimpleMetaTypeUnitTestCase.class);
+   }
+   
+   public SimpleMetaTypeUnitTestCase(String name)
+   {
+      super(name);
+   }
+
+   SimpleMetaType[] types = new SimpleMetaType[]
+   {
+      SimpleMetaType.BIGDECIMAL,
+      SimpleMetaType.BIGINTEGER,
+      SimpleMetaType.BOOLEAN,
+      SimpleMetaType.BYTE,
+      SimpleMetaType.CHARACTER,
+      SimpleMetaType.DATE,
+      SimpleMetaType.DOUBLE,
+      SimpleMetaType.FLOAT,
+      SimpleMetaType.INTEGER,
+      SimpleMetaType.LONG,
+      SimpleMetaType.SHORT,
+      SimpleMetaType.STRING,
+      SimpleMetaType.VOID
+   };
+
+   Class[] classes = new Class[]
+   {
+      BigDecimal.class,
+      BigInteger.class,
+      Boolean.class,
+      Byte.class,
+      Character.class,
+      Date.class,
+      Double.class,
+      Float.class,
+      Integer.class,
+      Long.class,
+      Short.class,
+      String.class,
+      Void.class
+   };
+
+   @SuppressWarnings("unchecked")
+   SimpleValue[] values = new SimpleValue[]
+   {
+      new SimpleValueSupport<BigDecimal>(SimpleMetaType.BIGDECIMAL, new BigDecimal(1)),
+      new SimpleValueSupport<BigInteger>(SimpleMetaType.BIGINTEGER, BigInteger.ONE),
+      new SimpleValueSupport<Boolean>(SimpleMetaType.BOOLEAN, new Boolean(false)),
+      new SimpleValueSupport<Byte>(SimpleMetaType.BYTE, new Byte(Byte.MAX_VALUE)),
+      new SimpleValueSupport<Character>(SimpleMetaType.CHARACTER, new Character('a')),
+      new SimpleValueSupport<Date>(SimpleMetaType.DATE, new Date(System.currentTimeMillis())),
+      new SimpleValueSupport<Double>(SimpleMetaType.DOUBLE, new Double(1)),
+      new SimpleValueSupport<Float>(SimpleMetaType.FLOAT, new Float(1)),
+      new SimpleValueSupport<Integer>(SimpleMetaType.INTEGER, new Integer(1)),
+      new SimpleValueSupport<Long>(SimpleMetaType.LONG, new Long(1)),
+      new SimpleValueSupport<Short>(SimpleMetaType.SHORT, new Short(Short.MAX_VALUE)),
+      new SimpleValueSupport<String>(SimpleMetaType.STRING, new String("hello")),
+      new SimpleValueSupport(SimpleMetaType.VOID, null)
+   };
+
+   @SuppressWarnings("unchecked")
+   SimpleValue[] nullValues = new SimpleValue[]
+   {
+      new SimpleValueSupport<BigDecimal>(SimpleMetaType.BIGDECIMAL, null),
+      new SimpleValueSupport<BigInteger>(SimpleMetaType.BIGINTEGER, null),
+      new SimpleValueSupport<Boolean>(SimpleMetaType.BOOLEAN, null),
+      new SimpleValueSupport<Byte>(SimpleMetaType.BYTE, null),
+      new SimpleValueSupport<Character>(SimpleMetaType.CHARACTER, null),
+      new SimpleValueSupport<Date>(SimpleMetaType.DATE, null),
+      new SimpleValueSupport<Double>(SimpleMetaType.DOUBLE, null),
+      new SimpleValueSupport<Float>(SimpleMetaType.FLOAT, null),
+      new SimpleValueSupport<Integer>(SimpleMetaType.INTEGER, null),
+      new SimpleValueSupport<Long>(SimpleMetaType.LONG, null),
+      new SimpleValueSupport<Short>(SimpleMetaType.SHORT, null),
+      new SimpleValueSupport<String>(SimpleMetaType.STRING, null),
+      new SimpleValueSupport(SimpleMetaType.VOID, null)
+   };
+
+   public void testSimpleTypes() throws Exception
+   {
+      for (int i = 0; i < types.length; i++)
+      {
+         String className = classes[i].getName();
+         getLog().debug("SimpleMetaType: " + className + " className=" + types[i].getClassName() + " typeName=" + types[i].getTypeName() + " description=" + types[i].getDescription());
+         assertEquals(className, types[i].getClassName());
+         assertEquals(className, types[i].getTypeName());
+         assertEquals(className, types[i].getDescription());
+      }
+   }
+
+   public void testEquals() throws Exception
+   {
+      for (int i = 0; i < types.length; i++)
+      {
+        for (int j = 0; j < types.length; j++)
+        {
+           boolean resultEquals = types[i].equals(types[j]);
+           boolean resultReference = types[i] != types[j];
+           getLog().debug("equals  : " + types[i].getClassName() + " " + types[j] + " result=" + resultEquals);
+           getLog().debug("equality: " + types[i].getClassName() + " " + types[j] + " result=" + resultReference);
+           if (i == j)
+              assertEquals("SimpleMetaTypes should be equal to itself " + classes[i], types[i], types[j]);
+           else
+           {
+              assertNotSame("SimpleMetaTypes should be different under equality " + classes[i], types[i], types[j]);
+              assertTrue("SimpleMetaTypes should be different under reference " + classes[i], types[i] != types[j]);
+           }
+        }
+      }
+   }
+
+   public void testIsValue() throws Exception
+   {
+      for (int i = 0; i < types.length; ++i)
+      {
+         for (int j = 0; j < types.length; ++j)
+         {
+
+            // isValue makes no sense for Void
+            if (values[i].getValue() == null)
+               continue;
+
+            boolean result = types[j].isValue(values[i]);
+            getLog().debug("isValue: " + types[j].getClassName() + " value=" + values[i] + " result=" + result);
+            
+            if (i == j)
+            {
+               assertTrue(classes[i] + " should be a simple value of " + types[j], result);
+               result = types[i].isValue(nullValues[j]);
+               getLog().debug("isValue: " + types[i].getClassName() + " value=null value result=" + result);
+               assertTrue(nullValues[j] + " should be a simple value of " + types[i], result);
+            }
+            else
+            {
+               assertFalse(classes[i] + " should NOT be a simple value of " + types[j], result);
+               result = types[i].isValue(nullValues[j]);
+               getLog().debug("isValue: " + types[i].getClassName() + " value=null value result=" + result);
+               assertFalse(nullValues[j] + " should NOT be a simple value of " + types[i], result);
+            }
+         }
+      }
+   }
+
+   public void testHashCode() throws Exception
+   {
+      for (int i = 0; i < types.length; i++)
+      {
+         int classHashCode = classes[i].getName().hashCode();
+         int typeHashCode = types[i].hashCode();
+         getLog().debug("hashCode: " + types[i].getClassName() + " expected=" + classHashCode + " actual=" + typeHashCode);
+         assertEquals(classHashCode, typeHashCode);
+      }
+   }
+
+   public void testToString() throws Exception
+   {
+      String smt = SimpleMetaType.class.getSimpleName();
+      for (int i = 0; i < types.length; i++)
+      {
+         String className = classes[i].getName();
+         String toString = types[i].toString();
+         getLog().debug("toString: " + types[i].getClassName() + " value=" + toString);
+         assertTrue("SimpleMetaType " + className + " should contain " + smt, toString.indexOf(smt) != -1);
+         assertTrue("SimpleMetaType " + className + " should contain " + className, toString.indexOf(className) != -1);
+      }
+   }
+
+   public void testSerialization() throws Exception
+   {
+      for (int i = 0; i < types.length; i++)
+      {
+         getLog().debug("serialization: " + types[i].getClassName() + " original=" + types[i]);
+         byte[] bytes = serialize(types[i]);
+         SimpleMetaType result = (SimpleMetaType) deserialize(bytes);
+         getLog().debug("serialization: " + types[i].getClassName() + " result  =" + types[i]);
+
+         assertTrue("Should resolve to same object after serialization " + types[i], types[i] == result);
+      }
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/TypesTestSuite.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/TypesTestSuite.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/types/test/TypesTestSuite.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,53 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.metatype.types.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+/**
+ * Types Test Suite.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 55115 $
+ */
+public class TypesTestSuite extends TestSuite
+{
+   public static void main(String[] args)
+   {
+      TestRunner.run(suite());
+   }
+
+   public static Test suite()
+   {
+      TestSuite suite = new TestSuite("Types Tests");
+
+      suite.addTest(MetaTypeUnitTestCase.suite());
+      suite.addTest(SimpleMetaTypeUnitTestCase.suite());
+      suite.addTest(ArrayMetaTypeUnitTestCase.suite());
+      suite.addTest(ImmutableCompositeMetaTypeUnitTestCase.suite());
+      suite.addTest(ImmutableTableMetaTypeUnitTestCase.suite());
+      
+      return suite;
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/values/test/CompositeValueSupportUnitTestCase.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/values/test/CompositeValueSupportUnitTestCase.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/values/test/CompositeValueSupportUnitTestCase.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,546 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.metatype.values.test;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+import junit.framework.Test;
+
+import org.jboss.metatype.api.types.CompositeMetaType;
+import org.jboss.metatype.api.values.CompositeValue;
+import org.jboss.metatype.api.values.CompositeValueSupport;
+import org.jboss.metatype.api.values.MetaValue;
+import org.jboss.metatype.api.values.SimpleValue;
+import org.jboss.test.metatype.AbstractMetaTypeTest;
+
+/**
+ * CompositeValueSupportUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class CompositeValueSupportUnitTestCase extends AbstractMetaTypeTest
+{
+   public static Test suite()
+   {
+      return suite(CompositeValueSupportUnitTestCase.class);
+   }
+   
+   public CompositeValueSupportUnitTestCase(String name)
+   {
+      super(name);
+   }
+
+   public void testCompositeValueSupport() throws Exception
+   {
+      CompositeMetaType compositeMetaType = initCompositeMetaType();
+      Map<String, MetaValue> map = initMapValues();
+      String[] keys = initKeys();
+      MetaValue[] values = initValues();
+      new CompositeValueSupport(compositeMetaType, map);
+      new CompositeValueSupport(compositeMetaType, keys, values);
+   }
+
+   public void testGetCompositeMetaType() throws Exception
+   {
+      CompositeMetaType compositeMetaType = initCompositeMetaType();
+      Map<String, MetaValue> map = initMapValues();
+      CompositeValue v = new CompositeValueSupport(compositeMetaType, map);
+      assertEquals(compositeMetaType, v.getMetaType());
+   }
+
+   public void testGet()throws Exception
+   {
+      CompositeMetaType compositeMetaType = initCompositeMetaType();
+      Map<String, MetaValue> map = initMapValues();
+      CompositeValue v = new CompositeValueSupport(compositeMetaType, map);
+
+      assertEquals(initStringValue1(), v.get("name1"));
+      assertEquals(initInteger2(), v.get("name2"));
+   }
+
+   public void testGetAll() throws Exception
+   {
+      SimpleValue<String> value1 = initStringValue1();
+      SimpleValue<Integer> integer2 = initInteger2();
+      CompositeMetaType compositeMetaType = initCompositeMetaType();
+      Map<String, MetaValue> map = initMapValues();
+      CompositeValue v = new CompositeValueSupport(compositeMetaType, map);
+
+      MetaValue[] result = v.getAll(new String[] { "name1", "name2" });
+      assertEquals(value1, result[0]);
+      assertEquals(integer2, result[1]);
+      result = v.getAll(new String[] { "name2", "name1" });
+      assertEquals(value1, result[1]);
+      assertEquals(integer2, result[0]);
+      result = v.getAll(new String[] { "name1" });
+      assertEquals(value1, result[0]);
+      result = v.getAll(new String[] { "name2" });
+      assertEquals(integer2, result[0]);
+   }
+
+   public void testContainsKey() throws Exception
+   {
+      CompositeMetaType compositeMetaType = initCompositeMetaType();
+      Map<String, MetaValue> map = initMapValues();
+      CompositeValue v = new CompositeValueSupport(compositeMetaType, map);
+      assertTrue("data should contain key name1", v.containsKey("name1"));
+      assertTrue("data should contain key name2", v.containsKey("name2"));
+      assertFalse("data should not contain key nameX", v.containsKey("nameX"));
+      assertFalse("data should not contain key null", v.containsKey(null));
+      assertFalse("data should not contain key <empty>", v.containsKey(""));
+   }
+
+   public void testContainsValue() throws Exception
+   {
+      SimpleValue<String> value1 = initStringValue1();
+      SimpleValue<Integer> integer2 = initInteger2();
+      SimpleValue<String> name1 = initStringName1();
+      SimpleValue<String> nullString = initStringNull();
+      SimpleValue<String> emptyString = initStringEmpty();
+      SimpleValue<Integer> nullInteger = initIntegerNull();
+      CompositeMetaType compositeMetaType = initCompositeMetaType();
+      Map<String, MetaValue> map = initMapValues();
+      CompositeValue v = new CompositeValueSupport(compositeMetaType, map);
+
+      assertTrue("data should contain value value1", v.containsValue(value1));
+      assertTrue("data should contain value 2", v.containsValue(integer2));
+      assertFalse("data should not contain value name1", v.containsValue(name1));
+      assertFalse("data should not contain key null", v.containsValue(null));
+      assertFalse("data should not contain key null", v.containsValue(nullString));
+      assertFalse("data should not contain key <empty>", v.containsValue(emptyString));
+
+      map.clear();
+      map.put("name1", value1);
+      map.put("name2", null);
+      v = new CompositeValueSupport(compositeMetaType, map);
+      assertTrue("data should contain value null", v.containsValue(null));
+      assertFalse("data should not contain key null", v.containsValue(nullString));
+
+      map.clear();
+      map.put("name1", value1);
+      map.put("name2", nullInteger);
+      v = new CompositeValueSupport(compositeMetaType, map);
+      assertTrue("data should contain value null", v.containsValue(nullInteger));
+      assertFalse("data should not contain key null", v.containsValue(null));
+   }
+
+   public void testValues() throws Exception
+   {
+      SimpleValue<String> value1 = initStringValue1();
+      SimpleValue<Integer> integer2 = initInteger2();
+      SimpleValue<String> name1 = initStringName1();
+      SimpleValue<String> nullString = initStringNull();
+      SimpleValue<String> emptyString = initStringEmpty();
+      SimpleValue<Integer> nullInteger = initIntegerNull();
+
+      CompositeMetaType compositeMetaType = initCompositeMetaType();
+      Map<String, MetaValue> map = initMapValues();
+      CompositeValue v = new CompositeValueSupport(compositeMetaType, map);
+      Collection<?> values = v.values();
+      assertTrue("data values contain 2 elements", values.size() == 2);
+      assertTrue("data values should have value1", values.contains(value1));
+      assertTrue("data values should have 2", values.contains(integer2));
+      assertFalse("data values should not have name1", values.contains(name1));
+      assertFalse("data values should not have null", values.contains(null));
+      assertFalse("data values should not have null", values.contains(nullString));
+      assertFalse("data values should not have <empty>", values.contains(emptyString));
+
+      map.clear();
+      map.put("name1", value1);
+      map.put("name2", null);
+      v = new CompositeValueSupport(compositeMetaType, map);
+      values = v.values();
+      assertTrue("data values should contain value null", values.contains(null));
+      assertFalse("data values should not have null", values.contains(nullString));
+
+      map.clear();
+      map.put("name1", value1);
+      map.put("name2", nullInteger);
+      v = new CompositeValueSupport(compositeMetaType, map);
+      values = v.values();
+      assertTrue("data values should contain value null", values.contains(nullInteger));
+      assertFalse("data values should not have null", values.contains(null));
+   }
+
+   public void testEquals() throws Exception
+   {
+      CompositeMetaType compositeMetaType = initCompositeMetaType();
+      Map<String, MetaValue> map = initMapValues();
+      CompositeValue v = new CompositeValueSupport(compositeMetaType, map);
+
+      assertEquals("data should equal itself", v, v);
+      assertNotSame("data should not equal null", v, null);
+      assertNotSame("data should not equal non CompositeData", v, new Object());
+
+      CompositeValue v2 = new CompositeValueSupport(compositeMetaType, map);
+
+      assertEquals("data should equal with data2 with different instance of the same composite type", v, v2);
+      assertEquals("data should equal with data2 with different instance of the same composite type", v2, v);
+
+      CompositeMetaType compositeMetaType2 = initCompositeMetaType2();
+      v2 = new CompositeValueSupport(compositeMetaType2, map);
+
+      assertNotSame("data should not be equal with data2 with different composite type", v, v2);
+      assertNotSame("data2 should not be equal with data with different composite type", v2, v);
+
+      Map<String, MetaValue> map2 = initMapValues2();
+      v2 = new CompositeValueSupport(compositeMetaType, map2);
+
+      assertNotSame("data should not be equal with data2 with different values", v, v2);
+      assertNotSame("data2 should not be equal with data with different value", v2, v);
+   }
+
+   public void testHashCode() throws Exception
+   {
+      CompositeMetaType compositeMetaType = initCompositeMetaType();
+      Map<String, MetaValue> map = initMapValues();
+      CompositeValue v = new CompositeValueSupport(compositeMetaType, map);
+
+      int myHashCode = compositeMetaType.hashCode() + "value1".hashCode() + new Integer(2).hashCode();
+      assertEquals("Wrong hash code generated", myHashCode, v.hashCode());
+   }
+
+   public void testToString() throws Exception
+   {
+      CompositeMetaType compositeMetaType = initCompositeMetaType();
+      Map<String, MetaValue> map = initMapValues();
+      CompositeValue v = new CompositeValueSupport(compositeMetaType, map);
+
+      String toString = v.toString();
+
+      assertTrue("toString() should contain the composite type", toString.indexOf(compositeMetaType.toString()) != -1);
+      assertTrue("toString() should contain name1", toString.indexOf("name1") != -1);
+      assertTrue("toString() should contain value1", toString.indexOf("value1") != -1);
+      assertTrue("toString() should contain name2=", toString.indexOf("name2") != -1);
+      assertTrue(toString + " should contain " + new Integer(2), toString.indexOf(new Integer(2).toString()) != -1);
+   }
+
+   public void testSerialization() throws Exception
+   {
+      CompositeMetaType compositeMetaType = initCompositeMetaType();
+      Map<String, MetaValue> map = initMapValues();
+      CompositeValue v = new CompositeValueSupport(compositeMetaType, map);
+      byte[] bytes = serialize(v);
+      Object result = deserialize(bytes);
+      assertEquals(v, result);
+   }
+
+   public void testErrorsArray() throws Exception
+   {
+      CompositeMetaType compositeMetaType = initCompositeMetaType();
+      String[] itemNames = initKeys();
+      MetaValue[] itemValues = initValues();
+
+      try
+      {
+         new CompositeValueSupport(null, itemNames, itemValues);
+         fail("Excepted IllegalArgumentException for null composite type");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new CompositeValueSupport(compositeMetaType, null, itemValues);
+         fail("Excepted IllegalArgumentException for null item names");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new CompositeValueSupport(compositeMetaType, new String[0], itemValues);
+         fail("Excepted IllegalArgumentException for empty item names");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new CompositeValueSupport(compositeMetaType, itemNames, null);
+         fail("Excepted IllegalArgumentException for null item values");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new CompositeValueSupport(compositeMetaType, itemNames, new MetaValue[0]);
+         fail("Excepted IllegalArgumentException for empty item values");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new CompositeValueSupport(compositeMetaType, new String[] { "name1", null }, itemValues);
+         fail("Excepted IllegalArgumentException for a null item name");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new CompositeValueSupport(compositeMetaType, new String[] { "name1", "" }, itemValues);
+         fail("Excepted IllegalArgumentException for an empty item name");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new CompositeValueSupport(compositeMetaType, itemNames, new MetaValue[] { initStringWrong() });
+         fail("Excepted IllegalArgumentException for mismatch in number of itemNames/itemValues");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new CompositeValueSupport(compositeMetaType, new String[] { "name1" }, new MetaValue[] { initStringValue1() });
+         fail("Excepted IllegalArgumentException for mismatch in number of itemNames for CompositeType/CompositeData");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new CompositeValueSupport(compositeMetaType, new String[] { "name1", "wrongName" }, itemValues);
+         fail("Excepted IllegalArgumentException for an item name not in the composite type");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new CompositeValueSupport(compositeMetaType, itemNames, new MetaValue[] { initStringValue1(), initStringWrong() });
+         fail("Excepted IllegalArgumentException for an item value of the wrong type");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      new CompositeValueSupport(compositeMetaType, itemNames, new MetaValue[] { initStringValue1(), null });
+      new CompositeValueSupport(compositeMetaType, itemNames, new MetaValue[] { initStringValue1(), initIntegerNull() });
+   }
+
+   public void testErrorsMap() throws Exception
+   {
+      CompositeMetaType compositeMetaType = initCompositeMetaType();
+      Map<String, MetaValue> map = initMapValues();
+
+      try
+      {
+         new CompositeValueSupport(null, map);
+         fail("Excepted IllegalArgumentException for null composite type");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new CompositeValueSupport(compositeMetaType, null);
+         fail("Excepted IllegalArgumentException for null map");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         new CompositeValueSupport(compositeMetaType, new HashMap<String, MetaValue>());
+         fail("Excepted IllegalArgumentException for empty map");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         HashMap<String, MetaValue> map2 = new HashMap<String, MetaValue>();
+         map2.put("name1", initStringValue1());
+         map2.put(null, initInteger2());
+         new CompositeValueSupport(compositeMetaType, map2);
+         fail("Excepted IllegalArgumentException for a null key in map");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         HashMap<String, MetaValue> map2 = new HashMap<String, MetaValue>();
+         map2.put("name1", initStringValue1());
+         map2.put("", initInteger2());
+         new CompositeValueSupport(compositeMetaType, map2);
+         fail("Excepted IllegalArgumentException for an empty key in map");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         HashMap<String, MetaValue> map2 = new HashMap<String, MetaValue>();
+         map2.put("name1", initStringValue1());
+         new CompositeValueSupport(compositeMetaType, map2);
+         fail("Excepted IllegalArgumentException for mismatch in number of items for CompositeType/CompositeData");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         HashMap<String, MetaValue> map2 = new HashMap<String, MetaValue>();
+         map2.put("name1", initStringValue1());
+         map2.put("wrongName", initInteger2());
+         new CompositeValueSupport(compositeMetaType, map2);
+         fail("Excepted IllegalArgumentException for an item name not in the composite type");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         HashMap<String, MetaValue> map2 = new HashMap<String, MetaValue>();
+         map2.put("name1", initStringValue1());
+         map2.put("name2", initStringWrong());
+         new CompositeValueSupport(compositeMetaType, map2);
+         fail("Excepted IllegalArgumentException for an item value of the wrong type");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      HashMap<String, MetaValue> map2 = new HashMap<String, MetaValue>();
+      map2.put("name1", initStringValue1());
+      map2.put("name2", null);
+      new CompositeValueSupport(compositeMetaType, map2);
+
+      map2 = new HashMap<String, MetaValue>();
+      map2.put("name1", initStringValue1());
+      map2.put("name2", initIntegerNull());
+      new CompositeValueSupport(compositeMetaType, map2);
+   }
+
+   public void testErrors() throws Exception
+   {
+      CompositeMetaType compositeMetaType = initCompositeMetaType();
+      Map<String, MetaValue> map = initMapValues();
+      CompositeValue data = new CompositeValueSupport(compositeMetaType, map);
+
+      try
+      {
+         data.get(null);
+         fail("Excepted IllegalArgumentException for get and a null key");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         data.get("");
+         fail("Excepted IllegalArgumentException for get and an empty key");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         data.get("wrong");
+         fail("Excepted IllegalArgumentException for get and a wrong key");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         data.getAll(new String[] { "name1", null });
+         fail("Excepted IllegalArgumentException for getAll and a null key");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         data.getAll(new String[] { "name1", "" });
+         fail("Excepted IllegalArgumentException for getAll and an empty key");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      try
+      {
+         data.getAll(new String[] { "name1", "wrong" });
+         fail("Excepted IllegalArgumentException for getAll and an invalid key");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/values/test/SimpleValueSupportUnitTestCase.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/values/test/SimpleValueSupportUnitTestCase.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/values/test/SimpleValueSupportUnitTestCase.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,139 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.metatype.values.test;
+
+import junit.framework.Test;
+
+import org.jboss.metatype.api.types.SimpleMetaType;
+import org.jboss.metatype.api.values.SimpleValue;
+import org.jboss.metatype.api.values.SimpleValueSupport;
+import org.jboss.test.metatype.AbstractMetaTypeTest;
+
+/**
+ * SimpleValueSupportUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class SimpleValueSupportUnitTestCase extends AbstractMetaTypeTest
+{
+   public static Test suite()
+   {
+      return suite(SimpleValueSupportUnitTestCase.class);
+   }
+   
+   public SimpleValueSupportUnitTestCase(String name)
+   {
+      super(name);
+   }
+
+   public void testSimpleValueSupport() throws Exception
+   {
+      initStringValue1();
+   }
+
+   public void testGetSimpleMetaType() throws Exception
+   {
+      SimpleValue<String> value = initStringValue1();
+      assertEquals(SimpleMetaType.STRING, value.getMetaType());
+   }
+
+   public void testGetValue()throws Exception
+   {
+      SimpleValue<String> value = initStringValue1();
+      assertEquals("value1", value.getValue());
+   }
+
+   public void testSetValue()throws Exception
+   {
+      SimpleValueSupport<String> value = (SimpleValueSupport<String>) initStringValue1();
+      value.setValue("value2");
+      assertEquals("value2", value.getValue());
+   }
+
+   public void testEquals() throws Exception
+   {
+      SimpleValue<String> v = initStringValue1();
+
+      assertEquals("data should equal itself", v, v);
+      assertNotSame("data should not equal null", v, null);
+      assertNotSame("data should not equal null value", v, initStringNull());
+      assertNotSame("data should not equal empty value", v, initStringEmpty());
+      assertNotSame("data should not equal non SimpleValue", v, new Object());
+
+      SimpleValue v2 = initStringValue1();
+
+      assertEquals("data should equal with data2 with different instance of the same simple type", v, v2);
+      assertEquals("data should equal with data2 with different instance of the same simple type", v2, v);
+
+      v2 = initInteger2();
+
+      assertNotSame("data should not be equal with data2 with different simple type", v, v2);
+      assertNotSame("data2 should not be equal with data with different simple type", v2, v);
+
+      v2 = initStringName1();
+
+      assertNotSame("data should not be equal with data2 with different values", v, v2);
+      assertNotSame("data2 should not be equal with data with different value", v2, v);
+   }
+
+   public void testHashCode() throws Exception
+   {
+      SimpleValue<String> v = initStringValue1();
+
+      int myHashCode = "value1".hashCode();
+      assertEquals("Wrong hash code generated", myHashCode, v.hashCode());
+   }
+
+   public void testToString() throws Exception
+   {
+      SimpleValue<String> v = initStringValue1();
+
+      String toString = v.toString();
+
+      assertTrue("toString() should contain the simple type", toString.indexOf(SimpleMetaType.STRING.toString()) != -1);
+      assertTrue("toString() should contain value1", toString.indexOf("value1") != -1);
+   }
+
+   public void testSerialization() throws Exception
+   {
+      SimpleValue<String> v = initStringValue1();
+      byte[] bytes = serialize(v);
+      Object result = deserialize(bytes);
+      assertEquals(v, result);
+   }
+
+   public void testErrors() throws Exception
+   {
+      try
+      {
+         new SimpleValueSupport<String>(null, "value1");
+         fail("Excepted IllegalArgumentException for null simple type");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+
+      new SimpleValueSupport<String>(SimpleMetaType.STRING, null);
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/values/test/TableValueSupportUnitTestCase.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/values/test/TableValueSupportUnitTestCase.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/values/test/TableValueSupportUnitTestCase.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,714 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2006, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.metatype.values.test;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import junit.framework.Test;
+
+import org.jboss.metatype.api.types.CompositeMetaType;
+import org.jboss.metatype.api.types.ImmutableTableMetaType;
+import org.jboss.metatype.api.types.TableMetaType;
+import org.jboss.metatype.api.values.CompositeValue;
+import org.jboss.metatype.api.values.CompositeValueSupport;
+import org.jboss.metatype.api.values.MetaValue;
+import org.jboss.metatype.api.values.TableValue;
+import org.jboss.metatype.api.values.TableValueSupport;
+import org.jboss.test.metatype.AbstractMetaTypeTest;
+
+/**
+ * TableValueSupportUnitTestCase.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 1.1 $
+ */
+public class TableValueSupportUnitTestCase extends AbstractMetaTypeTest
+{
+   public static Test suite()
+   {
+      return suite(TableValueSupportUnitTestCase.class);
+   }
+   
+   public TableValueSupportUnitTestCase(String name)
+   {
+      super(name);
+   }
+
+   public void testTableValueSupport() throws Exception
+   {
+      TableMetaType tableType = initTableType();
+
+      new TableValueSupport(tableType);
+      new TableValueSupport(tableType, 100, .5f);
+   }
+   
+   public void testGetTabularType() throws Exception
+   {
+      TableMetaType tableType = initTableType();
+
+      TableValueSupport data = new TableValueSupport(tableType);
+      assertTrue("Expected the same table type", data.getMetaType().equals(tableType));
+   }
+   
+   public void testCalculateIndex() throws Exception
+   {
+      TableMetaType tableType = initTableType();
+
+      TableValueSupport data = new TableValueSupport(tableType);
+
+      CompositeValue compData = initCompositeValue(data);
+      Object[] index = data.calculateIndex(compData);
+
+      assertEquals("Expected index element 0 to be value1", index[0], initStringValue1());
+      assertEquals("Expected index element 1 to be 2", index[1], initInteger2());
+
+      compData = initCompositeValue3(data);
+      index = data.calculateIndex(compData);
+
+      assertEquals("Expected index element 0 to be value2", index[0], initStringValue2());
+      assertEquals("Expected index element 1 to be 3", index[1], initInteger3());
+   }
+
+   public void testContainsKey() throws Exception
+   {
+      TableMetaType tableType = initTableType();
+
+      TableValueSupport data = new TableValueSupport(tableType);
+
+      assertFalse("Didn't expect containsKey null", data.containsKey(null));
+
+      MetaValue[] index = new MetaValue[] { initStringValue1(), initInteger2() };
+      assertFalse("Didn't expect containsKey on empty data", data.containsKey(index));
+
+      CompositeValue compData = initCompositeValue2(data);
+      assertFalse("Didn't expect containsKey on index not present", data.containsKey(index));
+
+      compData = initCompositeValue(data);
+      data.put(compData);
+      assertTrue("Expected containsKey", data.containsKey(index));
+
+      compData = initCompositeValue2(data);
+      assertFalse("Didn't expect containsKey on index still not present", data.containsKey(data.calculateIndex(compData)));
+
+      data.remove(index);
+      assertFalse("Didn't expect removed data in containsKey", data.containsKey(index));
+   }
+
+   public void testContainsValue() throws Exception
+   {
+      TableMetaType tableType = initTableType();
+
+      TableValueSupport data = new TableValueSupport(tableType);
+
+      assertFalse("Didn't expect containsValue null", data.containsValue(null));
+
+      CompositeMetaType rowType2 = initCompositeMetaType2();
+
+      CompositeValue compData2 = initCompositeValue(rowType2);
+
+      assertFalse("Didn't expect containsValue wrong composite type", data.containsValue(compData2));
+
+      CompositeValue compData = initCompositeValue(data);
+      assertFalse("Didn't expect containsValue on data not present", data.containsValue(compData));
+
+      data.put(compData);
+      assertTrue("Expected containsValue", data.containsValue(compData));
+
+      compData = initCompositeValue2(data);
+      assertFalse("Didn't expect containsValue on value still not present", data.containsValue(compData));
+
+      assertFalse("Didn't expect containsValue still wrong composite type", data.containsValue(compData2));
+
+      data.remove(data.calculateIndex(compData));
+      assertFalse("Didn't expect removed data in containsValue", data.containsValue(compData));
+   }
+
+   public void testGet() throws Exception
+   {
+      TableMetaType tableType = initTableType();
+
+      TableValueSupport data = new TableValueSupport(tableType);
+
+      MetaValue[] index = initValues2();
+      assertNull("Expected null for get on data not present", data.get(index));
+
+      CompositeValue compData = initCompositeValue(data);
+      index = initValues();
+      data.put(compData);
+      assertEquals("Expected get to return the same value", compData, data.get(index));
+
+      index = initValues2();
+      assertNull("Didn't expect get on value still not present", data.get(index));
+
+      index = initValues();
+      data.remove(index);
+      assertNull("Didn't expect removed data in get", data.get(index));
+   }
+
+   public void testPut() throws Exception
+   {
+      TableMetaType tableType = initTableType();
+
+      TableValueSupport data = new TableValueSupport(tableType);
+
+      CompositeValue compData = initCompositeValue(data);
+      MetaValue[] index = initValues();
+      data.put(compData);
+      assertEquals("The data should be present after put", compData, data.get(index));
+
+      CompositeValue compData2 = initCompositeValue2(data);
+      index = initValues2();
+      data.put(compData2);
+      assertEquals("Another data should be present after put", compData2, data.get(index));
+
+      index = initValues();
+      assertEquals("The previous data should be present after put", compData, data.get(index));
+
+      data.remove(index);
+      data.put(compData);
+      assertEquals("Data should be present after remove/put", compData, data.get(index));
+   }
+
+   public void testRemove() throws Exception
+   {
+      TableMetaType tableType = initTableType();
+
+      TableValueSupport data = new TableValueSupport(tableType);
+
+      CompositeValue compData = initCompositeValue(data);
+      MetaValue[] index = initValues();
+
+      assertNull("Remove on data not present returns null", data.remove(index));
+
+      data.put(compData);
+      assertEquals("Remove on data present returns the data", compData, data.remove(index));
+   }
+
+   public void testPutAll() throws Exception
+   {
+      TableMetaType tableType = initTableType();
+
+      TableValueSupport data = new TableValueSupport(tableType);
+
+      data.putAll((CompositeValue[]) null);
+      assertTrue("Put all null is ok", data.isEmpty());
+
+      CompositeValue compData = initCompositeValue(data);
+
+      CompositeValue[] toPut = new CompositeValue[] { compData };
+      data.putAll(toPut);
+      assertEquals("Put all added one", 1, data.size());
+      assertTrue("Put all added the correct data", data.containsValue(compData));
+
+      CompositeValue compData2 = initCompositeValue2(data);
+      CompositeValue compData3 = initCompositeValue4(data);
+
+      toPut = new CompositeValue[] { compData2, compData3 };
+      data.putAll(toPut);
+      assertEquals("Put all added two", 3, data.size());
+      assertTrue("Put all added the correct data", data.containsValue(compData2));
+      assertTrue("Put all added the correct data", data.containsValue(compData3));
+      assertTrue("Put all original data still present", data.containsValue(compData));
+   }
+
+   public void testClear() throws Exception
+   {
+      TableMetaType tableType = initTableType();
+
+      TableValueSupport data = new TableValueSupport(tableType);
+
+      data.putAll((CompositeValue[]) null);
+      assertTrue("Put all null is ok", data.isEmpty());
+
+      CompositeValue compData = initCompositeValue(data);
+      CompositeValue compData2 = initCompositeValue2(data);
+      CompositeValue compData3 = initCompositeValue4(data);
+
+      data.putAll(new CompositeValue[] { compData, compData2, compData3 });
+
+      data.clear();
+      assertTrue("Clear should clear the data", data.isEmpty());
+   }
+
+   public void testSize() throws Exception
+   {
+      TableMetaType tableType = initTableType();
+
+      TableValueSupport data = new TableValueSupport(tableType);
+
+      assertEquals("Initial size is zero", 0, data.size());
+
+      CompositeValue compData = initCompositeValue(data);
+
+      data.putAll(new CompositeValue[] { compData });
+      assertEquals("Expected one element", 1, data.size());
+
+      CompositeValue compData2 = initCompositeValue2(data);
+      CompositeValue compData3 = initCompositeValue4(data);
+
+      data.putAll(new CompositeValue[] { compData2, compData3 });
+      assertEquals("Expected three elements", 3, data.size());
+
+      data.remove(initValues4());
+      assertEquals("Expected two elements", 2, data.size());
+
+      data.clear();
+      assertEquals("Expected no elements", 0, data.size());
+   }
+
+   public void testIsEmpty() throws Exception
+   {
+      TableMetaType tableType = initTableType();
+
+      TableValueSupport data = new TableValueSupport(tableType);
+
+      assertTrue("Initially empty", data.isEmpty());
+
+      CompositeValue compData = initCompositeValue(data);
+
+      data.putAll(new CompositeValue[] { compData });
+      assertFalse("Not empty after a put", data.isEmpty());
+
+      data.clear();
+      assertTrue("Expected no elements", data.isEmpty());
+   }
+
+   public void testKeySet() throws Exception
+   {
+      TableMetaType tableType = initTableType();
+
+      TableValueSupport data = new TableValueSupport(tableType);
+
+      CompositeValue compData = initCompositeValue(data);
+      CompositeValue compData2 = initCompositeValue2(data);
+      CompositeValue compData3 = initCompositeValue4(data);
+
+      data.putAll(new CompositeValue[] { compData, compData2, compData3 });
+
+      Set<List<MetaValue>> keySet = data.keySet();
+      assertEquals("Key set should contain 3 elements", 3, keySet.size());
+      assertTrue("Key set should contain index [value1, 2]", keySet.contains(Arrays.asList(initValues())));
+      assertTrue("Key set should contain index [value1, 3]", keySet.contains(Arrays.asList(initValues2())));
+      assertTrue("Key set should contain index [value1, 4]", keySet.contains(Arrays.asList(initValues4())));
+   }
+
+   public void testValues() throws Exception
+   {
+      TableMetaType tableType = initTableType();
+
+      TableValueSupport data = new TableValueSupport(tableType);
+
+      CompositeValue compData = initCompositeValue(data);
+      CompositeValue compData2 = initCompositeValue2(data);
+      CompositeValue compData3 = initCompositeValue4(data);
+
+      data.putAll(new CompositeValue[] { compData, compData2, compData3 });
+
+      Collection<CompositeValue> values = data.values();
+      assertEquals("Values should contain 3 elements", 3, values.size());
+      assertTrue("Values should contain index compData", values.contains(compData));
+      assertTrue("Values should contain index compData2", values.contains(compData2));
+      assertTrue("Values should contain index compData3", values.contains(compData3));
+   }
+
+   public void testClone()
+      throws Exception
+   {
+      TableMetaType tableType = initTableType();
+
+      TableValueSupport data = new TableValueSupport(tableType);
+
+      CompositeValue compData = initCompositeValue(data);
+      CompositeValue compData2 = initCompositeValue2(data);
+      CompositeValue compData3 = initCompositeValue4(data);
+
+      data.putAll(new CompositeValue[] { compData, compData2, compData3 });
+
+      TableValue clone = data.clone();
+      assertEquals("Clone should have the same tabular type", data.getMetaType(), clone.getMetaType());
+      assertEquals("Clone should have the same number of elements", data.size(), clone.size());
+      CompositeValue compDataClone = clone.get(initValues());
+      assertTrue("Should be a shallow clone", compData == compDataClone);
+   }
+
+   public void testEquals() throws Exception
+   {
+      TableMetaType tableType = initTableType();
+
+      TableValueSupport data = new TableValueSupport(tableType);
+
+      assertNotSame("Null should not be equal", data, null);
+      assertNotSame("Only TableValues should be equal", data, new Object());
+
+      assertEquals("An instance should equal itself", data, data);
+
+      TableValueSupport data2 = new TableValueSupport(tableType);
+
+      assertEquals("Two different instances with the same table type are equal", data, data2);
+      assertEquals("Two different instances with the same table type are equal", data2, data);
+
+      TableMetaType tableType2 = initTableType2();
+      data2 = new TableValueSupport(tableType2);
+
+      assertNotSame("Instances with different table type are not equal", data, data2);
+      assertNotSame("Instances with different table type are not equal", data2, data);
+
+      CompositeValue compData = initCompositeValue(data);
+      CompositeValue compData2 = initCompositeValue2(data);
+      CompositeValue compData3 = initCompositeValue4(data);
+
+      data.putAll(new CompositeValue[] { compData, compData2, compData3 });
+
+      data2 = new TableValueSupport(tableType);
+      data2.putAll(new CompositeValue[] { compData, compData2, compData3 });
+      assertEquals("Instances with the same composite values are equal", data, data2);
+      assertEquals("Instances with the same composite values are equal", data2, data);
+
+      data2 = new TableValueSupport(tableType);
+      data2.putAll(new CompositeValue[] { compData, compData2});
+      assertNotSame("Instances with different composite values are not equal", data, data2);
+      assertNotSame("Instances with different composite values are not equal", data2, data);
+   }
+
+   public void testHashCode() throws Exception
+   {
+      TableMetaType tableType = initTableType();
+
+      TableValueSupport data = new TableValueSupport(tableType);
+
+      CompositeValue compData = initCompositeValue(data);
+      CompositeValue compData2 = initCompositeValue2(data);
+      CompositeValue compData3 = initCompositeValue4(data);
+
+      data.putAll(new CompositeValue[] { compData, compData2, compData3 });
+
+      int myHashCode = tableType.hashCode() + compData.hashCode() + compData2.hashCode() + compData3.hashCode();
+      assertEquals("Wrong hash code generated", myHashCode, data.hashCode());
+   }
+
+   public void testToString() throws Exception
+   {
+      TableMetaType tableType = initTableType();
+
+      TableValueSupport data = new TableValueSupport(tableType);
+
+      CompositeValue compData = initCompositeValue(data);
+      CompositeValue compData2 = initCompositeValue2(data);
+      CompositeValue compData3 = initCompositeValue4(data);
+
+      data.putAll(new CompositeValue[] { compData, compData2, compData3 });
+
+      String toString = data.toString();
+
+      assertTrue("toString() should contain the tabular type", toString.indexOf(tableType.toString()) != -1);
+      assertTrue("toString() should contain index=compositeValue for compData",
+         toString.indexOf(Arrays.asList(data.calculateIndex(compData)) + "=" + compData) != -1);
+      assertTrue("toString() should contain index=compositeValue for compData2",
+         toString.indexOf(Arrays.asList(data.calculateIndex(compData2)) + "=" + compData2) != -1);
+      assertTrue("toString() should contain index=compositeValue for compData3",
+         toString.indexOf(Arrays.asList(data.calculateIndex(compData3)) + "=" + compData3) != -1);
+   }
+
+   public void testSerialization() throws Exception
+   {
+      TableMetaType tableType = initTableType();
+
+      TableValueSupport data = new TableValueSupport(tableType);
+
+      CompositeValue compData = initCompositeValue(data);
+      CompositeValue compData2 = initCompositeValue2(data);
+      CompositeValue compData3 = initCompositeValue4(data);
+
+      data.putAll(new CompositeValue[] { compData, compData2, compData3 });
+
+      byte[] bytes = serialize(data);
+      Object result = deserialize(bytes);
+      assertEquals(data, result);
+   }
+
+   public void testErrors() throws Exception
+   {
+      TableMetaType tableType = initTableType();
+
+      CompositeValue compData = initCompositeValue(tableType.getRowType());
+      CompositeValue compData2 = initCompositeValue2(initCompositeMetaType2());
+
+      try
+      {
+         new TableValueSupport(null);
+         fail("Expected IllegalArgumentException for null tabular type");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         new TableValueSupport(null, 10, .5f);
+         fail("Expected IllegalArgumentException for null tabular type");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         new TableValueSupport(tableType, -1, .5f);
+         fail("Expected IllegalArgumentException for negative initial capacity");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         new TableValueSupport(tableType, 10, 0f);
+         fail("Expected IllegalArgumentException for zero load factor");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         new TableValueSupport(tableType, 10, -0.5f);
+         fail("Expected IllegalArgumentException for negative load factor");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         TableValueSupport data = new TableValueSupport(tableType);
+         data.calculateIndex(null);
+         fail("Expected IllegalArgumentException for calculate index on null object");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         TableValueSupport data = new TableValueSupport(tableType);
+         data.calculateIndex(compData2);
+         fail("Expected IllegalArgumentException for calculate index on wrong composite type");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         TableValueSupport data = new TableValueSupport(tableType);
+         data.get((MetaValue[]) null);
+         fail("Expected IllegalArgumentException for get(null)");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         TableValueSupport data = new TableValueSupport(tableType);
+         data.get(new MetaValue[] { initStringWrong() });
+         fail("Expected IllegalArgumentException for get(wrong)");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         TableValueSupport data = new TableValueSupport(tableType);
+         data.put(null);
+         fail("Expected IllegalArgumentException for put(CompositeValue) with null value");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         TableValueSupport data = new TableValueSupport(tableType);
+         data.put(compData2);
+         fail("Expected IllegalArgumentException for put(CompositeValue) with wrong CompositeType");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         TableValueSupport data = new TableValueSupport(tableType);
+         data.put(compData);
+         data.put(compData);
+         fail("Expected IllegalArgumentException for put(CompositeValue)");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         TableValueSupport data = new TableValueSupport(tableType);
+         data.remove((MetaValue[]) null);
+         fail("Expected IllegalArgumentException for remove(null)");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         TableValueSupport data = new TableValueSupport(tableType);
+         data.remove(new MetaValue[] { initStringWrong() });
+         fail("Expected IllegalArgumentException for remove(wrong)");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         TableValueSupport data = new TableValueSupport(tableType);
+         CompositeValue[] toPut = new CompositeValue[] { compData, null };
+         data.putAll(toPut);
+         fail("Expected IllegalArgumentException for putAll(CompositeValue[]) null");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         TableValueSupport data = new TableValueSupport(tableType);
+         CompositeValue[] toPut = new CompositeValue[] { compData, compData2 };
+         data.putAll(toPut);
+         fail("Expected IllegalArgumentException for putAll(CompositeValue[]) wrong composite type");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         TableValueSupport data = new TableValueSupport(tableType);
+         CompositeValue[] toPut = new CompositeValue[] { compData, compData };
+         data.putAll(toPut);
+         fail("Expected IllegalArgumentException for putAll(CompositeValue[]) with duplicate data");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+      
+      try
+      {
+         TableValueSupport data = new TableValueSupport(tableType);
+         CompositeValue[] toPut = new CompositeValue[] { compData };
+         data.putAll(toPut);
+         data.putAll(toPut);
+         fail("Expected IllegalArgumentException for putAll(CompositeValue[]) adding a duplicate");
+      }
+      catch (Throwable t)
+      {
+         checkThrowable(IllegalArgumentException.class, t);
+      }
+   }
+
+   protected TableMetaType initTableType()
+   {
+      CompositeMetaType rowType = initCompositeMetaType();
+
+      String[] indexNames = new String[] { "name1", "name2" };
+      TableMetaType tableType = new ImmutableTableMetaType("typeName", "description", rowType, indexNames);
+      return tableType;
+   }
+
+   protected TableMetaType initTableType2()
+   {
+      CompositeMetaType rowType = initCompositeMetaType();
+
+      String[] indexNames = new String[] { "name1", "name2" };
+      TableMetaType tableType = new ImmutableTableMetaType("typeName2", "description", rowType, indexNames);
+      return tableType;
+   }
+
+   protected CompositeValue initCompositeValue(TableValue tableValue)
+   {
+      return initCompositeValue(tableValue.getMetaType().getRowType());
+   }
+
+   protected CompositeValue initCompositeValue(CompositeMetaType rowType)
+   {
+      Map<String, MetaValue> map = initMapValues();
+      CompositeValue compData = new CompositeValueSupport(rowType, map);
+      return compData;
+   }
+
+   protected CompositeValue initCompositeValue2(TableValue tableValue)
+   {
+      return initCompositeValue2(tableValue.getMetaType().getRowType());
+   }
+
+   protected CompositeValue initCompositeValue2(CompositeMetaType rowType)
+   {
+      Map<String, MetaValue> map = initMapValues2();
+      CompositeValue compData = new CompositeValueSupport(rowType, map);
+      return compData;
+   }
+
+   protected CompositeValue initCompositeValue3(TableValue tableValue)
+   {
+      Map<String, MetaValue> map = initMapValues3();
+      CompositeValue compData = new CompositeValueSupport(tableValue.getMetaType().getRowType(), map);
+      return compData;
+   }
+
+   protected CompositeValue initCompositeValue4(TableValue tableValue)
+   {
+      Map<String, MetaValue> map = initMapValues4();
+      CompositeValue compData = new CompositeValueSupport(tableValue.getMetaType().getRowType(), map);
+      return compData;
+   }
+}

Added: projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/values/test/ValuesTestSuite.java
===================================================================
--- projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/values/test/ValuesTestSuite.java	2006-12-19 11:33:03 UTC (rev 59138)
+++ projects/microcontainer/trunk/metatype/src/tests/org/jboss/test/metatype/values/test/ValuesTestSuite.java	2006-12-19 13:01:12 UTC (rev 59139)
@@ -0,0 +1,51 @@
+/*
+* JBoss, Home of Professional Open Source
+* Copyright 2005, JBoss Inc., and individual contributors as indicated
+* by the @authors tag. See the copyright.txt in the distribution for a
+* full listing of individual contributors.
+*
+* This is free software; you can redistribute it and/or modify it
+* under the terms of the GNU Lesser General Public License as
+* published by the Free Software Foundation; either version 2.1 of
+* the License, or (at your option) any later version.
+*
+* This software is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+* Lesser General Public License for more details.
+*
+* You should have received a copy of the GNU Lesser General Public
+* License along with this software; if not, write to the Free
+* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+*/
+package org.jboss.test.metatype.values.test;
+
+import junit.framework.Test;
+import junit.framework.TestSuite;
+import junit.textui.TestRunner;
+
+/**
+ * Values Test Suite.
+ * 
+ * @author <a href="adrian at jboss.com">Adrian Brock</a>
+ * @version $Revision: 55115 $
+ */
+public class ValuesTestSuite extends TestSuite
+{
+   public static void main(String[] args)
+   {
+      TestRunner.run(suite());
+   }
+
+   public static Test suite()
+   {
+      TestSuite suite = new TestSuite("Values Tests");
+
+      suite.addTest(SimpleValueSupportUnitTestCase.suite());
+      suite.addTest(CompositeValueSupportUnitTestCase.suite());
+      suite.addTest(TableValueSupportUnitTestCase.suite());
+      
+      return suite;
+   }
+}




More information about the jboss-cvs-commits mailing list