polygene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nic...@apache.org
Subject [39/51] [abbrv] [partial] zest-java git commit: Revert "First round of changes to move to org.apache.zest namespace."
Date Fri, 31 Jul 2015 02:47:58 GMT
http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/QualifiedName.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/common/QualifiedName.java b/core/api/src/main/java/org/qi4j/api/common/QualifiedName.java
new file mode 100644
index 0000000..a869791
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/common/QualifiedName.java
@@ -0,0 +1,252 @@
+/*
+ * Copyright (c) 2009, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.qi4j.api.common;
+
+import java.io.Serializable;
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Member;
+import org.qi4j.api.util.NullArgumentException;
+
+/**
+ * QualifiedName is a representation of Property names to their full declaration.
+ * <p>
+ * A QualifiedName is created by combining the name of a method and the name of the type that declares the method.
+ * This class also contains many static utility methods to manage QualifiedName instances.
+ * </p>
+ * <p>
+ * <strong>NOTE: Unless you do very generic libraries, entity stores and other extensions that is deeply coupled into
+ * the Zest runtime, it is very unlikely you will need to use this class directly.</strong>
+ * </p>
+ * <p>
+ * It is also important to notice that the QualifiedName needs to be long-term stable, as the names are written
+ * to persistent storage. So any changes in the formatting <strong>must be made in a backward-compatible manner
+ * </strong>.
+ * </p>
+ * <p>
+ * The QualifiedName has two intrinsic parts, one being the {@code type} and the other the {@code name}. The
+ * {@code type} comes from the class where the QualifiedName originates from and internally kept as a {@link TypeName}
+ * instance. The name is the name from the method name. When the QualifiedName instance is converted to an external
+ * string representation, via the offical and formal {@link #toString()} method, the {@code type} is normalized, i.e.
+ * any dollar characters ($) in the name are replaced by dashes (-), to make them URI friendly.
+ * </p>
+ * <p>
+ * QualifiedName instances are immutable, implements {@link #hashCode()} and {@link #equals(Object)} as a value
+ * object and can safely be used as keys in {@link java.util.Map}.
+ */
+public final class QualifiedName
+    implements Comparable<QualifiedName>, Serializable
+{
+    private final TypeName typeName;
+    private final String name;
+
+    /**
+     * Creates a QualifiedName from a method.
+     * <p>
+     * This factory method will create a QualifiedName from the Method itself.
+     *
+     * </p>
+     *
+     * @param method Type method that returns a Property, for which the QualifiedName will be representing.
+     *
+     * @return A QualifiedName representing this method.
+     *
+     * @throws NullArgumentException If the {@code method} argument passed is null.
+     */
+    public static QualifiedName fromAccessor( AccessibleObject method )
+    {
+        NullArgumentException.validateNotNull( "method", method );
+        return fromClass( ( (Member) method ).getDeclaringClass(), ( (Member) method ).getName() );
+    }
+
+    /**
+     * Creates a QualifiedName instance from the Class and a given name.
+     * <p>
+     * This factory method converts the {@code type} to a {@link TypeName} and appends the given {@code name}.
+     *
+     * @param type The Class that is the base of the QualifiedName.
+     * @param name The qualifier name which will be appended to the base name derived from the {@code type} argument.
+     *
+     * @return A QualifiedName instance representing the {@code type} and {@code name} arguments.
+     *
+     * @throws NullArgumentException if any of the two arguments are {@code null}, or if the name string is empty.
+     */
+    public static QualifiedName fromClass( Class type, String name )
+    {
+        return new QualifiedName( TypeName.nameOf( type ), name );
+    }
+
+    /**
+     * Creates a Qualified name from a type as string and a name qualifier.
+     *
+     * @param type The type name as a a string, which must be properly formatted. No checks for correctly formatted
+     *             type name is performed.
+     * @param name The qualifier name which will be appended to the base name derived from the {@code type} argument.
+     *
+     * @return A QualifiedName instance representing the {@code type} and {@code name} arguments.
+     *
+     * @throws NullArgumentException if any of the two arguments are {@code null} or either string is empty.
+     */
+    public static QualifiedName fromName( String type, String name )
+    {
+        return new QualifiedName( TypeName.nameOf( type ), name );
+    }
+
+    /**
+     * Creates a QualifiedName from the external string format of QualifiedName.
+     * <p>
+     * This factory method is the reverse of {@link QualifiedName#toString() }  method, and creates a new QualifiedName
+     * instance from the string representation of the QualifiedName.
+     * </p>
+     *
+     * @param fullQualifiedName The QualifiedName external string representation to be converted back into a QualifiedName
+     *                      instance.
+     *
+     * @return The QualifiedName instance represented by the {@code qualifiedName} argument.
+     *
+     * @throws IllegalArgumentException If the {@code qualifiedName} argument has wrong format.
+     */
+    public static QualifiedName fromFQN( String fullQualifiedName )
+    {
+        NullArgumentException.validateNotEmpty( "qualifiedName", fullQualifiedName );
+        int idx = fullQualifiedName.lastIndexOf( ":" );
+        if( idx == -1 )
+        {
+            throw new IllegalArgumentException( "Name '" + fullQualifiedName + "' is not a qualified name" );
+        }
+        final String type = fullQualifiedName.substring( 0, idx );
+        final String name = fullQualifiedName.substring( idx + 1 );
+        return new QualifiedName( TypeName.nameOf( type ), name );
+    }
+
+    QualifiedName( TypeName typeName, String name )
+    {
+        NullArgumentException.validateNotNull( "typeName", typeName );
+        NullArgumentException.validateNotEmpty( "name", name );
+        this.typeName = typeName;
+        this.name = name;
+    }
+
+    /**
+     * Returns the normalized string of the type part of the QualifiedName.
+     *
+     * <p>
+     * The normalized type name means that all dollar ($) characters have been replaced by dashes (-).
+     * </p>
+     *
+     * @return the normalized string of the type part of the QualifiedName.
+     */
+    public String type()
+    {
+        return typeName.normalized();
+    }
+
+    /**
+     * Returns the name component of the QualifiedName.
+     *
+     * @return the name component of the QualifiedName.
+     */
+    public String name()
+    {
+        return name;
+    }
+
+    /**
+     * Returns the URI of the QualifiedName.
+     *
+     * <p>
+     * The URI is the {@link #toNamespace()} followed by the {@code name} component.
+     * <p>
+     *
+     * @return the URI of the QualifiedName.
+     *
+     * @see #toNamespace()
+     */
+    public String toURI()
+    {
+        return toNamespace() + name;
+    }
+
+    /**
+     * Return the URI of the {@link TypeName} component of the QualifiedName.
+     * <p>
+     * The URI of the {@link TypeName} component is in the form of;
+     * </p>
+     * <pre>
+     * "urn:qi4j:type:" normalizedClassName
+     * </pre>
+     * <p>
+     * where {@code normalizedClassName} is the fully-qualified class name having had any dollar ($) characters replaced
+     * by URI friendly dashes (-), with a trailing hash (#). Examples;
+     * </p>
+     * <pre>
+     * urn:qi4j:type:org.qi4j.api.common.QualifiedName#
+     * urn:qi4j:type:org.qi4j.samples.MyClass-MyInnerClass#
+     * </pre>
+     *
+     * @return the URI of the {@link TypeName} component of the QualifiedName.
+     */
+    public String toNamespace()
+    {
+        return typeName.toURI() + "#";
+    }
+
+    /**
+     * Return the formal and official, long-term stable, external string representation of a QualifiedName.
+     * <p>
+     * This returns the {@link org.qi4j.api.common.TypeName#toString()} followed by the {@code name} component.
+     * </p>
+     *
+     * @return the formal and official, long-term stable, external string representation of a QualifiedName.
+     */
+    @Override
+    public String toString()
+    {
+        return typeName + ":" + name;
+    }
+
+    @Override
+    public boolean equals( Object o )
+    {
+        if( this == o )
+        {
+            return true;
+        }
+        if( o == null || getClass() != o.getClass() )
+        {
+            return false;
+        }
+
+        QualifiedName that = (QualifiedName) o;
+
+        return name.equals( that.name ) && typeName.equals( that.typeName );
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return 31 * typeName.hashCode() + name.hashCode();
+    }
+
+    @Override
+    public int compareTo( QualifiedName other )
+    {
+        final int result = typeName.compareTo( other.typeName );
+        if( result != 0 )
+        {
+            return result;
+        }
+        return name.compareTo( other.name );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/TypeName.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/common/TypeName.java b/core/api/src/main/java/org/qi4j/api/common/TypeName.java
new file mode 100644
index 0000000..6a485e6
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/common/TypeName.java
@@ -0,0 +1,111 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.qi4j.api.common;
+
+import java.io.Serializable;
+import java.lang.reflect.Type;
+import org.qi4j.api.util.Classes;
+import org.qi4j.api.util.NullArgumentException;
+
+/**
+ * Represents a Type name.
+ */
+public final class TypeName
+    implements Serializable, Comparable<TypeName>
+{
+    private final String name;
+
+    public static TypeName nameOf( Class type )
+    {
+        NullArgumentException.validateNotNull( "type", type );
+        return new TypeName( type.getName() );
+    }
+
+    public static TypeName nameOf( Type type )
+    {
+        return nameOf( Classes.RAW_CLASS.map( type ) );
+    }
+
+    public static TypeName nameOf( String typeName )
+    {
+        return new TypeName( typeName );
+    }
+
+    private TypeName( String name )
+    {
+        NullArgumentException.validateNotEmpty( "name", name );
+        this.name = name;
+    }
+
+    public String normalized()
+    {
+        return Classes.normalizeClassToURI( name );
+    }
+
+    public String toURI()
+    {
+        return Classes.toURI( name );
+    }
+
+    public String name()
+    {
+        return name;
+    }
+
+    @Override
+    public String toString()
+    {
+        return name;
+    }
+
+    public boolean isClass( final Class<?> type )
+    {
+        return type.getName().equals( name );
+    }
+
+    @Override
+    public boolean equals( final Object o )
+    {
+        if( this == o )
+        {
+            return true;
+        }
+        if( o == null || getClass() != o.getClass() )
+        {
+            return false;
+        }
+
+        final TypeName other = (TypeName) o;
+
+        return name.equals( other.name );
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return name.hashCode();
+    }
+
+    @Override
+    public int compareTo( final TypeName typeName )
+    {
+        return this.name.compareTo( typeName.name );
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/UseDefaults.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/common/UseDefaults.java b/core/api/src/main/java/org/qi4j/api/common/UseDefaults.java
new file mode 100644
index 0000000..94f4446
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/common/UseDefaults.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright (c) 2009, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.qi4j.api.common;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * Annotation to denote that the initial value of a Property will be the default value for the type if none is
+ * specified during construction.
+ * <p>
+ * These are the default values used for various types:
+ * </p>
+ * <pre>
+ * Byte: 0
+ * Short: 0
+ * Character: 0
+ * Integer: 0
+ * Long: 0L
+ * Double: 0.0d
+ * Float: 0.0f
+ * Boolean: false
+ * String: ""
+ * List: empty java.util.ArrayList
+ * Set: empty java.util.HashSet
+ * Collection: empty java.util.ArrayList
+ * enum: first declared value
+ * </pre>
+ * <p>
+ * If this annotation is not used, the property will be set to null, and unless {@code &#64;Optional} is declared
+ * is not allowed.
+ * </p>
+ * <p>
+ * It is also possible to change the default values for Composites during the assembly. This is done by calling the
+ * {@code org.qi4j.bootstrap.ModuleAssembly#forMixin(Class)} method.
+ * </p>
+ * <p>
+ * Example;
+ * Let's assume that we have the following mixin type;
+ *
+ * <pre><code>
+ * public interface SomeType
+ * {
+ *     &#64;UseDefaults
+ *     Property&lt;String&gt; someValue();
+ * }
+ * </code></pre>
+ * And that we want to have {@code someValue()} to be initialized to "&lt;unknown&gt;" instead of the empty string.
+ * Then we need to declare the default for that with the following in the assembler.
+ * <pre><code>
+ * public void assemble( ModuleAssembly module )
+ * {
+ *     module.forMixin( SomeType.class ).declareDefaults().someValue().set( "&lt;unknown&gt;" );
+ * }
+ * }
+ * </code></pre>
+ */
+@SuppressWarnings( "JavadocReference" )
+@Retention( RetentionPolicy.RUNTIME )
+@Target( { ElementType.METHOD, ElementType.FIELD } )
+@Documented
+public @interface UseDefaults
+{
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/Visibility.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/common/Visibility.java b/core/api/src/main/java/org/qi4j/api/common/Visibility.java
new file mode 100644
index 0000000..0f38f36
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/common/Visibility.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2007, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.qi4j.api.common;
+
+/**
+ * Visibility is a core concept in the Zest structure system. It defines the locale of composites and objects, i.e.
+ * how far they can be 'seen' and therefor be used.
+ * <p>
+ * When a Composite or Object is declared in the assembly phase, and no visibility is set, only other
+ * composites/objects within the same module can use that declaration. For a declared composite/object to be usable
+ * from other modules a higher visibility must be set, either that the Composite/Object can be used by others within
+ * the same Layer, or even to be used by those in the layer above.
+ * </p>
+ */
+public enum Visibility
+{
+    /**
+     * Artifact is visible only in the declaring module (default)
+     */
+    module,
+    /**
+     * Artifact is visible to all modules in the same layer
+     */
+    layer,
+    /**
+     * Artifact is visible to other modules in the same layer and any modules in extending layers
+     */
+    application
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/package.html
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/common/package.html b/core/api/src/main/java/org/qi4j/api/common/package.html
new file mode 100644
index 0000000..f29de5d
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/common/package.html
@@ -0,0 +1,81 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<html>
+    <body>
+        <h2>Common API.</h2>
+        <p>
+            The Common API package is a collection of really low-level types needed at the core of the Zest™ Runtime. It is also
+            a collection of types that are not particularly cohesive, and effectively this package contains the loose ends
+            that does not belong elsewhere.
+        </p>
+        <p>
+            In this package, you can safely ignore the following classes;
+        </p>
+        <ul>
+            <li>MetaInfo</li>
+            <li>QualifiedName</li>
+            <li>TypeName</li>
+        </ul>
+        <p>UNLESS you are into deep integration into the Zest™ Runtime.</p>
+
+        <h3>&#64;AppliesTo and AppliesToFilter</h3>
+        <p>
+            This tandem of interface + annotation are primarily used for Generic Fragments, to indicate which methods on the
+            interface the fragment should be applied to.
+        </p>
+
+        <h3>&#64;Optional</h3>
+        <p>
+            In Zest™, method arguments, property values and injected fields are not allowed to be null by default. To allow
+            any of these to be null, i.e. undeclared, it is required that the argument, field or method is marked with the
+            &#64;Optional annotation.
+        </p>
+
+        <h3>&#64;UseDefaults</h3>
+        <p>
+            Since null is not allowed without the &#64;Optional annotation, it can sometimes by tedious to initialize all
+            the property values. And the &#64;UseDefaults annotation allows us to declare that Zest™ should set the Property
+            to a default value. These are either the pre-defined ones, or can be set per property declaration during the
+            assembly.
+        </p>
+
+        <h3>&#64;Visibility</h3>
+        <p>
+            Visibility is another innovative concept in Zest™, which leverage the structure system (Application, Layer, Module)
+            to limit the 'reach' when requesting composites and objects. The Visibility is declared per Composite/Object,
+            preferably in the most restrictive mode possible, and the visibility resolver will ensure a predictable resolution
+            algorithm;
+        </p>
+        <ol>
+            <li>Search the module of the caller first. If one and only one composite type fulfilling the request is available
+                return that to the caller. If two or more are found, throw an AmbiguousTypeException. If no composite found
+                continue to the next step.
+            </li>
+            <li>Search all modules in the Layer of the caller for composite that has a declaration other than
+                <code>Visibility.module</code>. If one and only one composite type fulfilling the request is available
+                return that to the caller. If two or more are found, throw an AmbiguousTypeException. If no composite found
+                continue to the next step.
+            </li>
+            <li>Search all modules in the Layer(s) (if any) directly below of the caller for composite that has a declaration of
+                <code>Visibility.application</code>. If one and only one composite type fulfilling the request is available
+                return that to the caller. If two or more are found, throw an AmbiguousTypeException. If no composite found
+                continue to the next step.
+            </li>
+            <li>Throw an NoSuchCompositeException (or related) exception.</li>
+        </ol>
+    </body>
+</html>
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/AmbiguousTypeException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/AmbiguousTypeException.java b/core/api/src/main/java/org/qi4j/api/composite/AmbiguousTypeException.java
new file mode 100644
index 0000000..34f3653
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/AmbiguousTypeException.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2008 Niclas Hedhman. All rights Reserved.
+ *
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License. 
+ */
+package org.qi4j.api.composite;
+
+/**
+ * This Exception is thrown when more than one Composite implements a MixinType
+ * that one tries to use to create a Composite instance from.
+ * <p>
+ * For instance;
+ * </p>
+ * <pre><code>
+ * public interface AbcComposite extends TransientComposite, Abc
+ * {}
+ *
+ * public interface DefComposite extends TransientComposite, Def
+ * {}
+ *
+ * public interface Abc
+ * {}
+ *
+ * public interface Def extends Abc
+ * {}
+ *
+ *
+ * TransientBuilder cb = factory.newTransientBuilder( Abc.class );
+ * </code></pre>
+ * <p>
+ * In the code above, both the AbcComposite and DefComposite implement Abc, and therefore
+ * the <code>newTransientBuilder</code> method can not unambiguously figure out which
+ * one is intended.
+ * </p>
+ */
+public class AmbiguousTypeException
+    extends RuntimeException
+{
+    private static final long serialVersionUID = 1L;
+
+    public AmbiguousTypeException( String message )
+    {
+        super( message );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/Composite.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/Composite.java b/core/api/src/main/java/org/qi4j/api/composite/Composite.java
new file mode 100644
index 0000000..91662fb
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/Composite.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2007, Rickard Öberg. All Rights Reserved.
+ * Copyright (c) 2007, Niclas Hedhman. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.qi4j.api.composite;
+
+import org.qi4j.api.mixin.Mixins;
+import org.qi4j.api.property.PropertyMixin;
+
+/**
+ * Base Composite interface.
+ * <p>
+ * All Composite objects must implement this interface. Let the
+ * Composite interface extend this one. An implementation will be provided
+ * by the framework.
+ * </p>
+ * <p>
+ * Properties and associations are handled by default.
+ * </p>
+ */
+@Mixins( { PropertyMixin.class } )
+public interface Composite
+{
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/CompositeContext.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/CompositeContext.java b/core/api/src/main/java/org/qi4j/api/composite/CompositeContext.java
new file mode 100644
index 0000000..d8a2aa7
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/CompositeContext.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright (c) 2007, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.qi4j.api.composite;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import org.qi4j.api.Qi4j;
+import org.qi4j.api.structure.Module;
+import org.qi4j.functional.Iterables;
+
+import static org.qi4j.functional.Iterables.toArray;
+
+/**
+ * Thread-associated composites. This is basically a ThreadLocal which maintains a reference
+ * to a TransientComposite instance for each thread. This can be used to implement various context
+ * patterns without having to pass the context explicitly as a parameter to methods.
+ */
+public class CompositeContext<T extends TransientComposite>
+    extends ThreadLocal<T>
+{
+    private Module module;
+    private Class<T> type;
+
+    public CompositeContext( Module module, Class<T> type )
+    {
+        this.module = module;
+        this.type = type;
+    }
+
+    @Override
+    protected T initialValue()
+    {
+        return module.newTransient( type );
+    }
+
+    @SuppressWarnings( "unchecked" )
+    public T proxy()
+    {
+        TransientComposite composite = get();
+
+        Iterable<Class<?>> types = Qi4j.FUNCTION_COMPOSITE_INSTANCE_OF.map( composite ).types();
+        return (T) Proxy.newProxyInstance(
+            composite.getClass().getClassLoader(),
+            toArray( Class.class, Iterables.<Class>cast( types ) ),
+            new ContextInvocationhandler() );
+    }
+
+    private class ContextInvocationhandler
+        implements InvocationHandler
+    {
+
+        @Override
+        public Object invoke( Object object, Method method, Object[] objects )
+            throws Throwable
+        {
+            try
+            {
+                return method.invoke( get(), objects );
+            }
+            catch( InvocationTargetException e )
+            {
+                throw e.getTargetException();
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/CompositeDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/CompositeDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/CompositeDescriptor.java
new file mode 100644
index 0000000..40b4462
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/CompositeDescriptor.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2009, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.qi4j.api.composite;
+
+/**
+ * Composite Descriptor.
+ */
+public interface CompositeDescriptor
+    extends ModelDescriptor
+{
+    Class<?> primaryType();
+
+    Iterable<Class<?>> mixinTypes();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/CompositeInstance.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/CompositeInstance.java b/core/api/src/main/java/org/qi4j/api/composite/CompositeInstance.java
new file mode 100644
index 0000000..79f8d62
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/CompositeInstance.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2008, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.qi4j.api.composite;
+
+import java.lang.reflect.InvocationHandler;
+import org.qi4j.api.property.StateHolder;
+import org.qi4j.api.structure.MetaInfoHolder;
+import org.qi4j.api.structure.Module;
+import org.qi4j.api.type.HasTypes;
+
+/**
+ * Composite Instance.
+ */
+public interface CompositeInstance
+    extends InvocationHandler, CompositeInvoker, HasTypes, MetaInfoHolder
+{
+    <T> T proxy();
+
+    <T> T newProxy( Class<T> mixinType )
+        throws IllegalArgumentException;
+
+    Module module();
+
+    CompositeDescriptor descriptor();
+
+    StateHolder state();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/CompositeInvoker.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/CompositeInvoker.java b/core/api/src/main/java/org/qi4j/api/composite/CompositeInvoker.java
new file mode 100644
index 0000000..5bd8d11
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/CompositeInvoker.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) 2010, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.qi4j.api.composite;
+
+import java.lang.reflect.Method;
+
+/**
+ * Composite method invoker.
+ * <p>
+ * All composites must implement this interface. Methods that are invoked
+ * may reside either in the public Composite interface or in any internal mixins.
+ * </p>
+ * <p>
+ * <strong><i>NOTE:</i></strong>Client code should never use method in this class. We have not been able to hide this
+ * from client code, but IF we find a way to do, this interface may disappear.
+ * </p>
+ */
+public interface CompositeInvoker
+{
+
+    Object invokeComposite( Method method, Object[] args )
+        throws Throwable;
+
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/ConstructorDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/ConstructorDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/ConstructorDescriptor.java
new file mode 100644
index 0000000..6e74dd9
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/ConstructorDescriptor.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2008, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.qi4j.api.composite;
+
+import java.lang.reflect.Constructor;
+
+/**
+ * Composite constructor descriptor.
+ */
+public interface ConstructorDescriptor
+{
+    Constructor<?> constructor();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/DecoratorMixin.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/DecoratorMixin.java b/core/api/src/main/java/org/qi4j/api/composite/DecoratorMixin.java
new file mode 100644
index 0000000..6b81844
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/DecoratorMixin.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2009 Niclas Hedhman.
+ *
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.qi4j.api.composite;
+
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import org.qi4j.api.injection.scope.Uses;
+
+/**
+ * Generic decorator mixin that allows a Composite to wrap
+ * any other Composite as long as they share an interface.
+ * <p>
+ * Can be used to effectively implement
+ * singleton mixins, since the decorated object can be shared between
+ * many instances.
+ * </p>
+ */
+public class DecoratorMixin
+    implements InvocationHandler
+{
+    private Object delegate;
+
+    public DecoratorMixin( @Uses Object delegate )
+    {
+        if( delegate instanceof Class )
+        {
+            Thread.dumpStack();
+        }
+        this.delegate = delegate;
+    }
+
+    @Override
+    public Object invoke( Object object, Method method, Object[] args )
+        throws Throwable
+    {
+        if( delegate instanceof InvocationHandler )
+        {
+            InvocationHandler handler = (InvocationHandler) delegate;
+            return handler.invoke( object, method, args );
+        }
+        else
+        {
+            try
+            {
+                return method.invoke( delegate, args );
+            }
+            catch( InvocationTargetException e )
+            {
+                throw e.getCause();
+            }
+            catch( IllegalArgumentException e )
+            {
+                String message = constructMessage( method, args );
+                throw new IllegalArgumentException( message, e );
+            }
+        }
+    }
+
+    private String constructMessage( Method method, Object[] args )
+    {
+        StringBuilder builder = new StringBuilder();
+        builder.append( "\nmethod: " );
+        builder.append( method.getDeclaringClass().getName() );
+        builder.append( "." );
+        builder.append( method.getName() );
+        builder.append( "\ndelegate: " );
+        builder.append( delegate );
+        builder.append( "\ndelegateType: " );
+        builder.append( delegate == null ? "n/a" : delegate.getClass().getName() );
+        builder.append( "\narguments: \n" );
+        for( Object arg : args )
+        {
+            builder.append( "    " );
+            Class argClass = arg.getClass();
+            if( Proxy.isProxyClass( argClass ) )
+            {
+                builder.append( Proxy.getInvocationHandler( arg ).getClass().getName() );
+            }
+            else
+            {
+                builder.append( argClass.getName() );
+            }
+            builder.append( '\n' );
+        }
+        return builder.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/DependencyDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/DependencyDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/DependencyDescriptor.java
new file mode 100644
index 0000000..70d7d06
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/DependencyDescriptor.java
@@ -0,0 +1,38 @@
+/*  Copyright 2008 Edward Yakop.
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+* implied.
+*
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*/
+package org.qi4j.api.composite;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+/**
+ * Composite dependency descriptor.
+ */
+public interface DependencyDescriptor
+{
+    Annotation injectionAnnotation();
+
+    Type injectionType();
+
+    Class<?> injectedClass();
+
+    Class<?> rawInjectionType();
+
+    boolean optional();
+
+    Annotation[] annotations();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/InjectedFieldDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/InjectedFieldDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/InjectedFieldDescriptor.java
new file mode 100644
index 0000000..2f7297e
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/InjectedFieldDescriptor.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright (c) 2008, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.qi4j.api.composite;
+
+import java.lang.reflect.Field;
+
+/**
+ * Composite injected field descriptor.
+ */
+public interface InjectedFieldDescriptor
+{
+    Field field();
+
+    DependencyDescriptor dependency();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/InjectedMethodDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/InjectedMethodDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/InjectedMethodDescriptor.java
new file mode 100644
index 0000000..8888d32
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/InjectedMethodDescriptor.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2008, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.qi4j.api.composite;
+
+import java.lang.reflect.Method;
+
+/**
+ * Composite injected method descriptor.
+ */
+public interface InjectedMethodDescriptor
+{
+    Method method();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/InjectedParametersDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/InjectedParametersDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/InjectedParametersDescriptor.java
new file mode 100644
index 0000000..301c56d
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/InjectedParametersDescriptor.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2008, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.qi4j.api.composite;
+
+/**
+ * Composite constructors and method injected parameters descriptor.
+ */
+public interface InjectedParametersDescriptor
+{
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/InvalidCompositeException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/InvalidCompositeException.java b/core/api/src/main/java/org/qi4j/api/composite/InvalidCompositeException.java
new file mode 100644
index 0000000..e5b86c0
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/InvalidCompositeException.java
@@ -0,0 +1,29 @@
+/*  Copyright 2007 Niclas Hedhman.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.qi4j.api.composite;
+
+/**
+ * This exception is thrown if a Composite is invalid.
+ */
+public class InvalidCompositeException
+    extends RuntimeException
+{
+    public InvalidCompositeException( String message )
+    {
+        super( message );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/InvalidValueCompositeException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/InvalidValueCompositeException.java b/core/api/src/main/java/org/qi4j/api/composite/InvalidValueCompositeException.java
new file mode 100644
index 0000000..60a48dd
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/InvalidValueCompositeException.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2009 Niclas Hedhman.
+ *
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.qi4j.api.composite;
+
+/**
+ * This exception is thrown if a ValueComposite is invalid.
+ */
+public class InvalidValueCompositeException
+    extends RuntimeException
+{
+    public InvalidValueCompositeException( String message )
+    {
+        super( message );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/MethodDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/MethodDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/MethodDescriptor.java
new file mode 100644
index 0000000..2f88f35
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/MethodDescriptor.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2008, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.qi4j.api.composite;
+
+import java.lang.reflect.Method;
+
+/**
+ * Composite Method Descriptor.
+ */
+public interface MethodDescriptor
+{
+    Method method();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/MissingMethodException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/MissingMethodException.java b/core/api/src/main/java/org/qi4j/api/composite/MissingMethodException.java
new file mode 100644
index 0000000..ae362cb
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/MissingMethodException.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2009 Niclas Hedhman.
+ *
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.qi4j.api.composite;
+
+/**
+ * This exception is thrown if client code tries to invoke a non-existing Composite method.
+ */
+public class MissingMethodException
+    extends RuntimeException
+{
+    public MissingMethodException( String message )
+    {
+        super( message );
+    }
+
+    public MissingMethodException( String message, NoSuchMethodException e )
+    {
+        super(message,e);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/ModelDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/ModelDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/ModelDescriptor.java
new file mode 100644
index 0000000..b0651f0
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/ModelDescriptor.java
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.qi4j.api.composite;
+
+import org.qi4j.api.common.Visibility;
+import org.qi4j.api.structure.MetaInfoHolder;
+import org.qi4j.api.type.HasTypes;
+
+/**
+ * Composite ModelDescriptor.
+ */
+public interface ModelDescriptor extends HasTypes, MetaInfoHolder
+{
+    Visibility visibility();
+
+    boolean isAssignableTo( Class<?> type );
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/NoSuchCompositeException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/NoSuchCompositeException.java b/core/api/src/main/java/org/qi4j/api/composite/NoSuchCompositeException.java
new file mode 100644
index 0000000..b404779
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/NoSuchCompositeException.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2008, Niclas Hedhman. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.qi4j.api.composite;
+
+import org.qi4j.api.common.InvalidApplicationException;
+
+/**
+ * This exception is thrown if client code tries to create a non-existing Composite type.
+ */
+public class NoSuchCompositeException
+    extends InvalidApplicationException
+{
+    private static final long serialVersionUID = 1L;
+
+    private final String compositeType;
+    private final String moduleName;
+
+    protected NoSuchCompositeException( String metaType, String compositeType, String moduleName )
+    {
+        super( "Could not find any visible " + metaType + " of type [" + compositeType + "] in module [" +
+               moduleName + "]." );
+        this.compositeType = compositeType;
+        this.moduleName = moduleName;
+    }
+
+    public String compositeType()
+    {
+        return compositeType;
+    }
+
+    public String moduleName()
+    {
+        return moduleName;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/NoSuchTransientException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/NoSuchTransientException.java b/core/api/src/main/java/org/qi4j/api/composite/NoSuchTransientException.java
new file mode 100644
index 0000000..e6a6f61
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/NoSuchTransientException.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2012, Niclas Hedhman. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ *
+ *     You may obtain a copy of the License at
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.qi4j.api.composite;
+
+/**
+ * This exception is thrown if client code tries to create a non-existing TransientComposite type.
+ */
+public class NoSuchTransientException extends NoSuchCompositeException
+{
+    public NoSuchTransientException( String typeName, String moduleName )
+    {
+        super( "TransientComposite", typeName, moduleName );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/PropertyMapper.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/PropertyMapper.java b/core/api/src/main/java/org/qi4j/api/composite/PropertyMapper.java
new file mode 100644
index 0000000..054a369
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/PropertyMapper.java
@@ -0,0 +1,580 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.qi4j.api.composite;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.lang.reflect.Array;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Set;
+import org.qi4j.api.Qi4j;
+import org.qi4j.api.property.GenericPropertyInfo;
+import org.qi4j.api.property.Property;
+import org.qi4j.api.util.Classes;
+import org.qi4j.api.util.Dates;
+import org.qi4j.api.value.ValueComposite;
+
+/**
+ * Transfer java.util.Properties to Composite properties
+ */
+public final class PropertyMapper
+{
+
+    private final static Map<Type, MappingStrategy> STRATEGY;
+
+    static
+    {
+        STRATEGY = new HashMap<>();
+        STRATEGY.put( Integer.class, new IntegerMapper() );
+        STRATEGY.put( Long.class, new LongMapper() );
+        STRATEGY.put( Short.class, new ShortMapper() );
+        STRATEGY.put( Byte.class, new ByteMapper() );
+        STRATEGY.put( String.class, new StringMapper() );
+        STRATEGY.put( Character.class, new CharMapper() );
+        STRATEGY.put( Float.class, new FloatMapper() );
+        STRATEGY.put( Double.class, new DoubleMapper() );
+        STRATEGY.put( Date.class, new DateMapper() );
+        STRATEGY.put( Boolean.class, new BooleanMapper() );
+        STRATEGY.put( BigDecimal.class, new BigDecimalMapper() );
+        STRATEGY.put( BigInteger.class, new BigIntegerMapper() );
+        STRATEGY.put( Enum.class, new EnumMapper() );
+        STRATEGY.put( Array.class, new ArrayMapper() );
+        STRATEGY.put( Map.class, new MapMapper() );
+        STRATEGY.put( List.class, new ListMapper() );
+        STRATEGY.put( Set.class, new SetMapper() );
+        STRATEGY.put( ValueComposite.class, new ValueCompositeMapper() );
+    }
+
+    /**
+     * Populate the Composite with properties from the given properties object.
+     *
+     * @param props     properties object
+     * @param composite the composite instance
+     *
+     * @throws IllegalArgumentException if properties could not be transferred to composite
+     */
+    public static void map( Properties props, Composite composite )
+        throws IllegalArgumentException
+    {
+        for( Map.Entry<Object, Object> objectObjectEntry : props.entrySet() )
+        {
+            try
+            {
+                String methodName = objectObjectEntry.getKey().toString();
+                Method propertyMethod = composite.getClass().getInterfaces()[ 0 ].getMethod( methodName );
+                propertyMethod.setAccessible( true );
+                Object value = objectObjectEntry.getValue();
+                Type propertyType = GenericPropertyInfo.propertyTypeOf( propertyMethod );
+
+                value = mapToType( composite, propertyType, value.toString() );
+
+                @SuppressWarnings( "unchecked" )
+                Property<Object> property = (Property<Object>) propertyMethod.invoke( composite );
+                property.set( value );
+            }
+            catch( NoSuchMethodException e )
+            {
+                throw new IllegalArgumentException( "Could not find any property named " + objectObjectEntry.getKey() );
+            }
+            catch( IllegalAccessException e )
+            {
+                //noinspection ThrowableInstanceNeverThrown
+                throw new IllegalArgumentException( "Could not populate property named " + objectObjectEntry.getKey(), e );
+            }
+            catch( InvocationTargetException e )
+            {
+                //noinspection ThrowableInstanceNeverThrown
+                String message = "Could not populate property named " + objectObjectEntry.getKey();
+                throw new IllegalArgumentException( message, e );
+            }
+        }
+    }
+
+    @SuppressWarnings( "raw" )
+    private static Object mapToType( Composite composite, Type propertyType, Object value )
+    {
+        final String stringValue = value.toString();
+        MappingStrategy strategy;
+        if( propertyType instanceof Class )
+        {
+            Class type = (Class) propertyType;
+            if( type.isArray() )
+            {
+                strategy = STRATEGY.get( Array.class );
+            }
+            else if( Enum.class.isAssignableFrom( Classes.RAW_CLASS.map( propertyType ) ) )
+            {
+                strategy = STRATEGY.get( Enum.class );
+            }
+            else
+            {
+                strategy = STRATEGY.get( type );
+            }
+            if( strategy == null  ) // If null, try with the ValueComposite Mapper...
+            {
+                strategy = STRATEGY.get( ValueComposite.class );
+            }
+        }
+        else if( propertyType instanceof ParameterizedType )
+        {
+            ParameterizedType type = ( (ParameterizedType) propertyType );
+
+            if( type.getRawType() instanceof Class )
+            {
+                Class clazz = (Class) type.getRawType();
+                if( List.class.isAssignableFrom( clazz ) )
+                {
+                    strategy = STRATEGY.get( List.class );
+                }
+                else if( Set.class.isAssignableFrom( clazz ) )
+                {
+                    strategy = STRATEGY.get( Set.class );
+                }
+                else if( Map.class.isAssignableFrom( clazz ) )
+                {
+                    strategy = STRATEGY.get( Map.class );
+                }
+                else
+                {
+                    throw new IllegalArgumentException( propertyType + " is not supported." );
+                }
+            }
+            else
+            {
+                throw new IllegalArgumentException( propertyType + " is not supported." );
+            }
+        }
+        else
+        {
+            throw new IllegalArgumentException( propertyType + " is not supported." );
+        }
+
+        if( strategy == null )
+        {
+            throw new IllegalArgumentException( propertyType + " is not supported." );
+        }
+
+        return strategy.map( composite, propertyType, stringValue );
+    }
+
+    /**
+     * Load a Properties object from the given stream, close it, and then populate
+     * the Composite with the properties.
+     *
+     * @param propertyInputStream properties input stream
+     * @param composite           the instance
+     *
+     * @throws IOException if the stream could not be read
+     */
+
+    public static void map( InputStream propertyInputStream, Composite composite )
+        throws IOException
+    {
+        if( propertyInputStream != null )
+        {
+            Properties configProps = new Properties();
+            try
+            {
+                configProps.load( propertyInputStream );
+            }
+            finally
+            {
+                propertyInputStream.close();
+            }
+            map( configProps, composite );
+        }
+    }
+
+    /**
+     * Create Properties object which is backed by the given Composite.
+     *
+     * @param composite the instance
+     *
+     * @return properties instance
+     */
+    public static Properties toJavaProperties( final Composite composite )
+    {
+        return new Properties()
+        {
+            private static final long serialVersionUID = 3550125427530538865L;
+
+            @Override
+            public Object get( Object o )
+            {
+                try
+                {
+                    Method propertyMethod = composite.getClass().getMethod( o.toString() );
+                    Property<?> property = (Property<?>) propertyMethod.invoke( composite );
+                    return property.get();
+                }
+                catch( NoSuchMethodException | IllegalAccessException | InvocationTargetException e )
+                {
+                    return null;
+                }
+            }
+
+            @Override
+            public Object put( Object o, Object o1 )
+            {
+                Object oldValue = get( o );
+
+                try
+                {
+                    Method propertyMethod = composite.getClass().getMethod( o.toString(), Object.class );
+                    propertyMethod.invoke( composite, o1 );
+                }
+                catch( NoSuchMethodException | IllegalAccessException | InvocationTargetException e )
+                {
+                    e.printStackTrace();
+                }
+
+                return oldValue;
+            }
+        };
+    }
+
+    private static void tokenize( String valueString, boolean mapSyntax, TokenizerCallback callback )
+    {
+        char[] data = valueString.toCharArray();
+
+        int oldPos = 0;
+        for( int pos = 0; pos < data.length; pos++ )
+        {
+            char ch = data[ pos ];
+            if( ch == '\"' )
+            {
+                pos = resolveQuotes( valueString, callback, data, pos, '\"' );
+                oldPos = pos;
+            }
+            if( ch == '\'' )
+            {
+                pos = resolveQuotes( valueString, callback, data, pos, '\'' );
+                oldPos = pos;
+            }
+            if( ch == ',' || ( mapSyntax && ch == ':' ) )
+            {
+                String token = new String( data, oldPos, pos - oldPos );
+                callback.token( token );
+                oldPos = pos + 1;
+            }
+        }
+        String token = new String( data, oldPos, data.length - oldPos );
+        callback.token( token );
+    }
+
+    private static int resolveQuotes( String valueString,
+                                      TokenizerCallback callback,
+                                      char[] data,
+                                      int pos, char quote
+    )
+    {
+        boolean found = false;
+        for( int j = pos + 1; j < data.length; j++ )
+        {
+            if( !found )
+            {
+                if( data[ j ] == quote )
+                {
+                    String token = new String( data, pos + 1, j - pos - 1 );
+                    callback.token( token );
+                    found = true;
+                }
+            }
+            else
+            {
+                if( data[ j ] == ',' )
+                {
+                    return j + 1;
+                }
+            }
+        }
+        if( !found )
+        {
+            throw new IllegalArgumentException( "String is not quoted correctly: " + valueString );
+        }
+        return data.length;
+    }
+
+    private interface TokenizerCallback
+    {
+        void token( String token );
+    }
+
+    private interface MappingStrategy
+    {
+        Object map( Composite composite, Type type, String value );
+    }
+
+    private static class StringMapper
+        implements MappingStrategy
+    {
+        @Override
+        public Object map( Composite composite, Type type, String value )
+        {
+            return value;
+        }
+    }
+
+    private static class IntegerMapper
+        implements MappingStrategy
+    {
+        @Override
+        public Object map( Composite composite, Type type, String value )
+        {
+            return new Integer( value.trim() );
+        }
+    }
+
+    private static class FloatMapper
+        implements MappingStrategy
+    {
+        @Override
+        public Object map( Composite composite, Type type, String value )
+        {
+            return new Float( value.trim() );
+        }
+    }
+
+    private static class DoubleMapper
+        implements MappingStrategy
+    {
+        @Override
+        public Object map( Composite composite, Type type, String value )
+        {
+            return new Double( value.trim() );
+        }
+    }
+
+    private static class LongMapper
+        implements MappingStrategy
+    {
+        @Override
+        public Object map( Composite composite, Type type, String value )
+        {
+            return new Long( value.trim() );
+        }
+    }
+
+    private static class ShortMapper
+        implements MappingStrategy
+    {
+        @Override
+        public Object map( Composite composite, Type type, String value )
+        {
+            return new Short( value.trim() );
+        }
+    }
+
+    private static class ByteMapper
+        implements MappingStrategy
+    {
+        @Override
+        public Object map( Composite composite, Type type, String value )
+        {
+            return new Byte( value.trim() );
+        }
+    }
+
+    private static class CharMapper
+        implements MappingStrategy
+    {
+        @Override
+        public Object map( Composite composite, Type type, String value )
+        {
+            return value.trim().charAt( 0 );
+        }
+    }
+
+    private static class BigDecimalMapper
+        implements MappingStrategy
+    {
+        @Override
+        public Object map( Composite composite, Type type, String value )
+        {
+            return new BigDecimal( value.trim() );
+        }
+    }
+
+    private static class BigIntegerMapper
+        implements MappingStrategy
+    {
+        @Override
+        public Object map( Composite composite, Type type, String value )
+        {
+            return new BigInteger( value.trim() );
+        }
+    }
+
+    private static class EnumMapper
+        implements MappingStrategy
+    {
+        @Override
+        @SuppressWarnings( "unchecked" )
+        public Object map( Composite composite, Type type, String value )
+        {
+            return Enum.valueOf( (Class<Enum>) type, value );
+        }
+    }
+
+    private static class DateMapper
+        implements MappingStrategy
+    {
+        @Override
+        public Object map( Composite composite, Type type, String value )
+        {
+            return Dates.fromString( value.trim() );
+        }
+    }
+
+    private static class ValueCompositeMapper
+        implements MappingStrategy
+    {
+        @Override
+        @SuppressWarnings( "unchecked" )
+        public Object map( Composite composite, Type type, String value )
+        {
+            return Qi4j.FUNCTION_COMPOSITE_INSTANCE_OF.map( composite ).module().newValueFromSerializedState( (Class<Object>) type, value );
+        }
+    }
+
+    private static class ArrayMapper
+        implements MappingStrategy
+    {
+        @Override
+        @SuppressWarnings( {"raw", "unchecked"} )
+        public Object map( final Composite composite, Type type, String value )
+        {
+            final Class arrayType = ( (Class) type ).getComponentType();
+            final ArrayList result = new ArrayList();
+            tokenize( value, false, new TokenizerCallback()
+            {
+                @Override
+                public void token( String token )
+                {
+                    result.add( mapToType( composite, arrayType, token ) );
+                }
+            } );
+            return result.toArray( (Object[]) Array.newInstance( arrayType, result.size() ) );
+        }
+    }
+
+    private static class BooleanMapper
+        implements MappingStrategy
+    {
+        @Override
+        public Object map( final Composite composite, Type type, String value )
+        {
+            return Boolean.valueOf( value.trim() );
+        }
+    }
+
+    private static class ListMapper
+        implements MappingStrategy
+    {
+        @Override
+        @SuppressWarnings( {"raw", "unchecked"} )
+        public Object map( final Composite composite, Type type, String value )
+        {
+            final Type dataType = ( (ParameterizedType) type ).getActualTypeArguments()[ 0 ];
+            final Collection result = new ArrayList();
+            tokenize( value, false, new TokenizerCallback()
+            {
+                @Override
+                public void token( String token )
+                {
+                    result.add( mapToType( composite, dataType, token ) );
+                }
+            } );
+            return result;
+        }
+    }
+
+    private static class SetMapper
+        implements MappingStrategy
+    {
+        @Override
+        @SuppressWarnings( {"raw", "unchecked"} )
+        public Object map( final Composite composite, Type type, String value )
+        {
+            final Type dataType = ( (ParameterizedType) type ).getActualTypeArguments()[ 0 ];
+            final Collection result = new HashSet();
+            tokenize( value, false, new TokenizerCallback()
+            {
+                @Override
+                public void token( String token )
+                {
+                    result.add( mapToType( composite, dataType, token ) );
+                }
+            } );
+            return result;
+        }
+    }
+
+    private static class MapMapper
+        implements MappingStrategy
+    {
+        @Override
+        @SuppressWarnings( {"raw", "unchecked"} )
+        public Object map( final Composite composite, Type generictype, String value )
+        {
+            ParameterizedType type = (ParameterizedType) generictype;
+            final Type keyType = type.getActualTypeArguments()[ 0 ];
+            final Type valueType = type.getActualTypeArguments()[ 0 ];
+            final Map result = new HashMap();
+            tokenize( value, true, new TokenizerCallback()
+            {
+                boolean keyArrivingNext = true;
+                String key;
+
+                @Override
+                public void token( String token )
+                {
+                    if( keyArrivingNext )
+                    {
+                        key = token;
+                        keyArrivingNext = false;
+                    }
+                    else
+                    {
+                        result.put( mapToType( composite, keyType, key ), mapToType( composite, valueType, token ) );
+                        keyArrivingNext = true;
+                    }
+                }
+            } );
+            return result;
+        }
+    }
+
+    private PropertyMapper()
+    {
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/StateDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/StateDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/StateDescriptor.java
new file mode 100644
index 0000000..3eebcd4
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/StateDescriptor.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2008, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.qi4j.api.composite;
+
+import org.qi4j.api.common.QualifiedName;
+import org.qi4j.api.property.PropertyDescriptor;
+
+/**
+ * Composite State Descriptor.
+ */
+public interface StateDescriptor
+{
+    PropertyDescriptor findPropertyModelByName( String name )
+        throws IllegalArgumentException;
+
+    PropertyDescriptor findPropertyModelByQualifiedName( QualifiedName name )
+        throws IllegalArgumentException;
+
+    Iterable<? extends PropertyDescriptor> properties();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/StatefulCompositeDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/StatefulCompositeDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/StatefulCompositeDescriptor.java
new file mode 100644
index 0000000..ba44494
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/StatefulCompositeDescriptor.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.qi4j.api.composite;
+
+/**
+ * Stateful Composite Descriptor.
+ */
+public interface StatefulCompositeDescriptor
+{
+    StateDescriptor state();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/TransientBuilder.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/TransientBuilder.java b/core/api/src/main/java/org/qi4j/api/composite/TransientBuilder.java
new file mode 100644
index 0000000..58b4ef6
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/TransientBuilder.java
@@ -0,0 +1,68 @@
+/*  Copyright 2007 Niclas Hedhman.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *  
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * 
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.qi4j.api.composite;
+
+import org.qi4j.api.common.ConstructionException;
+
+/**
+ * TransientBuilders are used to instantiate TransientComposites. They can be acquired from
+ * {@link TransientBuilderFactory#newTransientBuilder(Class)} and allows the client
+ * to provide additional settings before instantiating the TransientComposite.
+ */
+public interface TransientBuilder<T>
+{
+    /**
+     * Provide objects that can be injected into mixins that has the @Uses
+     * dependency injection annotation.
+     *
+     * @param usedObjects The objects that can be injected into mixins.
+     *
+     * @return the transient builder instance
+     *
+     * @see org.qi4j.api.injection.scope.Uses
+     */
+    TransientBuilder<T> use( Object... usedObjects );
+
+    /**
+     * Get a representation of the state for the new Composite.
+     * It is possible to access and update properties and associations,
+     * even immutable ones since the builder represents the initial state.
+     *
+     * @return a proxy implementing the Composite type
+     */
+    T prototype();
+
+    /**
+     * Get a representation of the state of the given type for the new Composite.
+     * This is primarily used if you want to provide state for a private mixin type.
+     *
+     * @param mixinType the mixin which you want to provide state for
+     *
+     * @return a proxy implementing the given mixin type
+     */
+    <K> K prototypeFor( Class<K> mixinType );
+
+    /**
+     * Create a new Composite instance.
+     *
+     * @return a new Composite instance
+     *
+     * @throws ConstructionException thrown if it was not possible to instantiate the Composite
+     */
+    T newInstance()
+        throws ConstructionException;
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/TransientBuilderFactory.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/TransientBuilderFactory.java b/core/api/src/main/java/org/qi4j/api/composite/TransientBuilderFactory.java
new file mode 100644
index 0000000..b06c58f
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/TransientBuilderFactory.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2007, Rickard Öberg. All Rights Reserved.
+ * Copyright (c) 2007, Niclas Hedhman. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+package org.qi4j.api.composite;
+
+import org.qi4j.api.common.ConstructionException;
+
+/**
+ * This factory creates TransientComposites and the TransientBuilders.
+ *
+ * TransientComposite instances are very flexible in what it can reference, but are restricted in where they
+ * can be used. So, TransientComposites are mainly recommended where Values, Entities and Services can not be used,
+ * but they can also not be used to store state, be serialized across a network or have automatic equals/hashCode
+ * calculations.
+ */
+public interface TransientBuilderFactory
+{
+    /**
+     * Create a builder for creating new TransientComposites that implements the given TransientComposite type.
+     *
+     * @param mixinType an interface that describes the TransientComposite to be instantiated
+     *
+     * @return a TransientBuilder for creation of TransientComposites implementing the interface
+     *
+     * @throws NoSuchTransientException if no composite extending the mixinType has been registered
+     */
+    <T> TransientBuilder<T> newTransientBuilder( Class<T> mixinType )
+        throws NoSuchTransientException;
+
+    /**
+     * Instantiate a TransientComposite of the given type.
+     *
+     * @param mixinType the TransientComposite type to instantiate
+     *
+     * @return a new TransientComposite instance
+     *
+     * @throws NoSuchTransientException if no composite extending the mixinType has been registered
+     * @throws org.qi4j.api.common.ConstructionException
+     *                                  if the composite could not be instantiated
+     */
+    <T> T newTransient( Class<T> mixinType, Object... uses )
+        throws NoSuchTransientException, ConstructionException;
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/TransientComposite.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/TransientComposite.java b/core/api/src/main/java/org/qi4j/api/composite/TransientComposite.java
new file mode 100644
index 0000000..8b21e88
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/TransientComposite.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2009 Niclas Hedhman.
+ *
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.qi4j.api.composite;
+
+/**
+ * Transient Composite Type.
+ *
+ * TransientComposites have the following criteria;
+ * <ul>
+ * <li>Does not persist its state, and is not serializable</li>
+ * <li>Can not be referenced from Properties, Associations, ValueComposites nor Entities</li>
+ * <li>Can reference all types</li>
+ * <li>No lifecycle</li>
+ * <li>equals/hashCode is delegated to a single Mixin implementing the methods, like any other method</li>
+ * </ul>
+ */
+public interface TransientComposite
+    extends Composite
+{
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/TransientDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/TransientDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/TransientDescriptor.java
new file mode 100644
index 0000000..0df706c
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/TransientDescriptor.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright (c) 2008, Rickard Öberg. All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package org.qi4j.api.composite;
+
+/**
+ * TransientComposite Descriptor.
+ */
+public interface TransientDescriptor
+    extends CompositeDescriptor, StatefulCompositeDescriptor
+{
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/package.html
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/composite/package.html b/core/api/src/main/java/org/qi4j/api/composite/package.html
new file mode 100644
index 0000000..00feaed
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/composite/package.html
@@ -0,0 +1,21 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one or more
+contributor license agreements.  See the NOTICE file distributed with
+this work for additional information regarding copyright ownership.
+The ASF licenses this file to You under the Apache License, Version 2.0
+(the "License"); you may not use this file except in compliance with
+the License.  You may obtain a copy of the License at
+
+http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+-->
+<html>
+    <body>
+        <h2>Composite API.</h2>
+    </body>
+</html>


Mime
View raw message