polygene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nic...@apache.org
Subject [45/81] [abbrv] [partial] zest-java git commit: ZEST-195 ; Replace all "zest" with "polygene"
Date Sat, 17 Dec 2016 10:28:21 GMT
http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/api/src/main/java/org/apache/polygene/api/composite/DependencyDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/composite/DependencyDescriptor.java b/core/api/src/main/java/org/apache/polygene/api/composite/DependencyDescriptor.java
new file mode 100644
index 0000000..ec87e2c
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/composite/DependencyDescriptor.java
@@ -0,0 +1,41 @@
+/*
+ *  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.apache.polygene.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/1c722f44/core/api/src/main/java/org/apache/polygene/api/composite/InjectedFieldDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/composite/InjectedFieldDescriptor.java b/core/api/src/main/java/org/apache/polygene/api/composite/InjectedFieldDescriptor.java
new file mode 100644
index 0000000..ce88a68
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/composite/InjectedFieldDescriptor.java
@@ -0,0 +1,32 @@
+/*
+ *  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.apache.polygene.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/1c722f44/core/api/src/main/java/org/apache/polygene/api/composite/InjectedMethodDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/composite/InjectedMethodDescriptor.java b/core/api/src/main/java/org/apache/polygene/api/composite/InjectedMethodDescriptor.java
new file mode 100644
index 0000000..0ad4f70
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/composite/InjectedMethodDescriptor.java
@@ -0,0 +1,31 @@
+/*
+ *  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.apache.polygene.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/1c722f44/core/api/src/main/java/org/apache/polygene/api/composite/InjectedParametersDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/composite/InjectedParametersDescriptor.java b/core/api/src/main/java/org/apache/polygene/api/composite/InjectedParametersDescriptor.java
new file mode 100644
index 0000000..5361575
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/composite/InjectedParametersDescriptor.java
@@ -0,0 +1,28 @@
+/*
+ *  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.apache.polygene.api.composite;
+
+/**
+ * Composite constructors and method injected parameters descriptor.
+ */
+public interface InjectedParametersDescriptor
+{
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/api/src/main/java/org/apache/polygene/api/composite/InvalidCompositeException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/composite/InvalidCompositeException.java b/core/api/src/main/java/org/apache/polygene/api/composite/InvalidCompositeException.java
new file mode 100644
index 0000000..d9de0c7
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/composite/InvalidCompositeException.java
@@ -0,0 +1,32 @@
+/*
+ *  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.apache.polygene.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/1c722f44/core/api/src/main/java/org/apache/polygene/api/composite/InvalidValueCompositeException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/composite/InvalidValueCompositeException.java b/core/api/src/main/java/org/apache/polygene/api/composite/InvalidValueCompositeException.java
new file mode 100644
index 0000000..c857a6e
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/composite/InvalidValueCompositeException.java
@@ -0,0 +1,32 @@
+/*
+ *  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.apache.polygene.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/1c722f44/core/api/src/main/java/org/apache/polygene/api/composite/MethodDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/composite/MethodDescriptor.java b/core/api/src/main/java/org/apache/polygene/api/composite/MethodDescriptor.java
new file mode 100644
index 0000000..f0a991d
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/composite/MethodDescriptor.java
@@ -0,0 +1,31 @@
+/*
+ *  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.apache.polygene.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/1c722f44/core/api/src/main/java/org/apache/polygene/api/composite/MissingMethodException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/composite/MissingMethodException.java b/core/api/src/main/java/org/apache/polygene/api/composite/MissingMethodException.java
new file mode 100644
index 0000000..a6e5998
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/composite/MissingMethodException.java
@@ -0,0 +1,38 @@
+/*
+ *  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.apache.polygene.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/1c722f44/core/api/src/main/java/org/apache/polygene/api/composite/ModelDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/composite/ModelDescriptor.java b/core/api/src/main/java/org/apache/polygene/api/composite/ModelDescriptor.java
new file mode 100644
index 0000000..cd7ddcf
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/composite/ModelDescriptor.java
@@ -0,0 +1,41 @@
+/*
+ *  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.apache.polygene.api.composite;
+
+import org.apache.polygene.api.common.Visibility;
+import org.apache.polygene.api.structure.MetaInfoHolder;
+import org.apache.polygene.api.structure.ModuleDescriptor;
+import org.apache.polygene.api.type.HasTypes;
+
+/**
+ * Composite ModelDescriptor.
+ */
+public interface ModelDescriptor extends HasTypes, MetaInfoHolder
+{
+    Visibility visibility();
+
+    /** The Module that the Model is declared in.
+     *
+     * @return The Module that this Model was declared in.
+     */
+    ModuleDescriptor module();
+
+    boolean isAssignableTo( Class<?> type );
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchCompositeException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchCompositeException.java b/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchCompositeException.java
new file mode 100644
index 0000000..e03eafc
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchCompositeException.java
@@ -0,0 +1,59 @@
+/*
+ *  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.apache.polygene.api.composite;
+
+import org.apache.polygene.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;
+    private final String visibleTypes;
+
+    protected NoSuchCompositeException( String metaType, String compositeType, String moduleName, String visibleTypes )
+    {
+        super( "Could not find any visible " + metaType + " of type [" + compositeType + "] in module [" +
+               moduleName + "].\n" + visibleTypes );
+        this.compositeType = compositeType;
+        this.moduleName = moduleName;
+        this.visibleTypes = visibleTypes;
+    }
+
+    public String compositeType()
+    {
+        return compositeType;
+    }
+
+    public String moduleName()
+    {
+        return moduleName;
+    }
+
+    public String visibleTypes()
+    {
+        return visibleTypes;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchTransientException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchTransientException.java b/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchTransientException.java
new file mode 100644
index 0000000..6f6bfd7
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/composite/NoSuchTransientException.java
@@ -0,0 +1,42 @@
+/*
+ *  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.apache.polygene.api.composite;
+
+import java.util.stream.Collectors;
+import org.apache.polygene.api.structure.TypeLookup;
+
+/**
+ * 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, TypeLookup typeLookup )
+    {
+        super( "TransientComposite", typeName, moduleName, formatVisibleTypes( typeLookup ) );
+    }
+
+    private static String formatVisibleTypes( TypeLookup typeLookup )
+    {
+        return typeLookup.allTransients()
+            .map(descriptor -> descriptor.primaryType().getName())
+            .collect( Collectors.joining( "\n", "Visible transient types are:\n", "" ) );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/api/src/main/java/org/apache/polygene/api/composite/PropertyMapper.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/composite/PropertyMapper.java b/core/api/src/main/java/org/apache/polygene/api/composite/PropertyMapper.java
new file mode 100644
index 0000000..0591bd4
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/composite/PropertyMapper.java
@@ -0,0 +1,655 @@
+/*
+ *  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.apache.polygene.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.time.Duration;
+import java.time.Instant;
+import java.time.LocalDate;
+import java.time.LocalDateTime;
+import java.time.OffsetDateTime;
+import java.time.Period;
+import java.time.ZonedDateTime;
+import java.util.ArrayList;
+import java.util.Collection;
+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.apache.polygene.api.PolygeneAPI;
+import org.apache.polygene.api.property.GenericPropertyInfo;
+import org.apache.polygene.api.property.Property;
+import org.apache.polygene.api.util.Classes;
+import org.apache.polygene.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( LocalDate.class, new LocalDateMapper() );
+        STRATEGY.put( LocalDateTime.class, new LocalDateTimeMapper() );
+        STRATEGY.put( ZonedDateTime.class, new ZonedDateTimeMapper() );
+        STRATEGY.put( OffsetDateTime.class, new OffsetDateTimeMapper() );
+        STRATEGY.put( Instant.class, new InstantMapper() );
+        STRATEGY.put( Duration.class, new DurationMapper() );
+        STRATEGY.put( Period.class, new PeriodMapper() );
+        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.apply( 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 LocalDateMapper
+        implements MappingStrategy
+    {
+        @Override
+        public Object map( Composite composite, Type type, String value )
+        {
+            return LocalDate.parse( value.trim() );
+        }
+    }
+
+    private static class LocalDateTimeMapper
+        implements MappingStrategy
+    {
+        @Override
+        public Object map( Composite composite, Type type, String value )
+        {
+            return LocalDateTime.parse( value.trim() );
+        }
+    }
+
+    private static class ZonedDateTimeMapper
+        implements MappingStrategy
+    {
+        @Override
+        public Object map( Composite composite, Type type, String value )
+        {
+            return ZonedDateTime.parse( value.trim() );
+        }
+    }
+
+    private static class OffsetDateTimeMapper
+        implements MappingStrategy
+    {
+        @Override
+        public Object map( Composite composite, Type type, String value )
+        {
+            return OffsetDateTime.parse( value.trim() );
+        }
+    }
+
+    private static class InstantMapper
+        implements MappingStrategy
+    {
+        @Override
+        public Object map( Composite composite, Type type, String value )
+        {
+            return Instant.parse( value.trim() );
+        }
+    }
+
+    private static class DurationMapper
+        implements MappingStrategy
+    {
+        @Override
+        public Object map( Composite composite, Type type, String value )
+        {
+            return Duration.parse( value.trim() );
+        }
+    }
+
+    private static class PeriodMapper
+        implements MappingStrategy
+    {
+        @Override
+        public Object map( Composite composite, Type type, String value )
+        {
+            return Period.parse( value.trim() );
+        }
+    }
+
+    private static class ValueCompositeMapper
+        implements MappingStrategy
+    {
+        @Override
+        @SuppressWarnings( "unchecked" )
+        public Object map( Composite composite, Type type, String value )
+        {
+            return PolygeneAPI.FUNCTION_COMPOSITE_INSTANCE_OF.apply( composite )
+                .module()
+                .instance()
+                .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/1c722f44/core/api/src/main/java/org/apache/polygene/api/composite/StateDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/composite/StateDescriptor.java b/core/api/src/main/java/org/apache/polygene/api/composite/StateDescriptor.java
new file mode 100644
index 0000000..20c07c2
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/composite/StateDescriptor.java
@@ -0,0 +1,39 @@
+/*
+ *  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.apache.polygene.api.composite;
+
+import java.util.stream.Stream;
+import org.apache.polygene.api.common.QualifiedName;
+import org.apache.polygene.api.property.PropertyDescriptor;
+
+/**
+ * Composite State Descriptor.
+ */
+public interface StateDescriptor
+{
+    PropertyDescriptor findPropertyModelByName( String name )
+        throws IllegalArgumentException;
+
+    PropertyDescriptor findPropertyModelByQualifiedName( QualifiedName name )
+        throws IllegalArgumentException;
+
+    Stream<? extends PropertyDescriptor> properties();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/api/src/main/java/org/apache/polygene/api/composite/StatefulCompositeDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/composite/StatefulCompositeDescriptor.java b/core/api/src/main/java/org/apache/polygene/api/composite/StatefulCompositeDescriptor.java
new file mode 100644
index 0000000..42cdcb3
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/composite/StatefulCompositeDescriptor.java
@@ -0,0 +1,28 @@
+/*
+ *  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.apache.polygene.api.composite;
+
+/**
+ * Stateful Composite Descriptor.
+ */
+public interface StatefulCompositeDescriptor
+{
+    StateDescriptor state();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/api/src/main/java/org/apache/polygene/api/composite/TransientBuilder.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/composite/TransientBuilder.java b/core/api/src/main/java/org/apache/polygene/api/composite/TransientBuilder.java
new file mode 100644
index 0000000..e42a904
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/composite/TransientBuilder.java
@@ -0,0 +1,71 @@
+/*
+ *  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.apache.polygene.api.composite;
+
+import org.apache.polygene.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.apache.polygene.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/1c722f44/core/api/src/main/java/org/apache/polygene/api/composite/TransientBuilderFactory.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/composite/TransientBuilderFactory.java b/core/api/src/main/java/org/apache/polygene/api/composite/TransientBuilderFactory.java
new file mode 100644
index 0000000..7c6c7a1
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/composite/TransientBuilderFactory.java
@@ -0,0 +1,59 @@
+/*
+ *  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.apache.polygene.api.composite;
+
+import org.apache.polygene.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.apache.polygene.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/1c722f44/core/api/src/main/java/org/apache/polygene/api/composite/TransientComposite.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/composite/TransientComposite.java b/core/api/src/main/java/org/apache/polygene/api/composite/TransientComposite.java
new file mode 100644
index 0000000..bcf86fd
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/composite/TransientComposite.java
@@ -0,0 +1,37 @@
+/*
+ *  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.apache.polygene.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/1c722f44/core/api/src/main/java/org/apache/polygene/api/composite/TransientDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/composite/TransientDescriptor.java b/core/api/src/main/java/org/apache/polygene/api/composite/TransientDescriptor.java
new file mode 100644
index 0000000..e4ce21a
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/composite/TransientDescriptor.java
@@ -0,0 +1,29 @@
+/*
+ *  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.apache.polygene.api.composite;
+
+/**
+ * TransientComposite Descriptor.
+ */
+public interface TransientDescriptor
+    extends CompositeDescriptor, StatefulCompositeDescriptor
+{
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/api/src/main/java/org/apache/polygene/api/composite/package.html
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/composite/package.html b/core/api/src/main/java/org/apache/polygene/api/composite/package.html
new file mode 100644
index 0000000..4c79ac8
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/composite/package.html
@@ -0,0 +1,24 @@
+<!--
+  ~  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>

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/api/src/main/java/org/apache/polygene/api/concern/ConcernDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/concern/ConcernDescriptor.java b/core/api/src/main/java/org/apache/polygene/api/concern/ConcernDescriptor.java
new file mode 100644
index 0000000..4986bec
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/concern/ConcernDescriptor.java
@@ -0,0 +1,29 @@
+/*
+ *  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.apache.polygene.api.concern;
+
+/**
+ * Concern descriptor.
+ */
+public interface ConcernDescriptor
+{
+    Class modifierClass();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/api/src/main/java/org/apache/polygene/api/concern/ConcernOf.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/concern/ConcernOf.java b/core/api/src/main/java/org/apache/polygene/api/concern/ConcernOf.java
new file mode 100644
index 0000000..e872308
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/concern/ConcernOf.java
@@ -0,0 +1,46 @@
+/*
+ *  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.apache.polygene.api.concern;
+
+import org.apache.polygene.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/1c722f44/core/api/src/main/java/org/apache/polygene/api/concern/Concerns.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/concern/Concerns.java b/core/api/src/main/java/org/apache/polygene/api/concern/Concerns.java
new file mode 100644
index 0000000..9c43e0f
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/concern/Concerns.java
@@ -0,0 +1,39 @@
+/*
+ *  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.apache.polygene.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/1c722f44/core/api/src/main/java/org/apache/polygene/api/concern/ConcernsDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/concern/ConcernsDescriptor.java b/core/api/src/main/java/org/apache/polygene/api/concern/ConcernsDescriptor.java
new file mode 100644
index 0000000..7a5ee07
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/concern/ConcernsDescriptor.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.apache.polygene.api.concern;
+
+/**
+ * Concerns descriptor.
+ */
+public interface ConcernsDescriptor
+{
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/1c722f44/core/api/src/main/java/org/apache/polygene/api/concern/GenericConcern.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/concern/GenericConcern.java b/core/api/src/main/java/org/apache/polygene/api/concern/GenericConcern.java
new file mode 100644
index 0000000..f96aec0
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/concern/GenericConcern.java
@@ -0,0 +1,34 @@
+/*
+ *  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.apache.polygene.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/1c722f44/core/api/src/main/java/org/apache/polygene/api/concern/internal/ConcernFor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/concern/internal/ConcernFor.java b/core/api/src/main/java/org/apache/polygene/api/concern/internal/ConcernFor.java
new file mode 100644
index 0000000..1db879c
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/concern/internal/ConcernFor.java
@@ -0,0 +1,67 @@
+/*
+ *  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.apache.polygene.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.apache.polygene.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/1c722f44/core/api/src/main/java/org/apache/polygene/api/concern/internal/package.html
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/concern/internal/package.html b/core/api/src/main/java/org/apache/polygene/api/concern/internal/package.html
new file mode 100644
index 0000000..7dcd3b6
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/concern/internal/package.html
@@ -0,0 +1,28 @@
+<!--
+  ~  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/1c722f44/core/api/src/main/java/org/apache/polygene/api/concern/package.html
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/concern/package.html b/core/api/src/main/java/org/apache/polygene/api/concern/package.html
new file mode 100644
index 0000000..f9d5d0c
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/concern/package.html
@@ -0,0 +1,24 @@
+<!--
+  ~  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/1c722f44/core/api/src/main/java/org/apache/polygene/api/configuration/Configuration.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/polygene/api/configuration/Configuration.java b/core/api/src/main/java/org/apache/polygene/api/configuration/Configuration.java
new file mode 100644
index 0000000..60da8eb
--- /dev/null
+++ b/core/api/src/main/java/org/apache/polygene/api/configuration/Configuration.java
@@ -0,0 +1,401 @@
+/*
+ *  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.apache.polygene.api.configuration;
+
+import java.io.IOException;
+import java.io.InputStream;
+import org.apache.polygene.api.PolygeneAPI;
+import org.apache.polygene.api.composite.Composite;
+import org.apache.polygene.api.composite.PropertyMapper;
+import org.apache.polygene.api.constraint.ConstraintViolationException;
+import org.apache.polygene.api.entity.EntityBuilder;
+import org.apache.polygene.api.identity.HasIdentity;
+import org.apache.polygene.api.identity.Identity;
+import org.apache.polygene.api.injection.scope.Service;
+import org.apache.polygene.api.injection.scope.Structure;
+import org.apache.polygene.api.injection.scope.This;
+import org.apache.polygene.api.mixin.Mixins;
+import org.apache.polygene.api.service.ServiceComposite;
+import org.apache.polygene.api.service.ServiceDescriptor;
+import org.apache.polygene.api.service.ServiceReference;
+import org.apache.polygene.api.service.qualifier.ServiceTags;
+import org.apache.polygene.api.structure.Module;
+import org.apache.polygene.api.unitofwork.NoSuchEntityTypeException;
+import org.apache.polygene.api.unitofwork.NoSuchEntityException;
+import org.apache.polygene.api.unitofwork.UnitOfWork;
+import org.apache.polygene.api.unitofwork.UnitOfWorkCompletionException;
+import org.apache.polygene.api.unitofwork.UnitOfWorkFactory;
+import org.apache.polygene.api.usecase.Usecase;
+import org.apache.polygene.api.usecase.UsecaseBuilder;
+import org.apache.polygene.api.value.ValueSerialization;
+
+/**
+ * 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.apache.polygene.api.entity.EntityComposite}. The Configuration implementation
+ * will either locate an instance of the given Configuration type in the
+ * persistent store using the reference 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 reference (e.g. "MyService.properties").
+ * If a service is not given a name via the {@code org.apache.polygene.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 Polygene 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 Polygene 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.apache.polygene.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 Polygene 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 PolygeneAPI api;
+
+        @This
+        private ServiceComposite me;
+
+        @Structure
+        private UnitOfWorkFactory uowf;
+
+        @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 = uowf.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 );
+
+            V configuration;
+            try
+            {
+                configuration = uow.get( serviceModel.<V>configurationType(), serviceComposite.identity().get() );
+                uow.pause();
+            }
+            catch( NoSuchEntityException | NoSuchEntityTypeException e )
+            {
+                return (V) initializeConfigurationInstance( serviceComposite, uow, serviceModel, serviceComposite.identity().get() );
+            }
+            return configuration;
+        }
+
+        @SuppressWarnings( "unchecked" )
+        private <V extends HasIdentity> V initializeConfigurationInstance(ServiceComposite serviceComposite,
+                                                                          UnitOfWork uow,
+                                                                          ServiceDescriptor serviceModel,
+                                                                          Identity identity
+        )
+            throws InstantiationException
+        {
+            Module module = api.moduleOf( serviceComposite ).instance();
+            Usecase usecase = UsecaseBuilder.newUsecase( "Configuration:" + me.identity().get() );
+            UnitOfWork buildUow = module.unitOfWorkFactory().newUnitOfWork( usecase );
+
+            Class<?> type = api.serviceDescriptorFor( serviceComposite ).types().findFirst().orElse( null );
+            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,
+                                                Identity 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 HasIdentity> V tryLoadJsonFile(UnitOfWork uow,
+                                                             Class<C> compositeType,
+                                                             Class<V> configType,
+                                                             Identity identity
+        )
+        {
+            return readConfig( uow, compositeType, configType, identity, ValueSerialization.Formats.JSON, ".json" );
+        }
+
+        private <C, V extends HasIdentity> V tryLoadYamlFile(UnitOfWork uow,
+                                                             Class<C> compositeType,
+                                                             Class<V> configType,
+                                                             Identity identity
+        )
+        {
+            return readConfig( uow, compositeType, configType, identity, ValueSerialization.Formats.YAML, ".yaml" );
+        }
+
+        private <C, V extends HasIdentity> V tryLoadXmlFile(UnitOfWork uow,
+                                                            Class<C> compositeType,
+                                                            Class<V> configType,
+                                                            Identity identity
+        )
+        {
+            return readConfig( uow, compositeType, configType, identity, ValueSerialization.Formats.XML, ".xml" );
+        }
+
+        private <C, V extends HasIdentity> V readConfig(UnitOfWork uow,
+                                                        Class<C> compositeType,
+                                                        Class<V> configType,
+                                                        Identity 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( uow.module(), configType, asStream );
+                        return uow.toEntity( configType, configObject );
+                    }
+                }
+            }
+            return null;
+        }
+    }
+}


Mime
View raw message