You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@polygene.apache.org by ni...@apache.org on 2015/07/30 21:48:25 UTC
[26/80] [partial] zest-java git commit: First round of changes to
move to org.apache.zest namespace.
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/MetaInfoDeclaration.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/MetaInfoDeclaration.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/MetaInfoDeclaration.java
new file mode 100644
index 0000000..8cee5f1
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/MetaInfoDeclaration.java
@@ -0,0 +1,221 @@
+/*
+ * Copyright (c) 2008, Michael Hunger 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.apache.zest.bootstrap;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.HashMap;
+import java.util.Map;
+import org.apache.zest.api.common.MetaInfo;
+import org.apache.zest.api.property.Property;
+
+/**
+ * Declaration of a Property or Association.
+ */
+public final class MetaInfoDeclaration
+ implements StateDeclarations, AssociationDeclarations, ManyAssociationDeclarations, NamedAssociationDeclarations
+{
+ Map<Class<?>, InfoHolder<?>> mixinPropertyDeclarations = new HashMap<>();
+
+ public MetaInfoDeclaration()
+ {
+ }
+
+ public <T> MixinDeclaration<T> on( Class<T> mixinType )
+ {
+ @SuppressWarnings( "unchecked" )
+ InfoHolder<T> propertyDeclarationHolder = (InfoHolder<T>) mixinPropertyDeclarations.get( mixinType );
+ if( propertyDeclarationHolder == null )
+ {
+ propertyDeclarationHolder = new InfoHolder<>( mixinType );
+ mixinPropertyDeclarations.put( mixinType, propertyDeclarationHolder );
+ }
+ return propertyDeclarationHolder;
+ }
+
+ @Override
+ public MetaInfo metaInfoFor( AccessibleObject accessor )
+ {
+ for( Map.Entry<Class<?>, InfoHolder<?>> entry : mixinPropertyDeclarations.entrySet() )
+ {
+ InfoHolder<?> holder = entry.getValue();
+ MetaInfo metaInfo = holder.metaInfoFor( accessor );
+ if( metaInfo != null )
+ {
+ Class<?> mixinType = entry.getKey();
+ return metaInfo.withAnnotations( mixinType )
+ .withAnnotations( accessor )
+ .withAnnotations( accessor instanceof Method ? ( (Method) accessor ).getReturnType() : ( (Field) accessor )
+ .getType() );
+ }
+ }
+ // TODO is this code reached at all??
+ Class<?> declaringType = ( (Member) accessor ).getDeclaringClass();
+ return new MetaInfo().withAnnotations( declaringType )
+ .withAnnotations( accessor )
+ .withAnnotations( accessor instanceof Method ? ( (Method) accessor ).getReturnType() : ( (Field) accessor ).getType() );
+ }
+
+ @Override
+ public Object initialValueOf( AccessibleObject accessor )
+ {
+ for( InfoHolder<?> propertyDeclarationHolder : mixinPropertyDeclarations.values() )
+ {
+ final Object initialValue = propertyDeclarationHolder.initialValueOf( accessor );
+ if( initialValue != null )
+ {
+ return initialValue;
+ }
+ }
+ return null;
+ }
+
+ @Override
+ public boolean useDefaults( AccessibleObject accessor )
+ {
+ for( InfoHolder<?> propertyDeclarationHolder : mixinPropertyDeclarations.values() )
+ {
+ final boolean useDefaults = propertyDeclarationHolder.useDefaults( accessor );
+ if( useDefaults )
+ {
+ return useDefaults;
+ }
+ }
+ return false;
+ }
+
+ private static class InfoHolder<T>
+ implements InvocationHandler, StateDeclarations, MixinDeclaration<T>
+ {
+ private final static class MethodInfo
+ {
+ Object initialValue;
+ boolean useDefaults;
+ MetaInfo metaInfo;
+
+ private MethodInfo( MetaInfo metaInfo )
+ {
+ this.metaInfo = metaInfo;
+ }
+ }
+
+ private final Class<T> mixinType;
+ private final Map<AccessibleObject, MethodInfo> methodInfos = new HashMap<>();
+ // temporary holder
+ private MetaInfo metaInfo = null;
+
+ private InfoHolder( Class<T> mixinType )
+ {
+ this.mixinType = mixinType;
+ }
+
+ @Override
+ @SuppressWarnings( "raw" )
+ public Object invoke( Object o, Method method, Object[] objects )
+ throws Throwable
+ {
+ final MethodInfo methodInfo = new MethodInfo( metaInfo );
+ methodInfo.useDefaults = true;
+ methodInfos.put( method, methodInfo );
+ metaInfo = null; // reset
+ final Class<?> returnType = method.getReturnType();
+ try
+ {
+ return Proxy.newProxyInstance( returnType.getClassLoader(), new Class[]{ returnType },
+ new InvocationHandler()
+ {
+ @Override
+ public Object invoke( Object o, Method method, Object[] objects )
+ throws Throwable
+ {
+ if( method.getName().equals( "set" ) )
+ {
+ methodInfo.initialValue = objects[ 0 ];
+ }
+ return null;
+ }
+ } );
+ }
+ catch( IllegalArgumentException e )
+ {
+ throw new IllegalArgumentException(
+ "Only methods with " + Property.class.getName() + " as return type can have declareDefaults()" );
+ }
+ }
+
+ public MethodInfo matches( AccessibleObject accessor )
+ {
+ return methodInfos.get( accessor );
+ }
+
+ @Override
+ public MetaInfo metaInfoFor( AccessibleObject accessor )
+ {
+ final MethodInfo methodInfo = matches( accessor );
+ if( methodInfo == null )
+ {
+ return null;
+ }
+ return methodInfo.metaInfo;
+ }
+
+ @Override
+ public Object initialValueOf( AccessibleObject accessor )
+ {
+ final MethodInfo methodInfo = matches( accessor );
+ if( methodInfo == null )
+ {
+ return null;
+ }
+ return methodInfo.initialValue;
+ }
+
+ @Override
+ public boolean useDefaults( AccessibleObject accessor )
+ {
+ final MethodInfo methodInfo = matches( accessor );
+ if( methodInfo == null )
+ {
+ return false;
+ }
+ return methodInfo.useDefaults;
+ }
+
+ // DSL Interface
+
+ @Override
+ @SuppressWarnings( "raw" )
+ public T declareDefaults()
+ {
+ return mixinType.cast(
+ Proxy.newProxyInstance( mixinType.getClassLoader(), new Class[]{ mixinType }, this ) );
+ }
+
+ @Override
+ public MixinDeclaration<T> setMetaInfo( Object info )
+ {
+ if( metaInfo == null )
+ {
+ metaInfo = new MetaInfo();
+ }
+ metaInfo.set( info );
+ return this;
+ }
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/MixinDeclaration.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/MixinDeclaration.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/MixinDeclaration.java
new file mode 100644
index 0000000..629c9df
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/MixinDeclaration.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2008, Michael Hunger. 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.apache.zest.bootstrap;
+
+/**
+ * Fluent API for declaring information about properties
+ *
+ * @param <T>
+ */
+public interface MixinDeclaration<T>
+{
+ T declareDefaults();
+
+ MixinDeclaration<T> setMetaInfo( Object info );
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ModuleAssembly.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ModuleAssembly.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ModuleAssembly.java
new file mode 100644
index 0000000..6bf4437
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ModuleAssembly.java
@@ -0,0 +1,240 @@
+/*
+ * Copyright 2008 Niclas Hedhman. All rights Reserved.
+ * Copyright 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.apache.zest.bootstrap;
+
+import org.apache.zest.api.activation.Activator;
+import org.apache.zest.api.structure.Module;
+import org.apache.zest.api.type.HasTypes;
+import org.apache.zest.functional.Specification;
+
+/**
+ * The ModuleAssembly is used to register any information about * what the module should contain, such as composites,
+ * entities and services.
+ * <p>
+ * Use the methods and the fluent API's to declare how the module should be constructed.
+ * </p>
+ */
+public interface ModuleAssembly
+{
+ /**
+ * Access the layer assembly for this module.
+ *
+ * @return The Layer containing this Module.
+ */
+ LayerAssembly layer();
+
+ /**
+ * Get an assembly for a particular Module. If this is called many times with the same names, then the same module
+ * is affected.
+ *
+ * @param layerName The name of the Layer
+ * @param moduleName The name of the Module to retrieve or create.
+ *
+ * @return The ModuleAssembly for the Module.
+ */
+ ModuleAssembly module( String layerName, String moduleName );
+
+ /**
+ * Set the name of this module.
+ *
+ * @param name The name that this Module should have.
+ *
+ * @return This instance to support the fluid DSL of bootstrap.
+ */
+ ModuleAssembly setName( String name );
+
+ /**
+ * Access the currently set name for this module.
+ *
+ * @return The name of this Module.
+ */
+ String name();
+
+ ModuleAssembly setMetaInfo( Object info );
+
+ /**
+ * Set the module activators. Activators are executed in order around the
+ * Module activation and passivation.
+ *
+ * @param activators the module activators
+ *
+ * @return the assembly
+ */
+ @SuppressWarnings({ "unchecked", "varargs" })
+ ModuleAssembly withActivators( Class<? extends Activator<Module>>... activators );
+
+ /**
+ * Declare a list of TransientComposites for this Module. Use the TransientDeclaration that is returned to
+ * declare further settings. Note that the TransientDeclaration works on all of the types specified.
+ *
+ * @param transientTypes The types that specifies the Transient types.
+ *
+ * @return An TransientDeclaration for the specified Transient types.
+ */
+ TransientDeclaration transients( Class<?>... transientTypes );
+
+ /**
+ * Given a Specification for TransientAssembly's, returns a TransientDeclaration that can
+ * be used to work with all of the assemblies matched by the specification.
+ *
+ * @param specification The Specification that specifies the TransientComposite types of interest.
+ *
+ * @return An TransientDeclaration for the specified TransientComposite types.
+ */
+ TransientDeclaration transients( Specification<? super TransientAssembly> specification );
+
+ /**
+ * Declare a list of ValueComposites for this Module. Use the ValueDeclaration that is returned to
+ * declare further settings. Note that the ValueDeclaration works on all of the types specified.
+ *
+ * @param valueTypes The types that specifies the Value types.
+ *
+ * @return An ValueDeclaration for the specified Value types.
+ */
+ ValueDeclaration values( Class<?>... valueTypes );
+
+ /**
+ * Given a Specification for ValueAssembly's, returns a ValueDeclaration that can
+ * be used to work with all of the assemblies matched by the specification.
+ *
+ * @param specification The Specification that specifies the ValueComposite types of interest.
+ *
+ * @return An ValueDeclaration for the specified ValueComposite types.
+ */
+ ValueDeclaration values( Specification<? super ValueAssembly> specification );
+
+ /**
+ * Declare a list of EntityComposites for this Module. Use the EntityDeclaration that is returned to
+ * declare further settings. Note that the EntityDeclaration works on all of the types specified.
+ *
+ * @param entityTypes The types that specifies the Entity types.
+ *
+ * @return An EntityDeclaration for the specified Entity types.
+ */
+ EntityDeclaration entities( Class<?>... entityTypes );
+
+ /**
+ * Given a Specification for EntityAssembly's, returns a EntityDeclaration that can
+ * be used to work with all of the assemblies matched by the specification.
+ *
+ * @param specification The Specification that specifies the EntityComposite types of interest.
+ *
+ * @return An EntityDeclaration for the specified EntityComposite types.
+ */
+ EntityDeclaration entities( Specification<? super EntityAssembly> specification );
+
+ /**
+ * Declare a list of Configuration Composites for this Module. Use the ConfigurationDeclaration that is returned to
+ * declare further settings. Note that the ConfigurationDeclaration works on all of the types specified.
+ *
+ * @param configurationTypes The types that specifies the Configuration types.
+ *
+ * @return An ConfigurationDeclaration for the specified Configuration types.
+ */
+ ConfigurationDeclaration configurations( Class<?>... configurationTypes );
+
+ /**
+ * Given a Specification for ConfigurationAssembly's, returns a ConfigurationDeclaration that can
+ * be used to work with all of the assemblies matched by the specification.
+ *
+ * @param specification The Specification that specifies the ConfigurationComposite types of interest.
+ *
+ * @return An ConfigurationDeclaration for the specified EntityComposite types.
+ */
+ ConfigurationDeclaration configurations( Specification<HasTypes> specification );
+
+
+ /**
+ * Declare a list of object classes for this Module. Use the ObjectDeclaration that is returned to
+ * declare further settings. Note that the ObjectDeclaration works on all of the types specified.
+ *
+ * @param objectTypes The types that specifies the Object types.
+ *
+ * @return An ObjectDeclaration for the specified Object types.
+ */
+ ObjectDeclaration objects( Class<?>... objectTypes )
+ throws AssemblyException;
+
+ /**
+ * Given a Specification for ObjectAssembly's, returns a ObjectDeclaration that can
+ * be used to work with all of the assemblies matched by the specification.
+ *
+ * @param specification The Specification that specifies the Object types of interest.
+ *
+ * @return An ObjectDeclaration for the specified Object types.
+ */
+ ObjectDeclaration objects( Specification<? super ObjectAssembly> specification );
+
+ /**
+ * Create a list of ServiceComposites for this Module. Use the ServiceDeclaration that is returned to
+ * declare further settings. This will always create new assemblies for the specified types, instead
+ * of potentially working on already declared types like the services(...) method.
+ *
+ * @param serviceTypes The types that specifies the Service types.
+ *
+ * @return An ServiceDeclaration for the specified Service types.
+ */
+ ServiceDeclaration addServices( Class<?>... serviceTypes );
+
+ /**
+ * Declare a list of ServiceComposites for this Module. Use the ServiceDeclaration that is returned to
+ * declare further settings. Note that the ServiceDeclaration works on all of the types specified.
+ *
+ * @param serviceTypes The types that specifies the Service types.
+ *
+ * @return An ServiceDeclaration for the specified Service types.
+ */
+ ServiceDeclaration services( Class<?>... serviceTypes );
+
+ /**
+ * Given a Specification for ServiceAssembly's, returns a ServiceDeclaration that can
+ * be used to work with all of the assemblies matched by the specification.
+ *
+ * @param specification The Specification that specifies the ServiceComposite types of interest.
+ *
+ * @return An ServiceDeclaration for the specified ServiceComposite types.
+ */
+ ServiceDeclaration services( Specification<? super ServiceAssembly> specification );
+
+ /**
+ * Declare a list of imported services for this Module. Use the ImportedServiceDeclaration that is returned to
+ * declare further settings. Note that the ImportedServiceDeclaration works on all of the types specified.
+ *
+ * @param serviceTypes The types that specifies the Imported Service types.
+ *
+ * @return An ImportedServiceDeclaration for the specified Imported Service types.
+ */
+ ImportedServiceDeclaration importedServices( Class<?>... serviceTypes );
+
+ /**
+ * Given a Specification for ImportedServiceAssembly's, returns a ImportedServiceDeclaration that can
+ * be used to work with all of the assemblies matched by the specification.
+ *
+ * @param specification The Specification that specifies the Imported Service types of interest.
+ *
+ * @return An ImportedServiceDeclaration for the specified Imported Service types.
+ */
+ ImportedServiceDeclaration importedServices( Specification<? super ImportedServiceAssembly> specification );
+
+ <T> MixinDeclaration<T> forMixin( Class<T> mixinType );
+
+ public <ThrowableType extends Throwable> void visit( AssemblyVisitor<ThrowableType> visitor )
+ throws ThrowableType;
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ModuleName.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ModuleName.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ModuleName.java
new file mode 100644
index 0000000..122dfa5
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ModuleName.java
@@ -0,0 +1,36 @@
+/*
+ * 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.apache.zest.bootstrap;
+
+/**
+ * Set the name of the module
+ */
+public final class ModuleName
+ implements Assembler
+{
+ private final String name;
+
+ public ModuleName( String name )
+ {
+ this.name = name;
+ }
+
+ @Override
+ public void assemble( ModuleAssembly module )
+ throws AssemblyException
+ {
+ module.setName( name );
+ }
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/NamedAssociationDeclarations.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/NamedAssociationDeclarations.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/NamedAssociationDeclarations.java
new file mode 100644
index 0000000..b5c8e46
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/NamedAssociationDeclarations.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2008-2011, Rickard Öberg. All Rights Reserved.
+ * Copyright (c) 2011-2013, Niclas Hedhman. All Rights Reserved.
+ * Copyright (c) 2014, Paul Merlin. 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.apache.zest.bootstrap;
+
+import java.lang.reflect.AccessibleObject;
+import org.apache.zest.api.common.MetaInfo;
+
+/**
+ * This provides declared {@link org.apache.zest.api.association.NamedAssociation} information that the runtime can use.
+ */
+public interface NamedAssociationDeclarations
+{
+ MetaInfo metaInfoFor( AccessibleObject accessor );
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ObjectAssembly.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ObjectAssembly.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ObjectAssembly.java
new file mode 100644
index 0000000..f26225c
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ObjectAssembly.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.zest.bootstrap;
+
+import org.apache.zest.api.type.HasTypes;
+
+/**
+ * This represents the assembly information of a single object type in a Module.
+ */
+public interface ObjectAssembly
+ extends HasTypes
+{
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ObjectDeclaration.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ObjectDeclaration.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ObjectDeclaration.java
new file mode 100644
index 0000000..af4c1c9
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ObjectDeclaration.java
@@ -0,0 +1,33 @@
+/*
+ * 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.apache.zest.bootstrap;
+
+import org.apache.zest.api.common.Visibility;
+
+/**
+ * Fluent API for declaring objects.Instances
+ * of this API are acquired by calling {@link ModuleAssembly#objects(Class[])}.
+ */
+public interface ObjectDeclaration
+{
+ ObjectDeclaration setMetaInfo( Object info );
+
+ ObjectDeclaration visibleIn( Visibility visibility )
+ throws IllegalStateException;
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/Qi4jRuntime.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/Qi4jRuntime.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/Qi4jRuntime.java
new file mode 100644
index 0000000..d0914bc
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/Qi4jRuntime.java
@@ -0,0 +1,32 @@
+/*
+ * 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.apache.zest.bootstrap;
+
+import org.apache.zest.api.Qi4j;
+import org.apache.zest.spi.Qi4jSPI;
+
+/**
+ * This interface has to be implemented by Zest runtimes.
+ */
+public interface Qi4jRuntime
+{
+ ApplicationAssemblyFactory applicationAssemblyFactory();
+
+ ApplicationModelFactory applicationModelFactory();
+
+ Qi4j api();
+
+ Qi4jSPI spi();
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/RuntimeFactory.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/RuntimeFactory.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/RuntimeFactory.java
new file mode 100644
index 0000000..e9631af
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/RuntimeFactory.java
@@ -0,0 +1,62 @@
+/*
+ * 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.zest.bootstrap;
+
+/**
+ * Zest runtime factory.
+ */
+public interface RuntimeFactory
+{
+ Qi4jRuntime createRuntime();
+
+ /**
+ * Standalone application Zest runtime factory.
+ */
+ public final class StandaloneApplicationRuntimeFactory
+ implements RuntimeFactory
+ {
+ @Override
+ public Qi4jRuntime createRuntime()
+ {
+ ClassLoader loader = getClass().getClassLoader();
+ try
+ {
+ Class<? extends Qi4jRuntime> runtimeClass = loadRuntimeClass( loader );
+ return runtimeClass.newInstance();
+ }
+ catch( ClassNotFoundException e )
+ {
+ System.err.println( "Zest Runtime jar is not present in the classpath." );
+ }
+ catch( InstantiationException | IllegalAccessException e )
+ {
+ System.err.println( "Invalid Zest Runtime class. If you are providing your own Zest Runtime, please " +
+ "contact qi4j-dev at Google Groups for assistance." );
+ }
+ return null;
+ }
+
+ @SuppressWarnings( { "unchecked" } )
+ private Class<? extends Qi4jRuntime> loadRuntimeClass( ClassLoader loader )
+ throws ClassNotFoundException
+ {
+ return (Class<? extends Qi4jRuntime>) loader.loadClass( "org.qi4j.runtime.Qi4jRuntimeImpl" );
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ServiceAssembly.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ServiceAssembly.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ServiceAssembly.java
new file mode 100644
index 0000000..095c67b
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ServiceAssembly.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.zest.bootstrap;
+
+import org.apache.zest.api.type.HasTypes;
+
+/**
+ * This represents the assembly information of a single ServiceComposite in a Module.
+ */
+public interface ServiceAssembly extends HasTypes
+{
+ String identity();
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ServiceDeclaration.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ServiceDeclaration.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ServiceDeclaration.java
new file mode 100644
index 0000000..dc820d5
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ServiceDeclaration.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2008 Niclas Hedhman. All rights Reserved.
+ * Copyright 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.apache.zest.bootstrap;
+
+import org.apache.zest.api.activation.Activator;
+import org.apache.zest.api.common.Visibility;
+
+/**
+ * Fluent API for declaring services hosted in Zest. Instances
+ * of this API are acquired by calling {@link ModuleAssembly#services(Class[])}.
+ */
+public interface ServiceDeclaration
+{
+ ServiceDeclaration setMetaInfo( Object serviceAttribute );
+
+ ServiceDeclaration visibleIn( Visibility visibility );
+
+ ServiceDeclaration withConcerns( Class<?>... concerns );
+
+ ServiceDeclaration withSideEffects( Class<?>... sideEffects );
+
+ ServiceDeclaration withMixins( Class<?>... mixins );
+
+ ServiceDeclaration withTypes( Class<?>... types );
+
+ ServiceDeclaration identifiedBy( String identity );
+
+ ServiceDeclaration taggedWith( String... tags );
+
+ ServiceDeclaration instantiateOnStartup();
+
+ /**
+ * Set the service activators. Activators are executed in order around the
+ * ServiceReference activation and passivation.
+ *
+ * @param activators the service activators
+ * @return the assembly
+ */
+ @SuppressWarnings( { "unchecked","varargs" } )
+ ServiceDeclaration withActivators( Class<? extends Activator<?>>... activators );
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/SingletonAssembler.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/SingletonAssembler.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/SingletonAssembler.java
new file mode 100644
index 0000000..1666f7a
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/SingletonAssembler.java
@@ -0,0 +1,99 @@
+/*
+ * 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.apache.zest.bootstrap;
+
+import org.apache.zest.api.Qi4j;
+import org.apache.zest.api.activation.ActivationException;
+import org.apache.zest.api.structure.Application;
+import org.apache.zest.api.structure.Module;
+
+/**
+ * Base class for Assembler that creates an Application
+ * with one Layer and one Module. Create a subclass of this
+ * and implement the {@link Assembler#assemble(ModuleAssembly)} method.
+ * Once the SingletonAssembler is instantiated it will have created and activated
+ * an Application which can be accessed from {@link org.apache.zest.bootstrap.SingletonAssembler#application()}.
+ * You can also easily access any resources specific for the single Module, such as the TransientBuilderFactory.
+ */
+public abstract class SingletonAssembler
+ implements Assembler
+{
+ private Energy4Java qi4j;
+ private Application applicationInstance;
+ private final Module moduleInstance;
+
+ /**
+ * Creates a Zest Runtime instance containing one Layer with one Module.
+ * The Layer will be named "Layer 1" and the Module will be named "Module 1". It is possible to add
+ * additional layers and modules via the Assembler interface that must be implemented in the subclass of this
+ * class.
+ *
+ * @throws AssemblyException Either if the model can not be created from the disk, or some inconsistency in
+ * the programming model makes it impossible to create it.
+ * @throws ActivationException If the automatic {@code activate()} method is throwing this Exception..
+ */
+ public SingletonAssembler()
+ throws AssemblyException, ActivationException
+ {
+// START SNIPPET: actual
+ qi4j = new Energy4Java();
+ applicationInstance = qi4j.newApplication( new ApplicationAssembler()
+ {
+ @Override
+ public ApplicationAssembly assemble( ApplicationAssemblyFactory applicationFactory )
+ throws AssemblyException
+ {
+ return applicationFactory.newApplicationAssembly( SingletonAssembler.this );
+ }
+ } );
+
+ try
+ {
+ beforeActivation( applicationInstance );
+ applicationInstance.activate();
+ }
+ catch( Exception e )
+ {
+ if( e instanceof ActivationException )
+ {
+ throw ( (ActivationException) e );
+ }
+ throw new ActivationException( "Could not activate application", e );
+ }
+// START SNIPPET: actual
+
+ moduleInstance = applicationInstance.findModule( "Layer 1", "Module 1" );
+ }
+
+ public final Qi4j runtime()
+ {
+ return qi4j.spi();
+ }
+
+ public final Application application()
+ {
+ return applicationInstance;
+ }
+
+ public final Module module()
+ {
+ return moduleInstance;
+ }
+
+ protected void beforeActivation( Application application )
+ throws Exception
+ {
+ }
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/StateDeclarations.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/StateDeclarations.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/StateDeclarations.java
new file mode 100644
index 0000000..ad060b2
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/StateDeclarations.java
@@ -0,0 +1,30 @@
+/*
+ * 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.apache.zest.bootstrap;
+
+import java.lang.reflect.AccessibleObject;
+import org.apache.zest.api.common.MetaInfo;
+
+/**
+ * This provides declared {@link org.apache.zest.api.property.Property} information that the runtime can use.
+ */
+public interface StateDeclarations
+{
+ MetaInfo metaInfoFor( AccessibleObject accessor );
+
+ Object initialValueOf( AccessibleObject accessor );
+
+ boolean useDefaults( AccessibleObject accessor );
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/TransientAssembly.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/TransientAssembly.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/TransientAssembly.java
new file mode 100644
index 0000000..7d8db10
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/TransientAssembly.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.zest.bootstrap;
+
+import org.apache.zest.api.type.HasTypes;
+
+/**
+ * This represents the assembly information of a single TransientComposite in a Module.
+ */
+public interface TransientAssembly
+ extends HasTypes
+{
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/TransientDeclaration.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/TransientDeclaration.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/TransientDeclaration.java
new file mode 100644
index 0000000..2709595
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/TransientDeclaration.java
@@ -0,0 +1,40 @@
+/*
+ * 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.apache.zest.bootstrap;
+
+import org.apache.zest.api.common.Visibility;
+
+/**
+ * Fluent API for declaring TransientComposites. Instances
+ * of this API are acquired by calling {@link ModuleAssembly#transients(Class[])}.
+ */
+public interface TransientDeclaration
+{
+ TransientDeclaration setMetaInfo( Object info );
+
+ TransientDeclaration visibleIn( Visibility visibility );
+
+ TransientDeclaration withConcerns( Class<?>... concerns );
+
+ TransientDeclaration withSideEffects( Class<?>... sideEffects );
+
+ TransientDeclaration withMixins( Class<?>... mixins );
+
+ TransientDeclaration withTypes( Class<?>... roles );
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ValueAssembly.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ValueAssembly.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ValueAssembly.java
new file mode 100644
index 0000000..98a242a
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ValueAssembly.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.zest.bootstrap;
+
+import org.apache.zest.api.type.HasTypes;
+
+/**
+ * This represents the assembly information of a single ValueComposite in a Module.
+ */
+public interface ValueAssembly
+ extends HasTypes
+{
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ValueDeclaration.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ValueDeclaration.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ValueDeclaration.java
new file mode 100644
index 0000000..5392d2c
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/ValueDeclaration.java
@@ -0,0 +1,39 @@
+/*
+ * 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.apache.zest.bootstrap;
+
+import org.apache.zest.api.common.Visibility;
+
+/**
+ * Fluent API for declaring values
+ */
+public interface ValueDeclaration
+{
+ ValueDeclaration setMetaInfo( Object info );
+
+ ValueDeclaration visibleIn( Visibility visibility );
+
+ ValueDeclaration withConcerns( Class<?>... concerns );
+
+ ValueDeclaration withSideEffects( Class<?>... sideEffects );
+
+ ValueDeclaration withMixins( Class<?>... mixins );
+
+ ValueDeclaration withTypes( Class<?>... roles );
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/builder/ApplicationBuilder.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/builder/ApplicationBuilder.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/builder/ApplicationBuilder.java
new file mode 100644
index 0000000..5532ae7
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/builder/ApplicationBuilder.java
@@ -0,0 +1,250 @@
+/*
+ * Copyright 2014 Niclas Hedhman.
+ * Copyright 2014 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.apache.zest.bootstrap.builder;
+
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Scanner;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.apache.zest.api.activation.ActivationEventListener;
+import org.apache.zest.api.activation.ActivationEventListenerRegistration;
+import org.apache.zest.api.activation.ActivationException;
+import org.apache.zest.api.activation.ApplicationPassivationThread;
+import org.apache.zest.api.structure.Application;
+import org.apache.zest.api.structure.ApplicationDescriptor;
+import org.apache.zest.bootstrap.ApplicationAssembler;
+import org.apache.zest.bootstrap.ApplicationAssembly;
+import org.apache.zest.bootstrap.ApplicationAssemblyFactory;
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.Energy4Java;
+import org.apache.zest.bootstrap.LayerAssembly;
+
+/**
+ * Application Builder.
+ */
+public class ApplicationBuilder
+ implements ActivationEventListenerRegistration
+{
+ private final String applicationName;
+ private final Map<String, LayerDeclaration> layers = new HashMap<>();
+ private final List<ActivationEventListener> activationListeners = new ArrayList<>();
+
+ public ApplicationBuilder( String applicationName )
+ {
+ this.applicationName = applicationName;
+ }
+
+ /**
+ * Create and activate a new Application.
+ * @return Activated Application
+ * @throws AssemblyException if the assembly failed
+ * @throws ActivationException if the activation failed
+ */
+ public Application newApplication()
+ throws AssemblyException, ActivationException
+ {
+ Energy4Java qi4j = new Energy4Java();
+ ApplicationDescriptor model = qi4j.newApplicationModel( new ApplicationAssembler()
+ {
+ @Override
+ public ApplicationAssembly assemble( ApplicationAssemblyFactory factory )
+ throws AssemblyException
+ {
+ ApplicationAssembly assembly = factory.newApplicationAssembly();
+ assembly.setName( applicationName );
+ HashMap<String, LayerAssembly> createdLayers = new HashMap<>();
+ for( Map.Entry<String, LayerDeclaration> entry : layers.entrySet() )
+ {
+ LayerAssembly layer = entry.getValue().createLayer( assembly );
+ createdLayers.put( entry.getKey(), layer );
+ }
+ for( LayerDeclaration layer : layers.values() )
+ {
+ layer.initialize( createdLayers );
+ }
+ return assembly;
+ }
+ } );
+ Application application = model.newInstance( qi4j.api() );
+ for( ActivationEventListener activationListener : activationListeners )
+ {
+ application.registerActivationEventListener( activationListener );
+ }
+ beforeActivation();
+ application.activate();
+ afterActivation();
+ return application;
+ }
+
+ /**
+ * Called before application activation.
+ */
+ protected void beforeActivation()
+ {
+ }
+
+ /**
+ * Called after application activation.
+ */
+ protected void afterActivation()
+ {
+ }
+
+ @Override
+ public void registerActivationEventListener( ActivationEventListener listener )
+ {
+ activationListeners.add( listener );
+ }
+
+ @Override
+ public void deregisterActivationEventListener( ActivationEventListener listener )
+ {
+ activationListeners.remove( listener );
+ }
+
+ /**
+ * Declare Layer.
+ * @param layerName Name of the Layer
+ * @return Layer declaration for the given name, new if did not already exists
+ */
+ public LayerDeclaration withLayer( String layerName )
+ {
+ LayerDeclaration layerDeclaration = layers.get( layerName );
+ if( layerDeclaration != null )
+ {
+ return layerDeclaration;
+ }
+ layerDeclaration = new LayerDeclaration( layerName );
+ layers.put( layerName, layerDeclaration );
+ return layerDeclaration;
+ }
+
+ /**
+ * Load an ApplicationBuilder from a JSON String.
+ * @param json JSON String
+ * @return Application Builder loaded from JSON
+ * @throws JSONException if unable to read JSON
+ * @throws AssemblyException if unable to declare the assembly
+ */
+ public static ApplicationBuilder fromJson( String json )
+ throws JSONException, AssemblyException
+ {
+ JSONObject root = new JSONObject( json );
+ return fromJson( root );
+ }
+
+ /**
+ * Load an ApplicationBuilder from a JSON InputStream.
+ * @param json JSON input
+ * @return Application Builder loaded from JSON
+ * @throws JSONException if unable to read JSON
+ * @throws AssemblyException if unable to declare the assembly
+ */
+ public static ApplicationBuilder fromJson( InputStream json )
+ throws JSONException, AssemblyException
+ {
+ String jsonString = new Scanner( json, "UTF-8" ).useDelimiter( "\\A" ).next();
+ return fromJson( jsonString );
+ }
+
+ /**
+ * Load an ApplicationBuilder from a JSONObject.
+ * @param root JSON object
+ * @return Application Builder loaded from JSON
+ * @throws JSONException if unable to read JSON
+ * @throws AssemblyException if unable to declare the assembly
+ */
+ public static ApplicationBuilder fromJson( JSONObject root )
+ throws JSONException, AssemblyException
+ {
+ String applicationName = root.getString( "name" );
+ ApplicationBuilder builder = new ApplicationBuilder( applicationName );
+ builder.configureWithJson( root );
+ return builder;
+ }
+
+ /** Configures the application struucture from a JSON document.
+ *
+ * @param root The JSON document root.
+ * @throws JSONException if the JSON document isn't valid.
+ * @throws AssemblyException if probelms in the Assemblers provided in the JSON document.
+ */
+ protected void configureWithJson( JSONObject root )
+ throws JSONException, AssemblyException
+ {
+ JSONArray layers = root.optJSONArray( "layers" );
+ if( layers != null )
+ {
+ for( int i = 0; i < layers.length(); i++ )
+ {
+ JSONObject layerObject = layers.getJSONObject( i );
+ String layerName = layerObject.getString( "name" );
+ LayerDeclaration layerDeclaration = withLayer( layerName );
+ JSONArray using = layerObject.optJSONArray( "uses" );
+ if( using != null )
+ {
+ for( int j = 0; j < using.length(); j++ )
+ {
+ layerDeclaration.using( using.getString( j ) );
+ }
+ }
+ JSONArray modules = layerObject.optJSONArray( "modules" );
+ if( modules != null )
+ {
+ for( int k = 0; k < modules.length(); k++ )
+ {
+ JSONObject moduleObject = modules.getJSONObject( k );
+ String moduleName = moduleObject.getString( "name" );
+ ModuleDeclaration moduleDeclaration = layerDeclaration.withModule( moduleName );
+ JSONArray assemblers = moduleObject.optJSONArray( "assemblers" );
+ if( assemblers != null )
+ {
+ for( int m = 0; m < assemblers.length(); m++ )
+ {
+ String string = assemblers.getString( m );
+ moduleDeclaration.withAssembler( string );
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ /**
+ * {@literal main} method that read JSON from STDIN.
+ * <p>Passivation exceptions are written to STDERR if any.</p>
+ * @param args Unused
+ * @throws JSONException if unable to read JSON
+ * @throws AssemblyException if the assembly failed
+ * @throws ActivationException if the activation failed
+ */
+ public static void main( String[] args )
+ throws JSONException, ActivationException, AssemblyException
+ {
+ ApplicationBuilder builder = fromJson( System.in );
+ Application application = builder.newApplication();
+ Runtime.getRuntime().addShutdownHook( new ApplicationPassivationThread( application, System.err ) );
+ }
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/builder/LayerDeclaration.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/builder/LayerDeclaration.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/builder/LayerDeclaration.java
new file mode 100644
index 0000000..cacd282
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/builder/LayerDeclaration.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2014 Niclas Hedhman.
+ * Copyright 2014 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.apache.zest.bootstrap.builder;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import org.apache.zest.bootstrap.ApplicationAssembly;
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.LayerAssembly;
+import org.apache.zest.bootstrap.ModuleAssembly;
+import org.apache.zest.functional.Iterables;
+
+/**
+ * Provides declared {@link org.apache.zest.api.structure.Layer} information that the {@link ApplicationBuilder} can use.
+ */
+public class LayerDeclaration
+{
+ private final String layerName;
+ private final List<String> using = new ArrayList<>();
+ private final Map<String, ModuleDeclaration> modules = new HashMap<>();
+ private LayerAssembly layer;
+
+ LayerDeclaration( String layerName )
+ {
+ this.layerName = layerName;
+ }
+
+ /**
+ * Declare using layer.
+ * @param layerName Used layer name
+ * @return This Layer declaration
+ */
+ public LayerDeclaration using( String layerName )
+ {
+ this.using.add( layerName );
+ return this;
+ }
+
+ /**
+ * Declare using layers.
+ * @param layerNames Used layers names
+ * @return This Layer declaration
+ */
+ public LayerDeclaration using( Iterable<String> layerNames )
+ {
+ Iterables.addAll( using, layerNames );
+ return this;
+ }
+
+ /**
+ * Declare Module.
+ * @param moduleName Name of the Module
+ * @return Module declaration for the given name, new if did not already exists
+ */
+ public ModuleDeclaration withModule( String moduleName )
+ {
+ ModuleDeclaration module = modules.get( moduleName );
+ if( module != null )
+ {
+ return module;
+ }
+ module = new ModuleDeclaration( moduleName );
+ modules.put( moduleName, module );
+ return module;
+ }
+
+ LayerAssembly createLayer( ApplicationAssembly application )
+ {
+ layer = application.layer( layerName );
+ layer.setName( layerName );
+ for( ModuleDeclaration module : modules.values() )
+ {
+ ModuleAssembly assembly = module.createModule( layer );
+ }
+ return layer;
+ }
+
+ void initialize( HashMap<String, LayerAssembly> createdLayers )
+ throws AssemblyException
+ {
+ for( String uses : using )
+ {
+ LayerAssembly usedLayer = createdLayers.get( uses );
+ layer.uses( usedLayer );
+ }
+ for( ModuleDeclaration module : modules.values() )
+ {
+ module.initialize();
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/builder/ModuleDeclaration.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/builder/ModuleDeclaration.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/builder/ModuleDeclaration.java
new file mode 100644
index 0000000..065e9d8
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/builder/ModuleDeclaration.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright 2014 Niclas Hedhman.
+ * Copyright 2014 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.apache.zest.bootstrap.builder;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.zest.bootstrap.Assembler;
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.LayerAssembly;
+import org.apache.zest.bootstrap.ModuleAssembly;
+
+import static org.apache.zest.api.util.Classes.isAssignableFrom;
+import static org.apache.zest.functional.Iterables.filter;
+import static org.apache.zest.functional.Iterables.toList;
+import static org.apache.zest.functional.Specifications.not;
+
+/**
+ * Provides declared {@link org.apache.zest.api.structure.Module} information that the {@link ApplicationBuilder} can use.
+ */
+public class ModuleDeclaration
+{
+ private final String moduleName;
+ private final List<Assembler> assemblers = new ArrayList<>();
+ private ModuleAssembly module;
+
+ public ModuleDeclaration( String moduleName )
+ {
+ this.moduleName = moduleName;
+ }
+
+ /**
+ * Declare Assembler.
+ * @param assembler Assembler instance
+ * @return This Module declaration
+ */
+ public ModuleDeclaration withAssembler( Assembler assembler )
+ {
+ assemblers.add( assembler );
+ return this;
+ }
+
+ /**
+ * Declare Assembler.
+ * @param classname Assembler class name
+ * @return This Module declaration
+ * @throws AssemblyException if unable to load class, not an Assembler or unable to instanciate
+ */
+ public ModuleDeclaration withAssembler( String classname )
+ throws AssemblyException
+ {
+ Class<? extends Assembler> clazz = loadClass( classname );
+ return withAssembler( clazz );
+ }
+
+ /**
+ * Declare Assembler.
+ * @param assemblerClass Assembler class
+ * @return This Module declaration
+ * @throws AssemblyException not an Assembler or if unable to instanciate
+ */
+ public ModuleDeclaration withAssembler( Class<?> assemblerClass )
+ throws AssemblyException
+ {
+ Assembler assembler = createAssemblerInstance( assemblerClass );
+ assemblers.add( assembler );
+ return this;
+ }
+
+ /**
+ * Declare Assemblers.
+ * <p>Declare several Assemblers from an Iterable of Class objects.</p>
+ * <p>Typically used along {@link org.apache.zest.bootstrap.ClassScanner}.</p>
+ * @param assemblerClasses Assembler classes
+ * @return This Module declaration
+ * @throws AssemblyException if one of the Class is not an Assembler or unable to instanciate
+ */
+ public ModuleDeclaration withAssemblers( Iterable<Class<?>> assemblerClasses )
+ throws AssemblyException
+ {
+ List<Class<?>> notAssemblers = toList(
+ filter( not( isAssignableFrom( Assembler.class ) ),
+ assemblerClasses )
+ );
+ if( !notAssemblers.isEmpty() )
+ {
+ throw new AssemblyException(
+ "Classes " + notAssemblers + " are not implementing " + Assembler.class.getName()
+ );
+ }
+ for( Class<?> assemblerClass : assemblerClasses )
+ {
+ withAssembler( assemblerClass );
+ }
+ return this;
+ }
+
+ ModuleAssembly createModule( LayerAssembly layer )
+ {
+ module = layer.module( moduleName );
+ return module;
+ }
+
+ void initialize()
+ throws AssemblyException
+ {
+ for( Assembler assembler : assemblers )
+ {
+ assembler.assemble( module );
+ }
+ }
+
+ @SuppressWarnings( "unchecked" )
+ private Class<? extends Assembler> loadClass( String classname )
+ throws AssemblyException
+ {
+ Class<?> clazz;
+ try
+ {
+ clazz = getClass().getClassLoader().loadClass( classname );
+ }
+ catch( Exception e )
+ {
+ throw new AssemblyException( "Unable to load class " + classname, e );
+ }
+ if( !Assembler.class.isAssignableFrom( clazz ) )
+ {
+ throw new AssemblyException(
+ "Class " + classname + " is not implementing " + Assembler.class.getName()
+ );
+ }
+ //noinspection unchecked
+ return (Class<? extends Assembler>) clazz;
+ }
+
+ private Assembler createAssemblerInstance( Class<?> assemblerClass )
+ throws AssemblyException
+ {
+ if( !Assembler.class.isAssignableFrom( assemblerClass ) )
+ {
+ throw new AssemblyException(
+ "Class " + assemblerClass + " is not implementing " + Assembler.class.getName()
+ );
+ }
+ try
+ {
+ return (Assembler) assemblerClass.newInstance();
+ }
+ catch( Exception e )
+ {
+ throw new AssemblyException( "Unable to instantiate " + assemblerClass, e );
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/builder/package.html
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/builder/package.html b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/builder/package.html
new file mode 100644
index 0000000..663b016
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/builder/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>
+ <h2>Application Builder.</h2>
+ <p>
+ Generic ApplicationBuilder, which simplifies the creation of Application Structure, either by a fluid DSL
+ or from a JSON file.
+ </p>
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/LayerAssembler.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/LayerAssembler.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/LayerAssembler.java
new file mode 100644
index 0000000..4522acd
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/LayerAssembler.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.zest.bootstrap.layered;
+
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.LayerAssembly;
+
+public interface LayerAssembler
+{
+ LayerAssembly assemble( LayerAssembly layer )
+ throws AssemblyException;
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/LayeredApplicationAssembler.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/LayeredApplicationAssembler.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/LayeredApplicationAssembler.java
new file mode 100644
index 0000000..a55fb9c
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/LayeredApplicationAssembler.java
@@ -0,0 +1,212 @@
+/*
+ * 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.zest.bootstrap.layered;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.HashMap;
+import org.apache.zest.api.activation.ActivationException;
+import org.apache.zest.api.activation.PassivationException;
+import org.apache.zest.api.structure.Application;
+import org.apache.zest.api.structure.ApplicationDescriptor;
+import org.apache.zest.bootstrap.ApplicationAssembler;
+import org.apache.zest.bootstrap.ApplicationAssembly;
+import org.apache.zest.bootstrap.ApplicationAssemblyFactory;
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.Energy4Java;
+import org.apache.zest.bootstrap.LayerAssembly;
+
+public abstract class LayeredApplicationAssembler
+ implements ApplicationAssembler
+{
+ protected Application application;
+ protected String name;
+ protected String version;
+ private final Application.Mode mode;
+ private ApplicationAssembly assembly;
+
+ private HashMap<Class<? extends LayerAssembler>, LayerAssembler> assemblers = new HashMap<>();
+
+ public LayeredApplicationAssembler( String name, String version, Application.Mode mode )
+ throws AssemblyException
+ {
+ this.name = name;
+ this.version = version;
+ this.mode = mode;
+ Energy4Java qi4j = new Energy4Java();
+ ApplicationDescriptor model = qi4j.newApplicationModel( this );
+ onModelCreated( model );
+ instantiateApplication( qi4j, model );
+ }
+
+ public ApplicationAssembly assembly()
+ {
+ return assembly;
+ }
+
+ /**
+ * This method is called from the constructor to instantiate the Zest application from the application model.
+ *
+ * <p>
+ * The default implementation simply calls;
+ * </p>
+ * <pre><code>
+ * application = model.newInstance( qi4j.spi() );
+ * </code></pre>
+ *
+ * @param qi4j The Zest runtime engine.
+ * @param model The application model descriptor.
+ */
+ protected void instantiateApplication( Energy4Java qi4j, ApplicationDescriptor model )
+ {
+ application = model.newInstance( qi4j.spi() );
+ }
+
+ /**
+ * This method is called after the Application Model has been created, before the instantiation of the Zest
+ * application.
+ *
+ * <p>
+ * The default implementation does nothing. Applications may have advanced features to inspect or
+ * modify the model prior to instantiation, and this is the place where such advanced manipulation is
+ * expected to take place.
+ * </p>
+ *
+ * @param model
+ */
+ protected void onModelCreated( ApplicationDescriptor model )
+ {
+ }
+
+ public Application application()
+ {
+ return application;
+ }
+
+ public void start()
+ throws ActivationException
+ {
+ application.activate();
+ }
+
+ public void stop()
+ throws PassivationException
+ {
+ application.passivate();
+ }
+
+ @Override
+ public ApplicationAssembly assemble( ApplicationAssemblyFactory applicationFactory )
+ throws AssemblyException
+ {
+ assembly = applicationFactory.newApplicationAssembly();
+ assembly.setName( name );
+ assembly.setVersion( version );
+ assembly.setMode( mode );
+ assembleLayers( assembly );
+ return assembly;
+ }
+
+ protected LayerAssembly createLayer( Class<? extends LayerAssembler> layerAssemblerClass )
+ throws IllegalArgumentException
+ {
+ try
+ {
+ String classname = layerAssemblerClass.getSimpleName();
+ if( classname.endsWith( "Layer" ) )
+ {
+ classname = classname.substring( 0, classname.length() - 5 ) + " Layer";
+ }
+ setNameIfPresent( layerAssemblerClass, classname );
+ LayerAssembly layer = assembly.layer( classname );
+
+ LayerAssembler layerAssembler = instantiateAssembler( layerAssemblerClass, layer );
+ assemblers.put( layerAssemblerClass, layerAssembler );
+ LayerAssembly assembly = layerAssembler.assemble( layer );
+ if( assembly == null )
+ {
+ // Assume that people forgot, and let's not require a "return layer", since we can do that ourselves.
+ return layer;
+ }
+ return assembly;
+ }
+ catch( Exception e )
+ {
+ throw new IllegalArgumentException( "Unable to instantiate layer with " + layerAssemblerClass.getSimpleName(), e );
+ }
+ }
+
+ private LayerAssembler instantiateAssembler( Class<? extends LayerAssembler> layerAssemblerClass,
+ LayerAssembly layer
+ )
+ throws InstantiationException, IllegalAccessException, java.lang.reflect.InvocationTargetException
+ {
+ LayerAssembler layerAssembler;
+ try
+ {
+ Constructor<? extends LayerAssembler> assemblyConstructor = layerAssemblerClass.getConstructor( LayerAssembly.class );
+ layerAssembler = assemblyConstructor.newInstance( layer );
+ }
+ catch( NoSuchMethodException e )
+ {
+ // Use default constructor then.
+ layerAssembler = layerAssemblerClass.newInstance();
+ }
+ return layerAssembler;
+ }
+
+ static void setNameIfPresent( Class<?> clazz, String classname )
+ throws IllegalAccessException
+ {
+ try
+ {
+ Field field = clazz.getDeclaredField( "NAME" );
+ if( Modifier.isStatic( field.getModifiers() ) )
+ {
+ field.setAccessible( true );
+ field.set( null, classname );
+ }
+ }
+ catch( Exception e )
+ {
+ // Ignore and consider normal.
+ }
+ }
+
+ @SuppressWarnings( "unchecked" )
+ protected <T extends LayerAssembler> T assemblerOf( Class<T> layerAssemblerClass )
+ {
+ return (T) assemblers.get( layerAssemblerClass );
+ }
+
+ /**
+ * Called from the constructor to assemble the layers in the applcation.
+ *
+ * <p>
+ * This method must be implemented, and is typically a list of LayerAssmebler instantitations, followed
+ * by {@link LayerAssembly#uses(LayerAssembly...)} declarations.
+ * </p>
+ * <pre><code>
+ *
+ * </code></pre>
+ */
+ protected abstract void assembleLayers( ApplicationAssembly assembly )
+ throws AssemblyException;
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/LayeredLayerAssembler.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/LayeredLayerAssembler.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/LayeredLayerAssembler.java
new file mode 100644
index 0000000..920ef54
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/LayeredLayerAssembler.java
@@ -0,0 +1,86 @@
+/*
+ * 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.zest.bootstrap.layered;
+
+import java.lang.reflect.Constructor;
+import java.util.HashMap;
+import org.apache.zest.bootstrap.LayerAssembly;
+import org.apache.zest.bootstrap.ModuleAssembly;
+
+public abstract class LayeredLayerAssembler
+ implements LayerAssembler
+{
+ private HashMap<Class<? extends ModuleAssembler>, ModuleAssembler> assemblers = new HashMap<>();
+
+ protected ModuleAssembly createModule( LayerAssembly layer, Class<? extends ModuleAssembler> modulerAssemblerClass )
+ {
+ try
+ {
+ ModuleAssembler moduleAssembler = instantiateAssembler( layer, modulerAssemblerClass );
+ String moduleName = createModuleName( modulerAssemblerClass );
+ LayeredApplicationAssembler.setNameIfPresent( modulerAssemblerClass, moduleName );
+ ModuleAssembly module = layer.module( moduleName );
+ assemblers.put( modulerAssemblerClass, moduleAssembler );
+ ModuleAssembly assembly = moduleAssembler.assemble( layer, module );
+ if( assembly == null )
+ {
+ return module;
+ }
+ return assembly;
+ }
+ catch( Exception e )
+ {
+ throw new IllegalArgumentException( "Unable to instantiate module with " + modulerAssemblerClass.getSimpleName(), e );
+ }
+ }
+
+ protected String createModuleName( Class<? extends ModuleAssembler> modulerAssemblerClass )
+ {
+ String moduleName = modulerAssemblerClass.getSimpleName();
+ if( moduleName.endsWith( "Module" ) )
+ {
+ moduleName = moduleName.substring( 0, moduleName.length() - 6 ) + " Module";
+ }
+ return moduleName;
+ }
+
+ private ModuleAssembler instantiateAssembler( LayerAssembly layer,
+ Class<? extends ModuleAssembler> modulerAssemblerClass
+ )
+ throws InstantiationException, IllegalAccessException, java.lang.reflect.InvocationTargetException
+ {
+ ModuleAssembler moduleAssembler;
+ try
+ {
+ Constructor<? extends ModuleAssembler> assemblyConstructor = modulerAssemblerClass.getConstructor( ModuleAssembly.class );
+ moduleAssembler = assemblyConstructor.newInstance( layer );
+ }
+ catch( NoSuchMethodException e )
+ {
+ moduleAssembler = modulerAssemblerClass.newInstance();
+ }
+ return moduleAssembler;
+ }
+
+ @SuppressWarnings( "unchecked" )
+ protected <T extends ModuleAssembler> T assemblerOf( Class<T> moduleAssemblerType )
+ {
+ return (T) assemblers.get( moduleAssemblerType );
+ }
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/ModuleAssembler.java
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/ModuleAssembler.java b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/ModuleAssembler.java
new file mode 100644
index 0000000..b277c82
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/ModuleAssembler.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.zest.bootstrap.layered;
+
+import org.apache.zest.bootstrap.AssemblyException;
+import org.apache.zest.bootstrap.LayerAssembly;
+import org.apache.zest.bootstrap.ModuleAssembly;
+
+public interface ModuleAssembler
+{
+ ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module )
+ throws AssemblyException;
+}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/package.html
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/package.html b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/package.html
new file mode 100644
index 0000000..60cdec2
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/layered/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>Layered Assembly.</h2>
+ </body>
+</html>
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/bootstrap/src/main/java/org/apache/zest/bootstrap/package.html
----------------------------------------------------------------------
diff --git a/core/bootstrap/src/main/java/org/apache/zest/bootstrap/package.html b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/package.html
new file mode 100644
index 0000000..0458761
--- /dev/null
+++ b/core/bootstrap/src/main/java/org/apache/zest/bootstrap/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>Assembly and Bootstrap API.</h2>
+ </body>
+</html>