polygene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nic...@apache.org
Subject [38/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:57 GMT
http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/concern/ConcernDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/concern/ConcernDescriptor.java b/core/api/src/main/java/org/qi4j/api/concern/ConcernDescriptor.java
new file mode 100644
index 0000000..a98adf7
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/concern/ConcernDescriptor.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.concern;
+
+/**
+ * Concern descriptor.
+ */
+public interface ConcernDescriptor
+{
+    Class modifierClass();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/concern/ConcernOf.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/concern/ConcernOf.java b/core/api/src/main/java/org/qi4j/api/concern/ConcernOf.java
new file mode 100644
index 0000000..33cdd01
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/concern/ConcernOf.java
@@ -0,0 +1,44 @@
+/*
+ * 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.concern;
+
+import org.qi4j.api.concern.internal.ConcernFor;
+
+/**
+ * Base class for Concerns. It introduces a typed "next" pointer
+ * that Concerns can use to invoke the next Concern (or mixin) in
+ * the chain.
+ * <p>
+ * Generic Concerns should subclass {@link GenericConcern} instead.
+ * </p>
+ * <p>
+ * Concerns implementations must be thread-safe in their implementation,
+ * as multiple threads may share instances.
+ * </p>
+ */
+public abstract class ConcernOf<T>
+{
+    /**
+     * The "next" pointer. This points to
+     * the next concern in the chain or the mixin
+     * to be invoked.
+     */
+    final
+    @ConcernFor
+    protected T next = null;
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/concern/Concerns.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/concern/Concerns.java b/core/api/src/main/java/org/qi4j/api/concern/Concerns.java
new file mode 100644
index 0000000..9213035
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/concern/Concerns.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.concern;
+
+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;
+
+/**
+ * This annotation is used by composites and mixins to declare what Concerns
+ * should be applied to the type or specific method.
+ */
+@Retention( RetentionPolicy.RUNTIME )
+@Target( { ElementType.TYPE, ElementType.METHOD } )
+@Documented
+public @interface Concerns
+{
+    Class<?>[] value();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/concern/ConcernsDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/concern/ConcernsDescriptor.java b/core/api/src/main/java/org/qi4j/api/concern/ConcernsDescriptor.java
new file mode 100644
index 0000000..dd9a91b
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/concern/ConcernsDescriptor.java
@@ -0,0 +1,24 @@
+/*  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.concern;
+
+/**
+ * Concerns descriptor.
+ */
+public interface ConcernsDescriptor
+{
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/concern/GenericConcern.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/concern/GenericConcern.java b/core/api/src/main/java/org/qi4j/api/concern/GenericConcern.java
new file mode 100644
index 0000000..2986ff8
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/concern/GenericConcern.java
@@ -0,0 +1,32 @@
+/*
+ * 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.concern;
+
+import java.lang.reflect.InvocationHandler;
+
+/**
+ * Base class for generic Concerns. Subclass
+ * and implement the "invoke" method. Use the
+ * "next" field in {@link ConcernOf} to continue the invocation
+ * chain.
+ */
+public abstract class GenericConcern
+    extends ConcernOf<InvocationHandler>
+    implements InvocationHandler
+{
+}
\ 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/concern/internal/ConcernFor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/concern/internal/ConcernFor.java b/core/api/src/main/java/org/qi4j/api/concern/internal/ConcernFor.java
new file mode 100644
index 0000000..de3e1b4
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/concern/internal/ConcernFor.java
@@ -0,0 +1,62 @@
+/*
+ * 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.concern.internal;
+
+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;
+import org.qi4j.api.injection.InjectionScope;
+
+/**
+ * This annotation is required once in each Concern, to mark the
+ * field where the next element in the call sequence should be
+ * injected.
+ * <p>
+ * The type of the field must be of the same type as the Concern
+ * itself, or an InvocationHandler.
+ * </p>
+ * <p>
+ * Example;
+ * </p>
+ * <pre><code>
+ * public interface MyStuff
+ * {
+ *     void doSomething();
+ * }
+ *
+ * public class MyStuffConcern
+ *     implements MyStuff
+ * {
+ *     &#64;ConcernFor MyStuff next;
+ *
+ *     public void doSomething()
+ *     {
+ *         // HERE DO THE MODIFIER STUFF.
+ *
+ *         // Delegate to the underlying mixin/modifier.
+ *         next.doSomething();
+ *     }
+ * }
+ * </code></pre>
+ */
+@Retention( RetentionPolicy.RUNTIME )
+@Target( { ElementType.FIELD, ElementType.PARAMETER } )
+@Documented
+@InjectionScope
+public @interface ConcernFor
+{
+}
\ 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/concern/internal/package.html
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/concern/internal/package.html b/core/api/src/main/java/org/qi4j/api/concern/internal/package.html
new file mode 100644
index 0000000..9351f10
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/concern/internal/package.html
@@ -0,0 +1,25 @@
+<!--
+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>
+        <h1>Internal/Private package for the Concern API.</h1>
+        <p>
+            This is an internal package, and no classes in this package is part of the API and compatibility
+            with these classes will not be attempted.
+        </p>
+    </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/concern/package.html
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/concern/package.html b/core/api/src/main/java/org/qi4j/api/concern/package.html
new file mode 100644
index 0000000..fcc7ef7
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/concern/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>Concern API.</h2>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/configuration/Configuration.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/configuration/Configuration.java b/core/api/src/main/java/org/qi4j/api/configuration/Configuration.java
new file mode 100644
index 0000000..77c373d
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/configuration/Configuration.java
@@ -0,0 +1,396 @@
+/*
+ * Copyright (c) 2008, Rickard Öberg. All Rights Reserved.
+ * Copyright (c) 2012, Paul Merlin.
+ *
+ * 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.configuration;
+
+import java.io.IOException;
+import java.io.InputStream;
+import org.qi4j.api.Qi4j;
+import org.qi4j.api.composite.Composite;
+import org.qi4j.api.composite.PropertyMapper;
+import org.qi4j.api.constraint.ConstraintViolationException;
+import org.qi4j.api.entity.EntityBuilder;
+import org.qi4j.api.entity.Identity;
+import org.qi4j.api.injection.scope.Service;
+import org.qi4j.api.injection.scope.Structure;
+import org.qi4j.api.injection.scope.This;
+import org.qi4j.api.mixin.Mixins;
+import org.qi4j.api.service.ServiceComposite;
+import org.qi4j.api.service.ServiceDescriptor;
+import org.qi4j.api.service.ServiceReference;
+import org.qi4j.api.service.qualifier.ServiceTags;
+import org.qi4j.api.structure.Module;
+import org.qi4j.api.unitofwork.EntityTypeNotFoundException;
+import org.qi4j.api.unitofwork.NoSuchEntityException;
+import org.qi4j.api.unitofwork.UnitOfWork;
+import org.qi4j.api.unitofwork.UnitOfWorkCompletionException;
+import org.qi4j.api.usecase.Usecase;
+import org.qi4j.api.usecase.UsecaseBuilder;
+import org.qi4j.api.value.ValueSerialization;
+
+import static org.qi4j.functional.Iterables.first;
+
+/**
+ * Provide Configurations for Services. A Service that wants to be configurable
+ * should inject a reference to Configuration with the Configuration type:
+ * <pre><code>
+ *  * &#64;This Configuration&#60;MyServiceConfiguration&#62; config;
+ * </code></pre>
+ * <p>
+ * where MyServiceConfiguration extends {@link ConfigurationComposite}, which itself is an ordinary
+ * {@link org.qi4j.api.entity.EntityComposite}. The Configuration implementation
+ * will either locate an instance of the given Configuration type in the
+ * persistent store using the identity of the Service, or create a new such instance
+ * if one doesn't already exist.
+ * </p>
+ * <p>
+ * If a new Configuration instance is created then it will be populated with properties
+ * from the properties file whose filesystem name is the same as the identity (e.g. "MyService.properties").
+ * If a service is not given a name via the {@code org.qi4j.bootstrap.ServiceDeclaration#identifiedBy(String)}, the
+ * name will default to the FQCN of the ServiceComposite type.
+ * </p>
+ * <p>
+ * The Configuration instance can be modified externally just like any other EntityComposite, but
+ * its values will not be updated in the Service until {@link #refresh()} is called. This allows
+ * safe reloads of Configuration state to ensure that it is not reloaded while the Service is handling
+ * a request.
+ * </p>
+ * <p>
+ * The Configuration will be automatically refreshed when the Service is activated by the Zest runtime.
+ * Any refreshes at other points will have to be done manually or triggered through some other
+ * mechanism.
+ * </p>
+ * <p>
+ * The user configuration entity is part of a long running {@link UnitOfWork}, and to persist changes to it the
+ * {@link #save()} method must be called. No other actions are required. Example;
+ * </p>
+ * <pre><code>
+ *
+ * public interface MyConfiguration extends ConfigurationComposite
+ * {
+ *     Property&lt;Long&gt; timeout();
+ * }
+ *
+ * :
+ *
+ * &#64;This Configuration&lt;MyConfiguration&gt; config;
+ * :
+ * private void setTimeoutConfiguration( long timeout )
+ * {
+ *     config.get().timeout().set( timeout );
+ *     config.save();
+ * }
+ * </code></pre>
+ * <p>
+ * And even if a separate thread is using the {@code timeout()} configuration when this is happening, the
+ * {@link UnitOfWork} isolation will ensure that the other thread is not affected. That thread, on the other hand
+ * will need to do a {@link #refresh()} at an appropriate time to pick up the timeout change. For instance;
+ * </p>
+ * <pre><code>
+ *
+ * &#64;Service InventoryService remoteInventoryService;
+ *
+ * public void restockInventoryItem( InventoryItemId id, int itemCount )
+ * {
+ *     config.refresh();
+ *     long timeout = config.get().timeout().get();
+ *
+ *     remoteInventoryService.restock( id, itemCount, timeout );
+ *
+ *     :
+ *     :
+ * }
+ * </code></pre>
+ */
+@SuppressWarnings( "JavadocReference" )
+@Mixins( Configuration.ConfigurationMixin.class )
+public interface Configuration<T>
+{
+    /**
+     * Retrieves the user configuration instance managed by this Configuration.
+     * <p>
+     * Even if the user configuration is initialized from properties file, the consistency rules of Zest composites
+     * still applies. If the the properties file is missing a value, then the initialization will fail with a
+     * RuntimeException. If Constraints has been defined, those will need to be satisfied as well. The user
+     * configuration instance returned will fulfill the constraints and consistency normal to all composites, and
+     * can therefor safely be used with additional checks.
+     * </p>
+     *
+     * @return The fully initialized and ready-to-use user configuration instance.
+     */
+    T get();
+
+    /**
+     * Updates the values of the managed user ConfigurationComposite instance from the underlying
+     * {@code org.qi4j.spi.entitystore.EntityStore}.  Any modified values in the current user configuration that
+     * has not been saved, via {@link #save()} method, will be lost.
+     */
+    void refresh();
+
+    /**
+     * Persists the modified values in the user configuration instance to the underlying store.
+     */
+    void save();
+
+    /**
+     * Implementation of Configuration.
+     * <p>
+     * This is effectively an internal class in Zest and should never be used directly by user code.
+     * </p>
+     *
+     * @param <T>
+     */
+    public class ConfigurationMixin<T>
+        implements Configuration<T>
+    {
+        private T configuration;
+        private UnitOfWork uow;
+
+        @Structure
+        private Qi4j api;
+
+        @This
+        private ServiceComposite me;
+
+        @Structure
+        private Module module;
+
+        @Service
+        private Iterable<ServiceReference<ValueSerialization>> valueSerialization;
+
+        public ConfigurationMixin()
+        {
+        }
+
+        @Override
+        public synchronized T get()
+        {
+            if( configuration == null )
+            {
+                Usecase usecase = UsecaseBuilder.newUsecase( "Configuration:" + me.identity().get() );
+                uow = module.newUnitOfWork( usecase );
+                try
+                {
+                    configuration = this.findConfigurationInstanceFor( me, uow );
+                }
+                catch( InstantiationException e )
+                {
+                    throw new IllegalStateException( e );
+                }
+            }
+
+            return configuration;
+        }
+
+        @Override
+        public synchronized void refresh()
+        {
+            if( configuration != null )
+            {
+                configuration = null;
+                uow.discard();
+                uow = null;
+            }
+        }
+
+        @Override
+        public void save()
+        {
+            if( uow != null )
+            {
+                try
+                {
+                    uow.complete();
+                    uow = null;
+                }
+                catch( UnitOfWorkCompletionException e )
+                {
+                    // Should be impossible
+                    e.printStackTrace();
+                }
+
+                configuration = null; // Force refresh
+            }
+        }
+
+        @SuppressWarnings( "unchecked" )
+        public <V> V findConfigurationInstanceFor( ServiceComposite serviceComposite, UnitOfWork uow )
+            throws InstantiationException
+        {
+            ServiceDescriptor serviceModel = api.serviceDescriptorFor( serviceComposite );
+
+            String identity = serviceComposite.identity().get();
+            V configuration;
+            try
+            {
+                configuration = uow.get( serviceModel.<V>configurationType(), identity );
+                uow.pause();
+            }
+            catch( NoSuchEntityException | EntityTypeNotFoundException e )
+            {
+                return (V) initializeConfigurationInstance( serviceComposite, uow, serviceModel, identity );
+            }
+            return configuration;
+        }
+
+        @SuppressWarnings( "unchecked" )
+        private <V extends Identity> V initializeConfigurationInstance( ServiceComposite serviceComposite,
+                                                                        UnitOfWork uow,
+                                                                        ServiceDescriptor serviceModel,
+                                                                        String identity
+        )
+            throws InstantiationException
+        {
+            Module module = api.moduleOf( serviceComposite );
+            Usecase usecase = UsecaseBuilder.newUsecase( "Configuration:" + me.identity().get() );
+            UnitOfWork buildUow = module.newUnitOfWork( usecase );
+
+            Class<?> type = first( api.serviceDescriptorFor( serviceComposite ).types() );
+            Class<V> configType = serviceModel.configurationType();
+
+            // Check for defaults
+            V config = tryLoadPropertiesFile( buildUow, type, configType, identity );
+            if( config == null )
+            {
+                config = tryLoadJsonFile( buildUow, type, configType, identity );
+                if( config == null )
+                {
+                    config = tryLoadYamlFile( buildUow, type, configType, identity );
+                    if( config == null )
+                    {
+                        config = tryLoadXmlFile( buildUow, type, configType, identity );
+                        if( config == null )
+                        {
+                            try
+                            {
+                                EntityBuilder<V> configBuilder = buildUow.newEntityBuilder( serviceModel.<V>configurationType(), identity );
+                                configBuilder.newInstance();
+                            }
+                            catch( ConstraintViolationException e )
+                            {
+                                throw new NoSuchConfigurationException( configType, identity, e );
+                            }
+                        }
+                    }
+                }
+            }
+
+            try
+            {
+                buildUow.complete();
+
+                // Try again
+                return (V) findConfigurationInstanceFor( serviceComposite, uow );
+            }
+            catch( Exception e1 )
+            {
+                InstantiationException ex = new InstantiationException(
+                    "Could not instantiate configuration, and no configuration initialization file was found (" + identity + ")" );
+                ex.initCause( e1 );
+                throw ex;
+            }
+        }
+
+        private <C, V> V tryLoadPropertiesFile( UnitOfWork buildUow,
+                                                Class<C> compositeType,
+                                                Class<V> configType,
+                                                String identity
+        )
+            throws InstantiationException
+        {
+            EntityBuilder<V> configBuilder = buildUow.newEntityBuilder( configType, identity );
+            String resourceName = identity + ".properties";
+            InputStream asStream = getResource( compositeType, resourceName );
+            if( asStream != null )
+            {
+                try
+                {
+                    PropertyMapper.map( asStream, (Composite) configBuilder.instance() );
+                    return configBuilder.newInstance();
+                }
+                catch( IOException e1 )
+                {
+                    InstantiationException exception = new InstantiationException(
+                        "Could not read underlying Properties file." );
+                    exception.initCause( e1 );
+                    throw exception;
+                }
+            }
+            return null;
+        }
+
+        private InputStream getResource( Class<?> type, String resourceName )
+        {
+            // Load defaults from classpath root if available
+            if( type.getResource( resourceName ) == null && type.getResource( "/" + resourceName ) != null )
+            {
+                resourceName = "/" + resourceName;
+            }
+            return type.getResourceAsStream( resourceName );
+        }
+
+        private <C, V extends Identity> V tryLoadJsonFile( UnitOfWork uow,
+                                                           Class<C> compositeType,
+                                                           Class<V> configType,
+                                                           String identity
+        )
+        {
+            return readConfig( uow, compositeType, configType, identity, ValueSerialization.Formats.JSON, ".json" );
+        }
+
+        private <C, V extends Identity> V tryLoadYamlFile( UnitOfWork uow,
+                                                           Class<C> compositeType,
+                                                           Class<V> configType,
+                                                           String identity
+        )
+        {
+            return readConfig( uow, compositeType, configType, identity, ValueSerialization.Formats.YAML, ".yaml" );
+        }
+
+        private <C, V extends Identity> V tryLoadXmlFile( UnitOfWork uow,
+                                                          Class<C> compositeType,
+                                                          Class<V> configType,
+                                                          String identity
+        )
+        {
+            return readConfig( uow, compositeType, configType, identity, ValueSerialization.Formats.XML, ".xml" );
+        }
+
+        private <C, V extends Identity> V readConfig( UnitOfWork uow,
+                                                      Class<C> compositeType,
+                                                      Class<V> configType,
+                                                      String identity,
+                                                      String format,
+                                                      String extension
+        )
+        {
+            for( ServiceReference<ValueSerialization> serializerRef : valueSerialization )
+            {
+                ServiceTags serviceTags = serializerRef.metaInfo( ServiceTags.class );
+                if( serviceTags.hasTag( format ) )
+                {
+                    String resourceName = identity + extension;
+                    InputStream asStream = getResource( compositeType, resourceName );
+                    if( asStream != null )
+                    {
+                        V configObject = serializerRef.get().deserialize( configType, asStream );
+                        return uow.toEntity( configType, configObject );
+                    }
+                }
+            }
+            return null;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/configuration/ConfigurationComposite.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/configuration/ConfigurationComposite.java b/core/api/src/main/java/org/qi4j/api/configuration/ConfigurationComposite.java
new file mode 100644
index 0000000..39fb149
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/configuration/ConfigurationComposite.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.configuration;
+
+import org.qi4j.api.composite.Composite;
+import org.qi4j.api.entity.EntityComposite;
+import org.qi4j.api.entity.Identity;
+import org.qi4j.api.entity.Queryable;
+
+/**
+ * Services that want to be configurable should have a ConfigurationComposite that contains all the settings.
+ * They are treated as EntityComposites, and are therefore stored in an EntityStore. There will be one instance
+ * per service instance that uses each ConfigurationComposite, and the identity of the entity is the same as that
+ * of the service.
+ */
+@Queryable( false )
+public interface ConfigurationComposite
+    extends Identity, Composite
+{
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/configuration/Enabled.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/configuration/Enabled.java b/core/api/src/main/java/org/qi4j/api/configuration/Enabled.java
new file mode 100644
index 0000000..19a2c29
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/configuration/Enabled.java
@@ -0,0 +1,28 @@
+/*
+ * 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.configuration;
+
+import org.qi4j.api.common.UseDefaults;
+import org.qi4j.api.property.Property;
+
+/**
+ * Common configuration for setting whether a service is enabled or not. A disabled service
+ * is not considered to be available. Let your own ConfigurationComposite extend this interface to use.
+ */
+public interface Enabled
+{
+    @UseDefaults
+    Property<Boolean> enabled();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/configuration/NoSuchConfigurationException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/configuration/NoSuchConfigurationException.java b/core/api/src/main/java/org/qi4j/api/configuration/NoSuchConfigurationException.java
new file mode 100644
index 0000000..b3d3ed1
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/configuration/NoSuchConfigurationException.java
@@ -0,0 +1,48 @@
+/*
+ *  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.configuration;
+
+import org.qi4j.api.constraint.ConstraintViolationException;
+import org.qi4j.api.entity.Identity;
+
+public class NoSuchConfigurationException extends RuntimeException
+{
+    private final Class<? extends Identity> configType;
+    private final String identity;
+
+    public NoSuchConfigurationException( Class<? extends Identity> configType,
+                                         String identity,
+                                         ConstraintViolationException cause
+    )
+    {
+        super( "No configuration found for '" + identity + "' and configuration " + configType.getName() + " has one or more non-Optional properties.", cause );
+        this.configType = configType;
+        this.identity = identity;
+    }
+
+    public Class<? extends Identity> configType()
+    {
+        return configType;
+    }
+
+    public String identity()
+    {
+        return identity;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/configuration/package.html
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/configuration/package.html b/core/api/src/main/java/org/qi4j/api/configuration/package.html
new file mode 100644
index 0000000..7f8a892
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/configuration/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>Configuration API.</h2>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/constraint/Constraint.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/constraint/Constraint.java b/core/api/src/main/java/org/qi4j/api/constraint/Constraint.java
new file mode 100644
index 0000000..8e53e0e
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/constraint/Constraint.java
@@ -0,0 +1,39 @@
+/*
+ * 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.constraint;
+
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+
+/**
+ * All Constraints must implement this interface, which is used for each
+ * value validation.
+ */
+public interface Constraint<ANNOTATION extends Annotation, TYPE>
+    extends Serializable
+{
+    /**
+     * For each value or parameter which should be checked this method will be invoked.
+     * If the method returns true the value is valid. If it returns false the value
+     * is considered invalid. When all constraints have been checked a ConstraintViolationException
+     * will be thrown with all the constraint violations that were found.
+     *
+     * @param annotation the annotation to match
+     * @param value      the value to be checked
+     *
+     * @return true if valid, false if invalid
+     */
+    boolean isValid( ANNOTATION annotation, TYPE value );
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/constraint/ConstraintDeclaration.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/constraint/ConstraintDeclaration.java b/core/api/src/main/java/org/qi4j/api/constraint/ConstraintDeclaration.java
new file mode 100644
index 0000000..7ca9249
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/constraint/ConstraintDeclaration.java
@@ -0,0 +1,31 @@
+/*
+ * 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.constraint;
+
+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;
+
+/**
+ * All annotations that are used to trigger Constraints must have this annotation.
+ */
+@Retention( RetentionPolicy.RUNTIME )
+@Target( ElementType.ANNOTATION_TYPE )
+@Documented
+public @interface ConstraintDeclaration
+{
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/constraint/ConstraintDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/constraint/ConstraintDescriptor.java b/core/api/src/main/java/org/qi4j/api/constraint/ConstraintDescriptor.java
new file mode 100644
index 0000000..ff5e5a6
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/constraint/ConstraintDescriptor.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.constraint;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * Constraint Descriptor.
+ */
+public interface ConstraintDescriptor
+{
+    Annotation annotation();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/constraint/ConstraintImplementationNotFoundException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/constraint/ConstraintImplementationNotFoundException.java b/core/api/src/main/java/org/qi4j/api/constraint/ConstraintImplementationNotFoundException.java
new file mode 100644
index 0000000..e27ef94
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/constraint/ConstraintImplementationNotFoundException.java
@@ -0,0 +1,28 @@
+/*
+ * 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.constraint;
+
+import org.qi4j.api.common.InvalidApplicationException;
+
+/**
+ * This exception is thrown if a Constraint implementation can not be found.
+ */
+public class ConstraintImplementationNotFoundException
+    extends InvalidApplicationException
+{
+    public ConstraintImplementationNotFoundException( String message )
+    {
+        super( message );
+    }
+}
\ 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/constraint/ConstraintViolation.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/constraint/ConstraintViolation.java b/core/api/src/main/java/org/qi4j/api/constraint/ConstraintViolation.java
new file mode 100644
index 0000000..09c4be0
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/constraint/ConstraintViolation.java
@@ -0,0 +1,52 @@
+/*
+ * 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.constraint;
+
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+
+/**
+ * When a constraint violation has occurred (ie Constraint.isValid has returned false) it
+ * is put in a collection of all violations that have occurred for this value check.
+ */
+public final class ConstraintViolation
+    implements Serializable
+{
+    private String name;
+    private final Annotation constraint;
+    private final Object value;
+
+    public ConstraintViolation( String name, Annotation constraint, Object value )
+    {
+        this.name = name;
+        this.constraint = constraint;
+        this.value = value;
+    }
+
+    public String name()
+    {
+        return name;
+    }
+
+    public Annotation constraint()
+    {
+        return constraint;
+    }
+
+    public Object value()
+    {
+        return value;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/constraint/ConstraintViolationException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/constraint/ConstraintViolationException.java b/core/api/src/main/java/org/qi4j/api/constraint/ConstraintViolationException.java
new file mode 100644
index 0000000..28e41b3
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/constraint/ConstraintViolationException.java
@@ -0,0 +1,257 @@
+/*
+ * 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.constraint;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Member;
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Locale;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+import org.qi4j.api.Qi4j;
+import org.qi4j.api.composite.Composite;
+import org.qi4j.functional.Function;
+import org.qi4j.functional.Iterables;
+
+/**
+ * This Exception is thrown when there is one or more Constraint Violations in a method
+ * call.
+ * <p>
+ * The Constraint Violations are aggregated per method, and this exception will contain those
+ * violations, together with the Composite instance it happened on as well as the Method that
+ * was invoked. The Exception also has support for localized messages of these violations.
+ * </p>
+ */
+public class ConstraintViolationException
+    extends IllegalArgumentException
+{
+    private static final long serialVersionUID = 1L;
+
+    private final Collection<ConstraintViolation> constraintViolations;
+    private String methodName;
+    private String mixinTypeName;
+    private String instanceToString;
+    private Iterable<Class<?>> instanceTypes;
+
+    public ConstraintViolationException( Composite instance, Member method,
+                                         Collection<ConstraintViolation> constraintViolations
+    )
+    {
+        this( instance.toString(), Qi4j.FUNCTION_DESCRIPTOR_FOR.map( instance ).types(), method, constraintViolations );
+    }
+
+    public ConstraintViolationException( String instanceToString,
+                                         Iterable<Class<?>> instanceTypes,
+                                         Member method,
+                                         Collection<ConstraintViolation> violations
+    )
+    {
+        this.instanceToString = instanceToString;
+        this.instanceTypes = instanceTypes;
+        mixinTypeName = method.getDeclaringClass().getName();
+        methodName = method.getName();
+        this.constraintViolations = violations;
+    }
+
+    public ConstraintViolationException( String instanceToString,
+                                         Iterable<Class<?>> instanceTypes,
+                                         String mixinTypeName,
+                                         String methodName,
+                                         Collection<ConstraintViolation> violations
+    )
+    {
+        this.instanceToString = instanceToString;
+        this.instanceTypes = instanceTypes;
+        this.mixinTypeName = mixinTypeName;
+        this.methodName = methodName;
+        this.constraintViolations = violations;
+    }
+
+    public Collection<ConstraintViolation> constraintViolations()
+    {
+        return constraintViolations;
+    }
+
+    /**
+     * Creates localized messages of all the constraint violations that has occured.
+     * <p>
+     * The key "<code>Qi4j_ConstraintViolation_<i><strong>CompositeType</strong></i></code>" will be used to lookup the text formatting
+     * pattern from the ResourceBundle, where <strong><code><i>CompositeType</i></code></strong> is the
+     * class name of the Composite where the constraint was violated. If such key does not exist, then the
+     * key &nbsp;"<code>Qi4j_ConstraintViolation</code>" will be used, and if that one also doesn't exist, or
+     * the resourceBundle argument is null, then the default patterns will be used;
+     * </p>
+     * <table summary="Localization of constraint vioations.">
+     * <tr><th>Type of Composite</th><th>Pattern used</th></tr>
+     * <tr><td>Composite</td>
+     * <td><code>Constraint Violation in {2}.{3} with constraint {4}, in composite \n{0} of type {1}</code></td>
+     * </tr>
+     * <tr><td>EntityComposite</td>
+     * <td><code>Constraint Violation in {2}.{3} with constraint {4}, in entity {1}[id={0}]</code></td>
+     * </tr>
+     * <tr><td>ServiceComposite</td>
+     * <td><code>Constraint Violation in {2}.{3} with constraint {4}, in service {0}</code></td>
+     * </tr>
+     * </table>
+     * Then format each ConstraintViolation according to such pattern, where the following argument are passed;
+     * <table summary="List of arguments available."><tr><th>Arg</th><th>Value</th></tr>
+     * <tr>
+     * <td>{0}</td>
+     * <td>Composite instance toString()</td>
+     * </tr>
+     * <tr>
+     * <td>{1}</td>
+     * <td>CompositeType class name</td>
+     * </tr>
+     * <tr>
+     * <td>{2}</td>
+     * <td>MixinType class name</td>
+     * </tr>
+     * <tr>
+     * <td>{3}</td>
+     * <td>MixinType method name</td>
+     * </tr>
+     * <tr>
+     * <td>{4}</td>
+     * <td>Annotation toString()</td>
+     * </tr>
+     * <tr>
+     * <td>{5}</td>
+     * <td>toString() of value passed as the argument, or "null" text if argument was null.</td>
+     * </tr>
+     * </table>
+     * <p>
+     * <b>NOTE!!!</b> This class is still under construction and will be modified further.
+     * </p>
+     *
+     * @param bundle The ResourceBundle for Localization, or null if default formatting and locale to be used.
+     *
+     * @return An array of localized messages of the violations incurred.
+     */
+    public String[] localizedMessagesFrom( ResourceBundle bundle )
+    {
+        String pattern = "Constraint violation in {0}.{1} for method ''{3}'' with constraint \"{4}({6})\", for value ''{5}''";
+
+        ArrayList<String> list = new ArrayList<String>();
+        for( ConstraintViolation violation : constraintViolations )
+        {
+            Locale locale;
+            if( bundle != null )
+            {
+                try
+                {
+                    pattern = bundle.getString( "qi4j.constraint." + mixinTypeName + "." + methodName );
+                }
+                catch( MissingResourceException e1 )
+                {
+                    try
+                    {
+                        pattern = bundle.getString( "qi4j.constraint" );
+                    }
+                    catch( MissingResourceException e2 )
+                    {
+                        // ignore. The default pattern will be used.
+                    }
+                }
+                locale = bundle.getLocale();
+            }
+            else
+            {
+                locale = Locale.getDefault();
+            }
+            MessageFormat format = new MessageFormat( pattern, locale );
+
+            Annotation annotation = violation.constraint();
+            String name = violation.name();
+            Object value = violation.value();
+            String classes;
+            if( Iterables.count( instanceTypes ) == 1 )
+            {
+                classes = Iterables.first( instanceTypes ).getSimpleName();
+            }
+            else
+            {
+                classes = "[" + Iterables.<Class<?>>toString( instanceTypes, new Function<Class<?>, String>()
+                {
+                    @Override
+                    public String map( Class<?> from )
+                    {
+                        return from.getSimpleName();
+                    }
+                }, "," ) + "]";
+            }
+            Object[] args = new Object[]
+                {
+                    instanceToString,
+                    classes,
+                    mixinTypeName,
+                    methodName,
+                    annotation.toString(),
+                    "" + value,
+                    name
+                };
+            StringBuffer text = new StringBuffer();
+            format.format( args, text, null );
+            list.add( text.toString() );
+        }
+        String[] result = new String[ list.size() ];
+        list.toArray( result );
+        return result;
+    }
+
+    public String localizedMessage()
+    {
+        String[] messages = localizedMessagesFrom( null );
+        StringBuilder result = new StringBuilder();
+        boolean first = true;
+        for( String message : messages )
+        {
+            if( !first )
+            {
+                result.append( ',' );
+            }
+            first = false;
+            result.append( message );
+        }
+        return result.toString();
+    }
+
+    @Override
+    public String getLocalizedMessage()
+    {
+        return localizedMessage();
+    }
+
+    @Override
+    public String getMessage()
+    {
+        return localizedMessage();
+    }
+
+    public String methodName()
+    {
+        return methodName;
+    }
+
+    public String mixinTypeName()
+    {
+        return mixinTypeName;
+    }
+}
\ 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/constraint/Constraints.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/constraint/Constraints.java b/core/api/src/main/java/org/qi4j/api/constraint/Constraints.java
new file mode 100644
index 0000000..b42701c
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/constraint/Constraints.java
@@ -0,0 +1,36 @@
+/*
+ * 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.constraint;
+
+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;
+
+/**
+ * This annotation is used by composites and mixins to declare what Constraints
+ * can be applied in the Composite.
+ * <p>
+ * Constraints implement the {@link Constraint} interface
+ * </p>
+ */
+@Retention( RetentionPolicy.RUNTIME )
+@Target( { ElementType.TYPE } )
+@Documented
+public @interface Constraints
+{
+    Class<? extends Constraint<?, ?>>[] value();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/constraint/ConstraintsDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/constraint/ConstraintsDescriptor.java b/core/api/src/main/java/org/qi4j/api/constraint/ConstraintsDescriptor.java
new file mode 100644
index 0000000..bea1115
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/constraint/ConstraintsDescriptor.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.constraint;
+
+/**
+ * Constraints Descriptor.
+ */
+public interface ConstraintsDescriptor
+{
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/constraint/Name.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/constraint/Name.java b/core/api/src/main/java/org/qi4j/api/constraint/Name.java
new file mode 100644
index 0000000..fc4c79e
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/constraint/Name.java
@@ -0,0 +1,32 @@
+/*
+ * 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.constraint;
+
+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 for parameter names. This is used to add extra information for constraint exception.
+ */
+@Retention( RetentionPolicy.RUNTIME )
+@Target( { ElementType.PARAMETER } )
+@Documented
+public @interface Name
+{
+    String value();
+}
\ 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/constraint/package.html
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/constraint/package.html b/core/api/src/main/java/org/qi4j/api/constraint/package.html
new file mode 100644
index 0000000..2e4d340
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/constraint/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>Constraint API.</h2>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/dataset/DataSet.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/dataset/DataSet.java b/core/api/src/main/java/org/qi4j/api/dataset/DataSet.java
new file mode 100644
index 0000000..2e4bdc3
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/dataset/DataSet.java
@@ -0,0 +1,36 @@
+/*
+ * 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.dataset;
+
+import org.qi4j.functional.Function;
+import org.qi4j.functional.Specification;
+
+/**
+ * definition.constrain(entity(Person.class))
+ * builder.from(path(Person.class,Movie.))
+ * TODO
+ */
+public interface DataSet<T>
+{
+    DataSet<T> constrain( Specification<T> selection );
+
+    <U> DataSet<U> project( Function<T, U> conversion );
+
+    Query<T> newQuery();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/dataset/DataSetSource.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/dataset/DataSetSource.java b/core/api/src/main/java/org/qi4j/api/dataset/DataSetSource.java
new file mode 100644
index 0000000..4cf68f1
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/dataset/DataSetSource.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.dataset;
+
+/**
+ * TODO
+ */
+public interface DataSetSource
+{
+    <T> DataSet<T> newDataSet( Class<T> type );
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/dataset/Query.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/dataset/Query.java b/core/api/src/main/java/org/qi4j/api/dataset/Query.java
new file mode 100644
index 0000000..61edd73
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/dataset/Query.java
@@ -0,0 +1,64 @@
+/*
+ * 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.dataset;
+
+import org.qi4j.api.property.Property;
+import org.qi4j.api.query.QueryException;
+import org.qi4j.api.query.QueryExecutionException;
+import org.qi4j.functional.Specification;
+import org.qi4j.functional.Visitor;
+
+/**
+ * TODO
+ */
+public interface Query<T>
+{
+    public enum Order
+    {
+        ASCENDING, DESCENDING
+    }
+
+    Query filter( Specification<T> filter );
+
+    Query orderBy( final Property<?> property, final Order order );
+
+    Query skip( int skipNrOfResults );
+
+    Query limit( int maxNrOfResults );
+
+    // Variables
+    Query<T> setVariable( String name, Object value );
+
+    Object getVariable( String name );
+
+    long count()
+        throws QueryExecutionException;
+
+    T first()
+        throws QueryExecutionException;
+
+    T single()
+        throws QueryException;
+
+    <ThrowableType extends Throwable> boolean execute( Visitor<T, ThrowableType> resultVisitor )
+        throws ThrowableType, QueryExecutionException;
+
+    Iterable<T> toIterable()
+        throws QueryExecutionException;
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/dataset/iterable/IterableDataSet.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/dataset/iterable/IterableDataSet.java b/core/api/src/main/java/org/qi4j/api/dataset/iterable/IterableDataSet.java
new file mode 100644
index 0000000..3300ea4
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/dataset/iterable/IterableDataSet.java
@@ -0,0 +1,57 @@
+/*
+ * 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.dataset.iterable;
+
+import org.qi4j.api.dataset.DataSet;
+import org.qi4j.api.dataset.Query;
+import org.qi4j.functional.Function;
+import org.qi4j.functional.Iterables;
+import org.qi4j.functional.Specification;
+
+/**
+ * TODO
+ */
+public class IterableDataSet<T>
+    implements DataSet<T>
+{
+    private Iterable<T> iterable;
+
+    public IterableDataSet( Iterable<T> iterable )
+    {
+        this.iterable = iterable;
+    }
+
+    @Override
+    public DataSet<T> constrain( Specification<T> selection )
+    {
+        return new IterableDataSet<T>( Iterables.filter( selection, iterable ) );
+    }
+
+    @Override
+    public <U> DataSet<U> project( Function<T, U> conversion )
+    {
+        return new IterableDataSet<U>( Iterables.map( conversion, iterable ) );
+    }
+
+    @Override
+    public Query<T> newQuery()
+    {
+        return new IterableQuery<T>( iterable );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/dataset/iterable/IterableQuery.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/dataset/iterable/IterableQuery.java b/core/api/src/main/java/org/qi4j/api/dataset/iterable/IterableQuery.java
new file mode 100644
index 0000000..b816a25
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/dataset/iterable/IterableQuery.java
@@ -0,0 +1,127 @@
+/*
+ * 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.dataset.iterable;
+
+import java.util.HashMap;
+import java.util.Map;
+import org.qi4j.api.dataset.Query;
+import org.qi4j.api.property.Property;
+import org.qi4j.api.query.QueryException;
+import org.qi4j.functional.Iterables;
+import org.qi4j.functional.Specification;
+import org.qi4j.functional.Visitor;
+
+/**
+ * TODO
+ */
+public class IterableQuery<T> implements Query<T>
+{
+    private Iterable<T> iterable;
+    private int skip;
+    private int limit;
+    private Map<String, Object> variables = new HashMap<String, Object>();
+
+    public IterableQuery( Iterable<T> iterable )
+    {
+        this.iterable = iterable;
+    }
+
+    @Override
+    public Query filter( Specification<T> filter )
+    {
+        iterable = Iterables.filter( filter, iterable );
+
+        return this;
+    }
+
+    @Override
+    public Query orderBy( Property<?> property, Order order )
+    {
+        return this;
+    }
+
+    @Override
+    public Query skip( int skipNrOfResults )
+    {
+        this.skip = skipNrOfResults;
+
+        return this;
+    }
+
+    @Override
+    public Query limit( int maxNrOfResults )
+    {
+        this.limit = maxNrOfResults;
+        return this;
+    }
+
+    @Override
+    public Query<T> setVariable( String name, Object value )
+    {
+        variables.put( name, value );
+        return this;
+    }
+
+    @Override
+    public Object getVariable( String name )
+    {
+        return variables.get( name );
+    }
+
+    @Override
+    public long count()
+    {
+        return Iterables.count( Iterables.limit( limit, Iterables.skip( skip, iterable ) ) );
+    }
+
+    @Override
+    public T first()
+    {
+        return Iterables.first( Iterables.limit( limit, Iterables.skip( skip, iterable ) ) );
+    }
+
+    @Override
+    public T single()
+        throws QueryException
+    {
+        return Iterables.single( Iterables.limit( limit, Iterables.skip( skip, iterable ) ) );
+    }
+
+    @Override
+    public <ThrowableType extends Throwable> boolean execute( Visitor<T, ThrowableType> resultVisitor )
+        throws ThrowableType
+    {
+        for( T t : toIterable() )
+        {
+            if( !resultVisitor.visit( t ) )
+            {
+                return false;
+            }
+        }
+
+        return true;
+    }
+
+    @Override
+    public Iterable<T> toIterable()
+        throws QueryException
+    {
+        return Iterables.limit( limit, Iterables.skip( skip, iterable ) );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/dataset/iterable/package.html
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/dataset/iterable/package.html b/core/api/src/main/java/org/qi4j/api/dataset/iterable/package.html
new file mode 100644
index 0000000..9874cb5
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/dataset/iterable/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>Iterable DataSets.</h2>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/dataset/package.html
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/dataset/package.html b/core/api/src/main/java/org/qi4j/api/dataset/package.html
new file mode 100644
index 0000000..f324682
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/dataset/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>DataSet API.</h2>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/entity/Aggregated.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/entity/Aggregated.java b/core/api/src/main/java/org/qi4j/api/entity/Aggregated.java
new file mode 100644
index 0000000..11e4ba5
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/entity/Aggregated.java
@@ -0,0 +1,31 @@
+/*
+ * 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.entity;
+
+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;
+
+/**
+ * Marks an association as aggregating the referenced Entities
+ */
+@Retention( RetentionPolicy.RUNTIME )
+@Target( { ElementType.METHOD } )
+@Documented
+public @interface Aggregated
+{
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/entity/EntityBuilder.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/entity/EntityBuilder.java b/core/api/src/main/java/org/qi4j/api/entity/EntityBuilder.java
new file mode 100644
index 0000000..7020253
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/entity/EntityBuilder.java
@@ -0,0 +1,60 @@
+/*  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.entity;
+
+import org.qi4j.api.common.ConstructionException;
+
+/**
+ * EntityBuilders are used to instantiate EntityComposites. They can be acquired from
+ * {@link org.qi4j.api.unitofwork.UnitOfWork#newEntityBuilder(Class)} and allows the client
+ * to provide additional settings before instantiating the Composite.
+ *
+ * After calling newInstance() the builder becomes invalid, and may not be called again.
+ */
+public interface EntityBuilder<T>
+{
+    /**
+     * 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 instance();
+
+    /**
+     * 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 instanceFor( Class<K> mixinType );
+
+    /**
+     * Create a new Entity instance.
+     *
+     * @return a new Entity instance
+     *
+     * @throws org.qi4j.api.common.ConstructionException
+     *                            thrown if it was not possible to instantiate the Composite
+     * @throws LifecycleException if the entity could not be created
+     */
+    T newInstance()
+        throws ConstructionException, LifecycleException;
+}
\ 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/entity/EntityBuilderTemplate.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/entity/EntityBuilderTemplate.java b/core/api/src/main/java/org/qi4j/api/entity/EntityBuilderTemplate.java
new file mode 100644
index 0000000..4473844
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/entity/EntityBuilderTemplate.java
@@ -0,0 +1,43 @@
+/*
+ * 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.entity;
+
+import org.qi4j.api.structure.Module;
+
+/**
+ * EntityBuilderTemplate.
+ */
+public abstract class EntityBuilderTemplate<T>
+{
+    Class<T> type;
+
+    protected EntityBuilderTemplate( Class<T> type )
+    {
+        this.type = type;
+    }
+
+    protected abstract void build( T prototype );
+
+    public T newInstance( Module module )
+    {
+        EntityBuilder<T> builder = module.currentUnitOfWork().newEntityBuilder( type );
+        build( builder.instance() );
+        return builder.newInstance();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/entity/EntityComposite.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/entity/EntityComposite.java b/core/api/src/main/java/org/qi4j/api/entity/EntityComposite.java
new file mode 100644
index 0000000..93089b8
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/entity/EntityComposite.java
@@ -0,0 +1,31 @@
+/*
+ * 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.entity;
+
+import org.qi4j.api.association.AssociationMixin;
+import org.qi4j.api.association.ManyAssociationMixin;
+import org.qi4j.api.association.NamedAssociationMixin;
+import org.qi4j.api.composite.Composite;
+import org.qi4j.api.mixin.Mixins;
+
+/**
+ * EntityComposites are Composites that has mutable state persisted in EntityStores and equality defined from its
+ * identity.
+ */
+@Mixins( { AssociationMixin.class, ManyAssociationMixin.class, NamedAssociationMixin.class } )
+public interface EntityComposite
+    extends Identity, Composite
+{
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/entity/EntityDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/entity/EntityDescriptor.java b/core/api/src/main/java/org/qi4j/api/entity/EntityDescriptor.java
new file mode 100644
index 0000000..6ce2500
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/entity/EntityDescriptor.java
@@ -0,0 +1,31 @@
+/*
+ * 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.entity;
+
+import org.qi4j.api.association.AssociationStateDescriptor;
+import org.qi4j.api.composite.CompositeDescriptor;
+import org.qi4j.api.composite.StatefulCompositeDescriptor;
+
+/**
+ * Entity Descriptor.
+ */
+public interface EntityDescriptor
+    extends CompositeDescriptor, StatefulCompositeDescriptor
+{
+    @Override
+    AssociationStateDescriptor state();
+
+    boolean queryable();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/entity/EntityReference.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/qi4j/api/entity/EntityReference.java b/core/api/src/main/java/org/qi4j/api/entity/EntityReference.java
new file mode 100644
index 0000000..967647c
--- /dev/null
+++ b/core/api/src/main/java/org/qi4j/api/entity/EntityReference.java
@@ -0,0 +1,133 @@
+/*
+ * 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.entity;
+
+import java.io.Serializable;
+import org.qi4j.api.util.NullArgumentException;
+
+/**
+ * An EntityReference is identity of a specific Entity instance.
+ * <p>When stringified, the identity is used as-is. Example:</p>
+ * <pre>123456-abcde</pre>
+ */
+public final class EntityReference
+    implements Serializable
+{
+    /**
+     * Parse an URI to an EntityReference.
+     * @param uri the URI to parse
+     * @return the EntityReference represented by the given URI
+     */
+    public static EntityReference parseURI( String uri )
+    {
+        String identity = uri.substring( "urn:qi4j:entity:".length() );
+        return new EntityReference( identity );
+    }
+
+    /**
+     * Parse an Entity identity to an EntityReference.
+     * @param identity the EntityReference identity
+     * @return the EntityReference represented by the given identity
+     */
+    public static EntityReference parseEntityReference( String identity )
+    {
+        return new EntityReference( identity );
+    }
+
+    /**
+     * @param object an EntityComposite
+     * @return the EntityReference for the given EntityComposite
+     */
+    public static EntityReference entityReferenceFor( Object object )
+    {
+        return new EntityReference( (EntityComposite) object );
+    }
+
+    public static EntityReference create( Identity identity )
+    {
+        if( identity == null )
+            return null;
+        return new EntityReference( identity.identity().get() );
+    }
+
+    private static final long serialVersionUID = 1L;
+
+    private String identity;
+
+    /**
+     * @param entityComposite a non-null EntityComposite
+     * @throws NullPointerException if entityComposite is null
+     */
+    public EntityReference( EntityComposite entityComposite )
+    {
+        this( entityComposite.identity().get() );
+    }
+
+    /**
+     * @param identity reference identity
+     * @throws NullArgumentException if identity is null or empty
+     */
+    public EntityReference( String identity )
+    {
+        NullArgumentException.validateNotEmpty( "identity", identity );
+        this.identity = identity;
+    }
+
+    /**
+     * @return This EntityReference identity.
+     */
+    public final String identity()
+    {
+        return identity;
+    }
+
+    /**
+     * @return An URI representation of this EntityReference.
+     */
+    public String toURI()
+    {
+        return "urn:qi4j:entity:" + identity;
+    }
+
+    @Override
+    public boolean equals( Object o )
+    {
+        if( this == o )
+        {
+            return true;
+        }
+        if( o == null || getClass() != o.getClass() )
+        {
+            return false;
+        }
+        EntityReference that = (EntityReference) o;
+        return identity.equals( that.identity );
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return identity.hashCode();
+    }
+
+    /**
+     * @return This EntityReference identity.
+     */
+    @Override
+    public String toString()
+    {
+        return identity;
+    }
+}


Mime
View raw message