http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/MetaInfoDeclaration.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/MetaInfoDeclaration.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/MetaInfoDeclaration.java new file mode 100644 index 0000000..0e55aba --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.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.qi4j.api.common.MetaInfo; +import org.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/MixinDeclaration.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/MixinDeclaration.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/MixinDeclaration.java new file mode 100644 index 0000000..719600a --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/ModuleAssembly.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/ModuleAssembly.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/ModuleAssembly.java new file mode 100644 index 0000000..4e473b4 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.bootstrap; + +import org.qi4j.api.activation.Activator; +import org.qi4j.api.structure.Module; +import org.qi4j.api.type.HasTypes; +import org.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/ModuleName.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/ModuleName.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/ModuleName.java new file mode 100644 index 0000000..e8a9a20 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/NamedAssociationDeclarations.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/NamedAssociationDeclarations.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/NamedAssociationDeclarations.java new file mode 100644 index 0000000..54a4257 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.bootstrap; + +import java.lang.reflect.AccessibleObject; +import org.qi4j.api.common.MetaInfo; + +/** + * This provides declared {@link org.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/ObjectAssembly.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/ObjectAssembly.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/ObjectAssembly.java new file mode 100644 index 0000000..e424cf6 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.bootstrap; + +import org.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/ObjectDeclaration.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/ObjectDeclaration.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/ObjectDeclaration.java new file mode 100644 index 0000000..278d6ff --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.bootstrap; + +import org.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/Qi4jRuntime.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/Qi4jRuntime.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/Qi4jRuntime.java new file mode 100644 index 0000000..76e6130 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.bootstrap; + +import org.qi4j.api.Qi4j; +import org.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/RuntimeFactory.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/RuntimeFactory.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/RuntimeFactory.java new file mode 100644 index 0000000..b4efd24 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/ServiceAssembly.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/ServiceAssembly.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/ServiceAssembly.java new file mode 100644 index 0000000..27ce698 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.bootstrap; + +import org.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/ServiceDeclaration.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/ServiceDeclaration.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/ServiceDeclaration.java new file mode 100644 index 0000000..c566c59 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.bootstrap; + +import org.qi4j.api.activation.Activator; +import org.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/SingletonAssembler.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/SingletonAssembler.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/SingletonAssembler.java new file mode 100644 index 0000000..7d2542d --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.bootstrap; + +import org.qi4j.api.Qi4j; +import org.qi4j.api.activation.ActivationException; +import org.qi4j.api.structure.Application; +import org.qi4j.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.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/StateDeclarations.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/StateDeclarations.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/StateDeclarations.java new file mode 100644 index 0000000..39a69b8 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.bootstrap; + +import java.lang.reflect.AccessibleObject; +import org.qi4j.api.common.MetaInfo; + +/** + * This provides declared {@link org.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/TransientAssembly.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/TransientAssembly.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/TransientAssembly.java new file mode 100644 index 0000000..f3e2a58 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.bootstrap; + +import org.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/TransientDeclaration.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/TransientDeclaration.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/TransientDeclaration.java new file mode 100644 index 0000000..a974f73 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.bootstrap; + +import org.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/ValueAssembly.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/ValueAssembly.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/ValueAssembly.java new file mode 100644 index 0000000..9f98406 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.bootstrap; + +import org.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/ValueDeclaration.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/ValueDeclaration.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/ValueDeclaration.java new file mode 100644 index 0000000..490ae87 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.bootstrap; + +import org.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/builder/ApplicationBuilder.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/builder/ApplicationBuilder.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/builder/ApplicationBuilder.java new file mode 100644 index 0000000..d68a3d5 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.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.qi4j.api.activation.ActivationEventListener; +import org.qi4j.api.activation.ActivationEventListenerRegistration; +import org.qi4j.api.activation.ActivationException; +import org.qi4j.api.activation.ApplicationPassivationThread; +import org.qi4j.api.structure.Application; +import org.qi4j.api.structure.ApplicationDescriptor; +import org.qi4j.bootstrap.ApplicationAssembler; +import org.qi4j.bootstrap.ApplicationAssembly; +import org.qi4j.bootstrap.ApplicationAssemblyFactory; +import org.qi4j.bootstrap.AssemblyException; +import org.qi4j.bootstrap.Energy4Java; +import org.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/builder/LayerDeclaration.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/builder/LayerDeclaration.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/builder/LayerDeclaration.java new file mode 100644 index 0000000..0a30bbe --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.bootstrap.builder; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import org.qi4j.bootstrap.ApplicationAssembly; +import org.qi4j.bootstrap.AssemblyException; +import org.qi4j.bootstrap.LayerAssembly; +import org.qi4j.bootstrap.ModuleAssembly; +import org.qi4j.functional.Iterables; + +/** + * Provides declared {@link org.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/builder/ModuleDeclaration.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/builder/ModuleDeclaration.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/builder/ModuleDeclaration.java new file mode 100644 index 0000000..6ac63d9 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.bootstrap.builder; + +import java.util.ArrayList; +import java.util.List; +import org.qi4j.bootstrap.Assembler; +import org.qi4j.bootstrap.AssemblyException; +import org.qi4j.bootstrap.LayerAssembly; +import org.qi4j.bootstrap.ModuleAssembly; + +import static org.qi4j.api.util.Classes.isAssignableFrom; +import static org.qi4j.functional.Iterables.filter; +import static org.qi4j.functional.Iterables.toList; +import static org.qi4j.functional.Specifications.not; + +/** + * Provides declared {@link org.qi4j.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.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/builder/package.html ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/builder/package.html b/core/bootstrap/src/main/java/org/qi4j/bootstrap/builder/package.html new file mode 100644 index 0000000..663b016 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayerAssembler.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayerAssembler.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayerAssembler.java new file mode 100644 index 0000000..c8a7b88 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayerAssembler.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.qi4j.bootstrap.layered; + +import org.qi4j.bootstrap.ApplicationAssembly; +import org.qi4j.bootstrap.AssemblyException; +import org.qi4j.bootstrap.LayerAssembly; + +public interface LayerAssembler +{ + LayerAssembly assemble( LayerAssembly layer ) + throws AssemblyException; +} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayeredApplicationAssembler.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayeredApplicationAssembler.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayeredApplicationAssembler.java new file mode 100644 index 0000000..b399711 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.bootstrap.layered; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.HashMap; +import org.qi4j.api.activation.ActivationException; +import org.qi4j.api.activation.PassivationException; +import org.qi4j.api.structure.Application; +import org.qi4j.api.structure.ApplicationDescriptor; +import org.qi4j.bootstrap.ApplicationAssembler; +import org.qi4j.bootstrap.ApplicationAssembly; +import org.qi4j.bootstrap.ApplicationAssemblyFactory; +import org.qi4j.bootstrap.AssemblyException; +import org.qi4j.bootstrap.Energy4Java; +import org.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayeredLayerAssembler.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayeredLayerAssembler.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/LayeredLayerAssembler.java new file mode 100644 index 0000000..def4a46 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.bootstrap.layered; + +import java.lang.reflect.Constructor; +import java.util.HashMap; +import org.qi4j.bootstrap.LayerAssembly; +import org.qi4j.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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/ModuleAssembler.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/ModuleAssembler.java b/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/ModuleAssembler.java new file mode 100644 index 0000000..17c8765 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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.qi4j.bootstrap.layered; + +import org.qi4j.bootstrap.AssemblyException; +import org.qi4j.bootstrap.LayerAssembly; +import org.qi4j.bootstrap.ModuleAssembly; + +public interface ModuleAssembler +{ + ModuleAssembly assemble( LayerAssembly layer, ModuleAssembly module ) + throws AssemblyException; +} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/package.html ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/package.html b/core/bootstrap/src/main/java/org/qi4j/bootstrap/layered/package.html new file mode 100644 index 0000000..60cdec2 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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/polygene-java/blob/a789141d/core/bootstrap/src/main/java/org/qi4j/bootstrap/package.html ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/main/java/org/qi4j/bootstrap/package.html b/core/bootstrap/src/main/java/org/qi4j/bootstrap/package.html new file mode 100644 index 0000000..0458761 --- /dev/null +++ b/core/bootstrap/src/main/java/org/qi4j/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> http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/bootstrap/src/test/java/org/apache/zest/bootstrap/ClassScannerTest.java ---------------------------------------------------------------------- diff --git a/core/bootstrap/src/test/java/org/apache/zest/bootstrap/ClassScannerTest.java b/core/bootstrap/src/test/java/org/apache/zest/bootstrap/ClassScannerTest.java deleted file mode 100644 index fc7147b..0000000 --- a/core/bootstrap/src/test/java/org/apache/zest/bootstrap/ClassScannerTest.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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.junit.Assert; -import org.junit.Test; -import org.apache.zest.api.activation.ActivationException; -import org.apache.zest.bootstrap.somepackage.Test2Value; -import org.apache.zest.functional.Iterables; - -import static org.apache.zest.bootstrap.ClassScanner.findClasses; -import static org.apache.zest.bootstrap.ClassScanner.matches; -import static org.apache.zest.functional.Iterables.filter; - -/** - * Test and showcase of the ClassScanner assembly utility. - */ -public class ClassScannerTest -{ - @Test - public void testClassScannerFiles() - throws ActivationException, AssemblyException - { - SingletonAssembler singleton = new SingletonAssembler() - { - @Override - public void assemble( ModuleAssembly module ) - throws AssemblyException - { - // Find all classes starting from TestValue, but include only the ones that are named *Value - - for( Class aClass : filter( matches( ".*Value" ), findClasses( TestValue.class ) ) ) - { - module.values( aClass ); - } - } - }; - - singleton.module().newValueBuilder( TestValue.class ); - singleton.module().newValueBuilder( Test2Value.class ); - } - - @Test - public void testClassScannerJar() - { - Assert.assertEquals( 138, Iterables.count( findClasses( Test.class ) ) ); - } -}