http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/association/NamedAssociationWrapper.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/association/NamedAssociationWrapper.java b/core/api/src/main/java/org/apache/zest/api/association/NamedAssociationWrapper.java new file mode 100644 index 0000000..ed47e31 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/association/NamedAssociationWrapper.java @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2011-2012, 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.api.association; + +import java.util.Iterator; +import java.util.Map; +import org.apache.zest.api.entity.EntityReference; + +/** + * If you want to catch calls to NamedAssociations, then create a GenericConcern + * that wraps the Zest-supplied NamedAssociations instance with NamedAssociationsWrapper. Override + * methods to perform your custom code. + */ +public class NamedAssociationWrapper + implements NamedAssociation<Object> +{ + protected NamedAssociation<Object> next; + + public NamedAssociationWrapper( NamedAssociation<Object> next ) + { + this.next = next; + } + + public NamedAssociation<Object> next() + { + return next; + } + + @Override + public Iterator<String> iterator() + { + return next.iterator(); + } + + @Override + public int count() + { + return next.count(); + } + + @Override + public boolean containsName( String name ) + { + return next.containsName( name ); + } + + @Override + public boolean put( String name, Object entity ) + { + return next.put( name, entity ); + } + + @Override + public boolean remove( String name ) + { + return next.remove( name ); + } + + @Override + public Object get( String name ) + { + return next.get( name ); + } + + @Override + public String nameOf( Object entity ) + { + return next.nameOf( entity ); + } + + @Override + public Map<String, Object> toMap() + { + return next.toMap(); + } + + @Override + public Iterable<EntityReference> references() + { + return next.references(); + } + + @Override + public EntityReference referenceOf( String name ) + { + return next.referenceOf( name ); + } + + @Override + public int hashCode() + { + return next.hashCode(); + } + + @Override + public boolean equals( Object obj ) + { + return next.equals( obj ); + } + + @Override + public String toString() + { + return next.toString(); + } +}
http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/association/package.html ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/association/package.html b/core/api/src/main/java/org/apache/zest/api/association/package.html new file mode 100644 index 0000000..cf48596 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/association/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>Association API.</h2> + </body> +</html> http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/cache/CacheOptions.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/cache/CacheOptions.java b/core/api/src/main/java/org/apache/zest/api/cache/CacheOptions.java new file mode 100644 index 0000000..4f609b6 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/cache/CacheOptions.java @@ -0,0 +1,86 @@ +/* + * Copyright 2010 Niclas Hedhman. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zest.api.cache; + +/** + * CacheOptions is a metaInfo class for the Cache system for Entity persistence. + * CacheOptions should be assigned to the Usecase of the UnitOfWork, to give hint on caching to entity stores. + * See {@link org.apache.zest.api.usecase.UsecaseBuilder} on how to set the metaInfo on Usecases. + */ +public final class CacheOptions +{ + public static final CacheOptions ALWAYS = new CacheOptions( true, true, true ); + public static final CacheOptions NEVER = new CacheOptions( false, false, false ); + + private final boolean cacheOnRead; + private final boolean cacheOnWrite; + private final boolean cacheOnNew; + + /** + * Constructor for CacheOptions. + * + * @param cacheOnRead if true, give the hint to the Cache system that it may not be a good idea to cache the + * read values. This is useful when it is known that the read will be over a large set and + * shouldn't affect the existing cached entities. For instance, when traversing the EntityStore + * this option is set to false. + * @param cacheOnWrite if true, give the hint to the Cache system that it may not be a good idea to cache the + * entity when the value is updated. If this is false, the cache should be emptied from any + * cached entity instead of updated. There are few cases when this is useful, and if this is + * false, it makes sense that the <i>cacheOnRead</i> is also false. + * @param cacheOnNew if true, give the hint to the Cache system that it may not be a good idea to cache a newly + * created Entity, as it is not likely to be read in the near future. This is useful when + * batch inserts are being made. + */ + public CacheOptions( boolean cacheOnRead, boolean cacheOnWrite, boolean cacheOnNew ) + { + this.cacheOnRead = cacheOnRead; + this.cacheOnWrite = cacheOnWrite; + this.cacheOnNew = cacheOnNew; + } + + /** + * @return if true, give the hint to the Cache system that it may not be a good idea to cache the + * read values. This is useful when it is known that the read will be over a large set and + * shouldn't affect the existing cached entities. For instance, when traversing the EntityStore + */ + public boolean cacheOnRead() + { + return cacheOnRead; + } + + /** + * @return if true, give the hint to the Cache system that it may not be a good idea to cache the + * entity when the value is updated. If this is false, the cache should be emptied from any + * cached entity instead of updated. There are few cases when this is useful, and if this is + * false, it makes sense that the <i>cacheOnRead</i> is also false. + */ + public boolean cacheOnWrite() + { + return cacheOnWrite; + } + + /** + * @return if true, give the hint to the Cache system that it may not be a good idea to cache a newly + * created Entity, as it is not likely to be read in the near future. This is useful when + * batch inserts are being made. + */ + public boolean cacheOnNew() + { + return cacheOnNew; + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/cache/package.html ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/cache/package.html b/core/api/src/main/java/org/apache/zest/api/cache/package.html new file mode 100644 index 0000000..a62da34 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/cache/package.html @@ -0,0 +1,40 @@ +<!-- +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>Cache API.</h2> + <p> + The Cache API/SPI is an extension point for Entity Store caching. + </p> + <p> + The API part is only to allow caching options to be passed to the underlying extension in a uniform and + standard way. CacheOptions are to be passed as meta info on the optional Cache extension that is specified + during assembly phase. Example; + </p> +<pre><code> +public void assemble( ModuleAssembly module ) +{ + CacheOptions options = new CacheOptions( true, true, false ); + module.addServices( EhCacheService.class ).setMetaInfo( options ); +} +</code></pre> + <p> + Not all EntityStore implementations use the Cache extension, so check the implementation details of the + EntityStore whether the cache extension can bring any benefits or not. + </p> + </body> +</html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/common/AppliesTo.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/common/AppliesTo.java b/core/api/src/main/java/org/apache/zest/api/common/AppliesTo.java new file mode 100644 index 0000000..a9b1262 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/common/AppliesTo.java @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2007, Rickard Ãberg. All Rights Reserved. + * Copyright (c) 2007, Niclas Hedhman. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. + * See the License for the specific language governing permissions + * and limitations under the License. + */ + +package org.apache.zest.api.common; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Fragments that implement InvocationHandler and which should only be applied to methods that have a particular + * annotation or implement a known interface should use this annotation. + * <p> + * @AppliesTo can specify one of; + * </p> + * <ul> + * <li>An annotation,</li> + * <li>An interface,</li> + * <li>An AppliesToFilter implementation.</li> + * </ul> + * <p> + * Example with annotation: + * </p> + * <pre><code> + * + * @AppliesTo( Sessional.class ) // Tells Zest to apply this concern on methods with @Sessional annotation + * public class SessionConcern extends GenericConcern + * { + * public Object invoke( Object proxy, Method method, Object[] args ) + * throws Throwable + * { + * ... do session stuff ... + * } + * } + * + * @Retention( RetentionPolicy.RUNTIME ) + * @Target( ElementType.METHOD ) + * @Documented + * @Inherited + * public @interface Sessional + * { + * } + * + * public class MyMixin + * implements My + * { + * @Sessional + * public void doSomethingSessional() + * { + * // ... do your logic wrapped in a session + * } + * + * public void doSomethingWithoutSession() + * { + * // ... do stuff that are not wrapped in session. + * } + * } + * + * public interface My + * { + * void doSomethingSessional(); + * + * void doSomethingWithoutSession(); + * } + * + * @Concerns( SessionConcern.class ) + * @Mixins( MyMixin.class ) + * public interface MyComposite extends My, TransientComposite + * {} + * </code></pre> + * <p> + * The doSomethingWithoutSession method do not have the @Sessional annotation, therefore the SessionConcern will + * not be placed into the call sequence of these methods, and + * vice-versa. The @Sessional annotation can be placed either on the interface method or the implementation + * method, depending on whether it is a contract or implementation detail. + * </p> + */ +@Retention( RetentionPolicy.RUNTIME ) +@Target( { ElementType.TYPE, ElementType.METHOD } ) +@Documented +public @interface AppliesTo +{ + /** + * List of interfaces, annotations or AppliesToFilter + * implementation classes. + * If one of them matches the current element it will be + * accepted, so this list can be considered an "or". + * + * @return array of classes or interfaces to be used by the filter + */ + Class<?>[] value(); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/common/AppliesToFilter.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/common/AppliesToFilter.java b/core/api/src/main/java/org/apache/zest/api/common/AppliesToFilter.java new file mode 100644 index 0000000..e217ebe --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/common/AppliesToFilter.java @@ -0,0 +1,83 @@ +/* + * 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.api.common; + +import java.lang.reflect.Method; + +/** + * Implementations of this interface can be specified in the @AppliesTo. + * <p> + * AppliesTo filters are one of the driving technologies in Zest. They allow you to apply fragments (Mixins, + * Concerns, SideEffects), often generic ones, depending on the context that they are evaluated under. This + * mechanism is heavily used internally in Zest to achieve many other features. + * </p> + * <p> + * The starting point is the basic use of AppliesToFilter, where the @AppliesTo annotation is given an + * AppliesToFilter implementation as an argument, for instance at a Mixin implementation; + * </p> + * <pre><code> + * @AppliesTo( MyAppliesToFilter.class ) + * public class SomeMixin + * implements InvocationHandler + * { + * + * } + * + * public class MyAppliesToFilter + * implements AppliesToFilter + * { + * public boolean appliesTo( Method method, Class<?> mixin, Class<?> compositeType, Class<?> fragmentClass ) + * { + * return method.getName().startsWith( "my" ); + * } + * } + * </code></pre> + * <p> + * In the case above, the generic mixin will only be applied to the methods that that is defined by the + * AppliesToFilter. This is the primary way to define limits on the application of generic fragments, since + * especially mixins are rarely applied to all methods. + * </p> + */ +public interface AppliesToFilter +{ + /** + * This is an internal AppliesToFilter which is assigned if no other AppliesToFilters are found for a given + * fragment. + * <p> + * There is no reason for user code to use this AppliesToFilter directly, and should be perceived as an + * internal class in Zest. + * </p> + */ + AppliesToFilter ALWAYS = new AppliesToFilter() + { + @Override + public boolean appliesTo( Method method, Class<?> mixin, Class<?> compositeType, Class<?> fragmentClass ) + { + return true; + } + }; + + /** + * Check if the Fragment should be applied or not. Will be call when applied to Mixins, Concerns, SideEffects. + * + * @param method method that is invoked + * @param mixin mixin implementation for the method + * @param compositeType composite type + * @param fragmentClass fragment that is being applies + * + * @return true if the filter passes, otherwise false + */ + boolean appliesTo( Method method, Class<?> mixin, Class<?> compositeType, Class<?> fragmentClass ); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/common/ConstructionException.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/common/ConstructionException.java b/core/api/src/main/java/org/apache/zest/api/common/ConstructionException.java new file mode 100644 index 0000000..3a5fff1 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/common/ConstructionException.java @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2007, Rickard Ãberg. All Rights Reserved. + * Copyright (c) 2007, Niclas Hedhman. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.zest.api.common; + +/** + * Thrown when a Fragment or object could not be instantiated. + * This includes, but not be limited to; + * <ul> + * <li>private constructor.</li> + * <li>abstract class for Constraints.</li> + * <li>interface instead of a class.</li> + * <li>useful constructor missing.</li> + * <li>exception thrown in the constructor.</li> + * <li>Subclassing of org.qi4j.api.property.Property</li> + * </ul> + * <p> + * See the nested exception for additional details. + * </p> + */ +public class ConstructionException + extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public ConstructionException() + { + } + + public ConstructionException( String message ) + { + super( message ); + } + + public ConstructionException( String message, Throwable cause ) + { + super( message, cause ); + } + + public ConstructionException( Throwable cause ) + { + super( cause ); + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/common/InvalidApplicationException.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/common/InvalidApplicationException.java b/core/api/src/main/java/org/apache/zest/api/common/InvalidApplicationException.java new file mode 100644 index 0000000..d0cb8aa --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/common/InvalidApplicationException.java @@ -0,0 +1,36 @@ +/* + * Copyright (c) 2007, Rickard Ãberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.zest.api.common; + +/** + * Thrown when an application is considered to not be constructed properly. + * This happens primarily when client code tries to instantiate Composites + * and objects which have not been registered in the ModuleAssembly. + */ +public class InvalidApplicationException + extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public InvalidApplicationException( String string ) + { + super( string ); + } + + public InvalidApplicationException( String string, Throwable cause ) + { + super( string, cause ); + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/common/MetaInfo.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/common/MetaInfo.java b/core/api/src/main/java/org/apache/zest/api/common/MetaInfo.java new file mode 100644 index 0000000..6856c61 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/common/MetaInfo.java @@ -0,0 +1,151 @@ +/* + * 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.api.common; + +import java.lang.annotation.Annotation; +import java.lang.reflect.AnnotatedElement; +import java.lang.reflect.Type; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.Map; +import org.apache.zest.api.concern.Concerns; +import org.apache.zest.api.mixin.Mixins; +import org.apache.zest.api.sideeffect.SideEffects; +import org.apache.zest.api.util.Classes; + +import static java.util.Arrays.asList; +import static org.apache.zest.api.util.Classes.typesOf; + +/** + * Used to declare and access meta-info. + * <p> + * <strong>This is effectively an internal class and should not be used directly.</strong> + * </p> + * <p> + * MetaInfo can be set on composites during the assembly phase, a.k.a the bootstrap + * process. MetaInfo is any additional data that one wishes to associate at the 'class level' instead of instance + * level of a composite declaration. + * </p> + * <p> + * To set the MetaInfo on a Composite, call the {@code setMetaInfo()} methods on the various composite declaration + * types, such as; + * </p> + * <pre><code> + * public void assemble( ModuleAssembly module ) + * throws AssemblyException + * { + * Map<String,String> properties = ...; + * module.services( MyService.class ).setMetaInfo( properties ); + * } + * </code></pre> + * <p> + * which can later be retrieved by calling the {@code metaInfo()} method on the composite itself. For the example + * above that would be; + * </p> + * <pre><code> + * @Mixins(MyServiceMixin.class) + * public interface MyService extends ServiceComposite + * { + * + * } + * + * public abstract class MyServiceMixin + * implements MyService + * { + * private Properties props; + * + * public MyServiceMixin() + * { + * props = metaInfo( Map.class ); + * } + * } + * </code></pre> + */ +public final class MetaInfo +{ + private final static Collection<Class> ignored; + + static + { + ignored = new HashSet<Class>( 4, 0.8f ); // Optimize size used. + ignored.addAll( asList( Mixins.class, Concerns.class, SideEffects.class ) ); + } + + private final Map<Class<?>, Object> metaInfoMap; + + public MetaInfo() + { + metaInfoMap = new LinkedHashMap<Class<?>, Object>(); + } + + public MetaInfo( MetaInfo metaInfo ) + { + metaInfoMap = new LinkedHashMap<Class<?>, Object>(); + metaInfoMap.putAll( metaInfo.metaInfoMap ); + } + + public void set( Object metaInfo ) + { + if( metaInfo instanceof Annotation ) + { + Annotation annotation = (Annotation) metaInfo; + metaInfoMap.put( annotation.annotationType(), metaInfo ); + } + else + { + Class<?> metaInfoclass = metaInfo.getClass(); + Iterable<Type> types = typesOf( metaInfoclass ); + for( Type type : types ) + { + metaInfoMap.put( Classes.RAW_CLASS.map( type ), metaInfo ); + } + } + } + + public <T> T get( Class<T> metaInfoType ) + { + return metaInfoType.cast( metaInfoMap.get( metaInfoType ) ); + } + + public <T> void add( Class<T> infoType, T info ) + { + metaInfoMap.put( infoType, info ); + } + + public MetaInfo withAnnotations( AnnotatedElement annotatedElement ) + { + for( Annotation annotation : annotatedElement.getAnnotations() ) + { + if( !ignored.contains( annotation.annotationType() ) + && get( annotation.annotationType() ) == null ) + { + set( annotation ); + } + } + return this; + } + + @Override + public String toString() + { + return metaInfoMap.toString(); + } + + public void remove( Class serviceFinderClass ) + { + metaInfoMap.remove( serviceFinderClass ); + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/common/Optional.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/common/Optional.java b/core/api/src/main/java/org/apache/zest/api/common/Optional.java new file mode 100644 index 0000000..f19b8fb --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/common/Optional.java @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2007, Rickard Ãberg. All Rights Reserved. + * Copyright (c) 2007, Niclas Hedhman. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.zest.api.common; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation to denote that something is optional. + * <ul> + * <li> + * If applied to a method parameter, then the value is allowed to be null. Default + * is that method parameters have to be non-null. + * </li> + * <li> + * If applied to a Property declaration, then the value may be null after construction of + * the instance, or may be set to null at a later time. + * </li> + * <li> + * If applied to an injected member field, it is allowed tha none get injected. For instance, an <code>@Optional + * @Service</code> would allow a service to not have been declared and the field will be null. + * </li> + * </ul> + * <p> + * Optionality is not the default in Zest, and if injections, property values and parameters in methods are not + * non-null, the Zest runtime will throw an {@link org.apache.zest.api.constraint.ConstraintViolationException}, indicating + * which field/property/parameter in which composite and mixin the problem has been detected. + * </p> + * <p> + * Example; + * </p> + * <pre><code> + * @Optional @Service + * MyService service; // If no MyService instance is declared and visible to this service injection point + * // the 'service' field will be null. + * + * @Service + * YourService other; // If no YourService instance is declared and visible to this service injection point + * // the Zest runtime will throw a ConstraintViolationException. + * + * </code></pre> + */ +@Retention( RetentionPolicy.RUNTIME ) +@Target( { ElementType.PARAMETER, ElementType.METHOD, ElementType.FIELD } ) +@Documented +public @interface Optional +{ +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/common/QualifiedName.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/common/QualifiedName.java b/core/api/src/main/java/org/apache/zest/api/common/QualifiedName.java new file mode 100644 index 0000000..eef1cce --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/common/QualifiedName.java @@ -0,0 +1,252 @@ +/* + * Copyright (c) 2009, Rickard Ãberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.zest.api.common; + +import java.io.Serializable; +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Member; +import org.apache.zest.api.util.NullArgumentException; + +/** + * QualifiedName is a representation of Property names to their full declaration. + * <p> + * A QualifiedName is created by combining the name of a method and the name of the type that declares the method. + * This class also contains many static utility methods to manage QualifiedName instances. + * </p> + * <p> + * <strong>NOTE: Unless you do very generic libraries, entity stores and other extensions that is deeply coupled into + * the Zest runtime, it is very unlikely you will need to use this class directly.</strong> + * </p> + * <p> + * It is also important to notice that the QualifiedName needs to be long-term stable, as the names are written + * to persistent storage. So any changes in the formatting <strong>must be made in a backward-compatible manner + * </strong>. + * </p> + * <p> + * The QualifiedName has two intrinsic parts, one being the {@code type} and the other the {@code name}. The + * {@code type} comes from the class where the QualifiedName originates from and internally kept as a {@link TypeName} + * instance. The name is the name from the method name. When the QualifiedName instance is converted to an external + * string representation, via the offical and formal {@link #toString()} method, the {@code type} is normalized, i.e. + * any dollar characters ($) in the name are replaced by dashes (-), to make them URI friendly. + * </p> + * <p> + * QualifiedName instances are immutable, implements {@link #hashCode()} and {@link #equals(Object)} as a value + * object and can safely be used as keys in {@link java.util.Map}. + */ +public final class QualifiedName + implements Comparable<QualifiedName>, Serializable +{ + private final TypeName typeName; + private final String name; + + /** + * Creates a QualifiedName from a method. + * <p> + * This factory method will create a QualifiedName from the Method itself. + * + * </p> + * + * @param method Type method that returns a Property, for which the QualifiedName will be representing. + * + * @return A QualifiedName representing this method. + * + * @throws NullArgumentException If the {@code method} argument passed is null. + */ + public static QualifiedName fromAccessor( AccessibleObject method ) + { + NullArgumentException.validateNotNull( "method", method ); + return fromClass( ( (Member) method ).getDeclaringClass(), ( (Member) method ).getName() ); + } + + /** + * Creates a QualifiedName instance from the Class and a given name. + * <p> + * This factory method converts the {@code type} to a {@link TypeName} and appends the given {@code name}. + * + * @param type The Class that is the base of the QualifiedName. + * @param name The qualifier name which will be appended to the base name derived from the {@code type} argument. + * + * @return A QualifiedName instance representing the {@code type} and {@code name} arguments. + * + * @throws NullArgumentException if any of the two arguments are {@code null}, or if the name string is empty. + */ + public static QualifiedName fromClass( Class type, String name ) + { + return new QualifiedName( TypeName.nameOf( type ), name ); + } + + /** + * Creates a Qualified name from a type as string and a name qualifier. + * + * @param type The type name as a a string, which must be properly formatted. No checks for correctly formatted + * type name is performed. + * @param name The qualifier name which will be appended to the base name derived from the {@code type} argument. + * + * @return A QualifiedName instance representing the {@code type} and {@code name} arguments. + * + * @throws NullArgumentException if any of the two arguments are {@code null} or either string is empty. + */ + public static QualifiedName fromName( String type, String name ) + { + return new QualifiedName( TypeName.nameOf( type ), name ); + } + + /** + * Creates a QualifiedName from the external string format of QualifiedName. + * <p> + * This factory method is the reverse of {@link QualifiedName#toString() } method, and creates a new QualifiedName + * instance from the string representation of the QualifiedName. + * </p> + * + * @param fullQualifiedName The QualifiedName external string representation to be converted back into a QualifiedName + * instance. + * + * @return The QualifiedName instance represented by the {@code qualifiedName} argument. + * + * @throws IllegalArgumentException If the {@code qualifiedName} argument has wrong format. + */ + public static QualifiedName fromFQN( String fullQualifiedName ) + { + NullArgumentException.validateNotEmpty( "qualifiedName", fullQualifiedName ); + int idx = fullQualifiedName.lastIndexOf( ":" ); + if( idx == -1 ) + { + throw new IllegalArgumentException( "Name '" + fullQualifiedName + "' is not a qualified name" ); + } + final String type = fullQualifiedName.substring( 0, idx ); + final String name = fullQualifiedName.substring( idx + 1 ); + return new QualifiedName( TypeName.nameOf( type ), name ); + } + + QualifiedName( TypeName typeName, String name ) + { + NullArgumentException.validateNotNull( "typeName", typeName ); + NullArgumentException.validateNotEmpty( "name", name ); + this.typeName = typeName; + this.name = name; + } + + /** + * Returns the normalized string of the type part of the QualifiedName. + * + * <p> + * The normalized type name means that all dollar ($) characters have been replaced by dashes (-). + * </p> + * + * @return the normalized string of the type part of the QualifiedName. + */ + public String type() + { + return typeName.normalized(); + } + + /** + * Returns the name component of the QualifiedName. + * + * @return the name component of the QualifiedName. + */ + public String name() + { + return name; + } + + /** + * Returns the URI of the QualifiedName. + * + * <p> + * The URI is the {@link #toNamespace()} followed by the {@code name} component. + * <p> + * + * @return the URI of the QualifiedName. + * + * @see #toNamespace() + */ + public String toURI() + { + return toNamespace() + name; + } + + /** + * Return the URI of the {@link TypeName} component of the QualifiedName. + * <p> + * The URI of the {@link TypeName} component is in the form of; + * </p> + * <pre> + * "urn:qi4j:type:" normalizedClassName + * </pre> + * <p> + * where {@code normalizedClassName} is the fully-qualified class name having had any dollar ($) characters replaced + * by URI friendly dashes (-), with a trailing hash (#). Examples; + * </p> + * <pre> + * urn:qi4j:type:org.qi4j.api.common.QualifiedName# + * urn:qi4j:type:org.qi4j.samples.MyClass-MyInnerClass# + * </pre> + * + * @return the URI of the {@link TypeName} component of the QualifiedName. + */ + public String toNamespace() + { + return typeName.toURI() + "#"; + } + + /** + * Return the formal and official, long-term stable, external string representation of a QualifiedName. + * <p> + * This returns the {@link org.apache.zest.api.common.TypeName#toString()} followed by the {@code name} component. + * </p> + * + * @return the formal and official, long-term stable, external string representation of a QualifiedName. + */ + @Override + public String toString() + { + return typeName + ":" + name; + } + + @Override + public boolean equals( Object o ) + { + if( this == o ) + { + return true; + } + if( o == null || getClass() != o.getClass() ) + { + return false; + } + + QualifiedName that = (QualifiedName) o; + + return name.equals( that.name ) && typeName.equals( that.typeName ); + } + + @Override + public int hashCode() + { + return 31 * typeName.hashCode() + name.hashCode(); + } + + @Override + public int compareTo( QualifiedName other ) + { + final int result = typeName.compareTo( other.typeName ); + if( result != 0 ) + { + return result; + } + return name.compareTo( other.name ); + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/common/TypeName.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/common/TypeName.java b/core/api/src/main/java/org/apache/zest/api/common/TypeName.java new file mode 100644 index 0000000..78f03af --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/common/TypeName.java @@ -0,0 +1,111 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.zest.api.common; + +import java.io.Serializable; +import java.lang.reflect.Type; +import org.apache.zest.api.util.Classes; +import org.apache.zest.api.util.NullArgumentException; + +/** + * Represents a Type name. + */ +public final class TypeName + implements Serializable, Comparable<TypeName> +{ + private final String name; + + public static TypeName nameOf( Class type ) + { + NullArgumentException.validateNotNull( "type", type ); + return new TypeName( type.getName() ); + } + + public static TypeName nameOf( Type type ) + { + return nameOf( Classes.RAW_CLASS.map( type ) ); + } + + public static TypeName nameOf( String typeName ) + { + return new TypeName( typeName ); + } + + private TypeName( String name ) + { + NullArgumentException.validateNotEmpty( "name", name ); + this.name = name; + } + + public String normalized() + { + return Classes.normalizeClassToURI( name ); + } + + public String toURI() + { + return Classes.toURI( name ); + } + + public String name() + { + return name; + } + + @Override + public String toString() + { + return name; + } + + public boolean isClass( final Class<?> type ) + { + return type.getName().equals( name ); + } + + @Override + public boolean equals( final Object o ) + { + if( this == o ) + { + return true; + } + if( o == null || getClass() != o.getClass() ) + { + return false; + } + + final TypeName other = (TypeName) o; + + return name.equals( other.name ); + } + + @Override + public int hashCode() + { + return name.hashCode(); + } + + @Override + public int compareTo( final TypeName typeName ) + { + return this.name.compareTo( typeName.name ); + } +} + http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/common/UseDefaults.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/common/UseDefaults.java b/core/api/src/main/java/org/apache/zest/api/common/UseDefaults.java new file mode 100644 index 0000000..a09e76a --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/common/UseDefaults.java @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2009, Rickard Ãberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.zest.api.common; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Annotation to denote that the initial value of a Property will be the default value for the type if none is + * specified during construction. + * <p> + * These are the default values used for various types: + * </p> + * <pre> + * Byte: 0 + * Short: 0 + * Character: 0 + * Integer: 0 + * Long: 0L + * Double: 0.0d + * Float: 0.0f + * Boolean: false + * String: "" + * List: empty java.util.ArrayList + * Set: empty java.util.HashSet + * Collection: empty java.util.ArrayList + * enum: first declared value + * </pre> + * <p> + * If this annotation is not used, the property will be set to null, and unless {@code @Optional} is declared + * is not allowed. + * </p> + * <p> + * It is also possible to change the default values for Composites during the assembly. This is done by calling the + * {@code org.qi4j.bootstrap.ModuleAssembly#forMixin(Class)} method. + * </p> + * <p> + * Example; + * Let's assume that we have the following mixin type; + * + * <pre><code> + * public interface SomeType + * { + * @UseDefaults + * Property<String> someValue(); + * } + * </code></pre> + * And that we want to have {@code someValue()} to be initialized to "<unknown>" instead of the empty string. + * Then we need to declare the default for that with the following in the assembler. + * <pre><code> + * public void assemble( ModuleAssembly module ) + * { + * module.forMixin( SomeType.class ).declareDefaults().someValue().set( "<unknown>" ); + * } + * } + * </code></pre> + */ +@SuppressWarnings( "JavadocReference" ) +@Retention( RetentionPolicy.RUNTIME ) +@Target( { ElementType.METHOD, ElementType.FIELD } ) +@Documented +public @interface UseDefaults +{ +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/common/Visibility.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/common/Visibility.java b/core/api/src/main/java/org/apache/zest/api/common/Visibility.java new file mode 100644 index 0000000..e81824b --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/common/Visibility.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2007, Rickard Ãberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.zest.api.common; + +/** + * Visibility is a core concept in the Zest structure system. It defines the locale of composites and objects, i.e. + * how far they can be 'seen' and therefor be used. + * <p> + * When a Composite or Object is declared in the assembly phase, and no visibility is set, only other + * composites/objects within the same module can use that declaration. For a declared composite/object to be usable + * from other modules a higher visibility must be set, either that the Composite/Object can be used by others within + * the same Layer, or even to be used by those in the layer above. + * </p> + */ +public enum Visibility +{ + /** + * Artifact is visible only in the declaring module (default) + */ + module, + /** + * Artifact is visible to all modules in the same layer + */ + layer, + /** + * Artifact is visible to other modules in the same layer and any modules in extending layers + */ + application +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/common/package.html ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/common/package.html b/core/api/src/main/java/org/apache/zest/api/common/package.html new file mode 100644 index 0000000..f29de5d --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/common/package.html @@ -0,0 +1,81 @@ +<!-- +Licensed to the Apache Software Foundation (ASF) under one or more +contributor license agreements. See the NOTICE file distributed with +this work for additional information regarding copyright ownership. +The ASF licenses this file to You under the Apache License, Version 2.0 +(the "License"); you may not use this file except in compliance with +the License. You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +--> +<html> + <body> + <h2>Common API.</h2> + <p> + The Common API package is a collection of really low-level types needed at the core of the Zest⢠Runtime. It is also + a collection of types that are not particularly cohesive, and effectively this package contains the loose ends + that does not belong elsewhere. + </p> + <p> + In this package, you can safely ignore the following classes; + </p> + <ul> + <li>MetaInfo</li> + <li>QualifiedName</li> + <li>TypeName</li> + </ul> + <p>UNLESS you are into deep integration into the Zest⢠Runtime.</p> + + <h3>@AppliesTo and AppliesToFilter</h3> + <p> + This tandem of interface + annotation are primarily used for Generic Fragments, to indicate which methods on the + interface the fragment should be applied to. + </p> + + <h3>@Optional</h3> + <p> + In Zestâ¢, method arguments, property values and injected fields are not allowed to be null by default. To allow + any of these to be null, i.e. undeclared, it is required that the argument, field or method is marked with the + @Optional annotation. + </p> + + <h3>@UseDefaults</h3> + <p> + Since null is not allowed without the @Optional annotation, it can sometimes by tedious to initialize all + the property values. And the @UseDefaults annotation allows us to declare that Zest⢠should set the Property + to a default value. These are either the pre-defined ones, or can be set per property declaration during the + assembly. + </p> + + <h3>@Visibility</h3> + <p> + Visibility is another innovative concept in Zestâ¢, which leverage the structure system (Application, Layer, Module) + to limit the 'reach' when requesting composites and objects. The Visibility is declared per Composite/Object, + preferably in the most restrictive mode possible, and the visibility resolver will ensure a predictable resolution + algorithm; + </p> + <ol> + <li>Search the module of the caller first. If one and only one composite type fulfilling the request is available + return that to the caller. If two or more are found, throw an AmbiguousTypeException. If no composite found + continue to the next step. + </li> + <li>Search all modules in the Layer of the caller for composite that has a declaration other than + <code>Visibility.module</code>. If one and only one composite type fulfilling the request is available + return that to the caller. If two or more are found, throw an AmbiguousTypeException. If no composite found + continue to the next step. + </li> + <li>Search all modules in the Layer(s) (if any) directly below of the caller for composite that has a declaration of + <code>Visibility.application</code>. If one and only one composite type fulfilling the request is available + return that to the caller. If two or more are found, throw an AmbiguousTypeException. If no composite found + continue to the next step. + </li> + <li>Throw an NoSuchCompositeException (or related) exception.</li> + </ol> + </body> +</html> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/composite/AmbiguousTypeException.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/composite/AmbiguousTypeException.java b/core/api/src/main/java/org/apache/zest/api/composite/AmbiguousTypeException.java new file mode 100644 index 0000000..7f3a0f8 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/composite/AmbiguousTypeException.java @@ -0,0 +1,57 @@ +/* + * Copyright 2008 Niclas Hedhman. All rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zest.api.composite; + +/** + * This Exception is thrown when more than one Composite implements a MixinType + * that one tries to use to create a Composite instance from. + * <p> + * For instance; + * </p> + * <pre><code> + * public interface AbcComposite extends TransientComposite, Abc + * {} + * + * public interface DefComposite extends TransientComposite, Def + * {} + * + * public interface Abc + * {} + * + * public interface Def extends Abc + * {} + * + * + * TransientBuilder cb = factory.newTransientBuilder( Abc.class ); + * </code></pre> + * <p> + * In the code above, both the AbcComposite and DefComposite implement Abc, and therefore + * the <code>newTransientBuilder</code> method can not unambiguously figure out which + * one is intended. + * </p> + */ +public class AmbiguousTypeException + extends RuntimeException +{ + private static final long serialVersionUID = 1L; + + public AmbiguousTypeException( String message ) + { + super( message ); + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/composite/Composite.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/composite/Composite.java b/core/api/src/main/java/org/apache/zest/api/composite/Composite.java new file mode 100644 index 0000000..b60f19c --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/composite/Composite.java @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2007, Rickard Ãberg. All Rights Reserved. + * Copyright (c) 2007, Niclas Hedhman. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.zest.api.composite; + +import org.apache.zest.api.mixin.Mixins; +import org.apache.zest.api.property.PropertyMixin; + +/** + * Base Composite interface. + * <p> + * All Composite objects must implement this interface. Let the + * Composite interface extend this one. An implementation will be provided + * by the framework. + * </p> + * <p> + * Properties and associations are handled by default. + * </p> + */ +@Mixins( { PropertyMixin.class } ) +public interface Composite +{ +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/composite/CompositeContext.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/composite/CompositeContext.java b/core/api/src/main/java/org/apache/zest/api/composite/CompositeContext.java new file mode 100644 index 0000000..b50d0d3 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/composite/CompositeContext.java @@ -0,0 +1,80 @@ +/* + * Copyright (c) 2007, Rickard Ãberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.zest.api.composite; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import org.apache.zest.api.Qi4j; +import org.apache.zest.api.structure.Module; +import org.apache.zest.functional.Iterables; + +import static org.apache.zest.functional.Iterables.toArray; + +/** + * Thread-associated composites. This is basically a ThreadLocal which maintains a reference + * to a TransientComposite instance for each thread. This can be used to implement various context + * patterns without having to pass the context explicitly as a parameter to methods. + */ +public class CompositeContext<T extends TransientComposite> + extends ThreadLocal<T> +{ + private Module module; + private Class<T> type; + + public CompositeContext( Module module, Class<T> type ) + { + this.module = module; + this.type = type; + } + + @Override + protected T initialValue() + { + return module.newTransient( type ); + } + + @SuppressWarnings( "unchecked" ) + public T proxy() + { + TransientComposite composite = get(); + + Iterable<Class<?>> types = Qi4j.FUNCTION_COMPOSITE_INSTANCE_OF.map( composite ).types(); + return (T) Proxy.newProxyInstance( + composite.getClass().getClassLoader(), + toArray( Class.class, Iterables.<Class>cast( types ) ), + new ContextInvocationhandler() ); + } + + private class ContextInvocationhandler + implements InvocationHandler + { + + @Override + public Object invoke( Object object, Method method, Object[] objects ) + throws Throwable + { + try + { + return method.invoke( get(), objects ); + } + catch( InvocationTargetException e ) + { + throw e.getTargetException(); + } + } + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/composite/CompositeDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/composite/CompositeDescriptor.java b/core/api/src/main/java/org/apache/zest/api/composite/CompositeDescriptor.java new file mode 100644 index 0000000..49f9f42 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/composite/CompositeDescriptor.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2009, Rickard Ãberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.zest.api.composite; + +/** + * Composite Descriptor. + */ +public interface CompositeDescriptor + extends ModelDescriptor +{ + Class<?> primaryType(); + + Iterable<Class<?>> mixinTypes(); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/composite/CompositeInstance.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/composite/CompositeInstance.java b/core/api/src/main/java/org/apache/zest/api/composite/CompositeInstance.java new file mode 100644 index 0000000..63aa10d --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/composite/CompositeInstance.java @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2008, Rickard Ãberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.zest.api.composite; + +import java.lang.reflect.InvocationHandler; +import org.apache.zest.api.property.StateHolder; +import org.apache.zest.api.structure.MetaInfoHolder; +import org.apache.zest.api.structure.Module; +import org.apache.zest.api.type.HasTypes; + +/** + * Composite Instance. + */ +public interface CompositeInstance + extends InvocationHandler, CompositeInvoker, HasTypes, MetaInfoHolder +{ + <T> T proxy(); + + <T> T newProxy( Class<T> mixinType ) + throws IllegalArgumentException; + + Module module(); + + CompositeDescriptor descriptor(); + + StateHolder state(); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/composite/CompositeInvoker.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/composite/CompositeInvoker.java b/core/api/src/main/java/org/apache/zest/api/composite/CompositeInvoker.java new file mode 100644 index 0000000..bc8a8d0 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/composite/CompositeInvoker.java @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2010, Rickard Ãberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.zest.api.composite; + +import java.lang.reflect.Method; + +/** + * Composite method invoker. + * <p> + * All composites must implement this interface. Methods that are invoked + * may reside either in the public Composite interface or in any internal mixins. + * </p> + * <p> + * <strong><i>NOTE:</i></strong>Client code should never use method in this class. We have not been able to hide this + * from client code, but IF we find a way to do, this interface may disappear. + * </p> + */ +public interface CompositeInvoker +{ + + Object invokeComposite( Method method, Object[] args ) + throws Throwable; + +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/composite/ConstructorDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/composite/ConstructorDescriptor.java b/core/api/src/main/java/org/apache/zest/api/composite/ConstructorDescriptor.java new file mode 100644 index 0000000..c235dca --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/composite/ConstructorDescriptor.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2008, Rickard Ãberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.zest.api.composite; + +import java.lang.reflect.Constructor; + +/** + * Composite constructor descriptor. + */ +public interface ConstructorDescriptor +{ + Constructor<?> constructor(); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/composite/DecoratorMixin.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/composite/DecoratorMixin.java b/core/api/src/main/java/org/apache/zest/api/composite/DecoratorMixin.java new file mode 100644 index 0000000..080a799 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/composite/DecoratorMixin.java @@ -0,0 +1,104 @@ +/* + * Copyright 2009 Niclas Hedhman. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zest.api.composite; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import org.apache.zest.api.injection.scope.Uses; + +/** + * Generic decorator mixin that allows a Composite to wrap + * any other Composite as long as they share an interface. + * <p> + * Can be used to effectively implement + * singleton mixins, since the decorated object can be shared between + * many instances. + * </p> + */ +public class DecoratorMixin + implements InvocationHandler +{ + private Object delegate; + + public DecoratorMixin( @Uses Object delegate ) + { + if( delegate instanceof Class ) + { + Thread.dumpStack(); + } + this.delegate = delegate; + } + + @Override + public Object invoke( Object object, Method method, Object[] args ) + throws Throwable + { + if( delegate instanceof InvocationHandler ) + { + InvocationHandler handler = (InvocationHandler) delegate; + return handler.invoke( object, method, args ); + } + else + { + try + { + return method.invoke( delegate, args ); + } + catch( InvocationTargetException e ) + { + throw e.getCause(); + } + catch( IllegalArgumentException e ) + { + String message = constructMessage( method, args ); + throw new IllegalArgumentException( message, e ); + } + } + } + + private String constructMessage( Method method, Object[] args ) + { + StringBuilder builder = new StringBuilder(); + builder.append( "\nmethod: " ); + builder.append( method.getDeclaringClass().getName() ); + builder.append( "." ); + builder.append( method.getName() ); + builder.append( "\ndelegate: " ); + builder.append( delegate ); + builder.append( "\ndelegateType: " ); + builder.append( delegate == null ? "n/a" : delegate.getClass().getName() ); + builder.append( "\narguments: \n" ); + for( Object arg : args ) + { + builder.append( " " ); + Class argClass = arg.getClass(); + if( Proxy.isProxyClass( argClass ) ) + { + builder.append( Proxy.getInvocationHandler( arg ).getClass().getName() ); + } + else + { + builder.append( argClass.getName() ); + } + builder.append( '\n' ); + } + return builder.toString(); + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/composite/DependencyDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/composite/DependencyDescriptor.java b/core/api/src/main/java/org/apache/zest/api/composite/DependencyDescriptor.java new file mode 100644 index 0000000..a2de941 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/composite/DependencyDescriptor.java @@ -0,0 +1,38 @@ +/* Copyright 2008 Edward Yakop. +* +* Licensed under the Apache License, Version 2.0 (the "License"); +* you may not use this file except in compliance with the License. +* You may obtain a copy of the License at +* +* http://www.apache.org/licenses/LICENSE-2.0 +* +* Unless required by applicable law or agreed to in writing, software +* distributed under the License is distributed on an "AS IS" BASIS, +* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or +* implied. +* +* See the License for the specific language governing permissions and +* limitations under the License. +*/ +package org.apache.zest.api.composite; + +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; + +/** + * Composite dependency descriptor. + */ +public interface DependencyDescriptor +{ + Annotation injectionAnnotation(); + + Type injectionType(); + + Class<?> injectedClass(); + + Class<?> rawInjectionType(); + + boolean optional(); + + Annotation[] annotations(); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/composite/InjectedFieldDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/composite/InjectedFieldDescriptor.java b/core/api/src/main/java/org/apache/zest/api/composite/InjectedFieldDescriptor.java new file mode 100644 index 0000000..0a6b282 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/composite/InjectedFieldDescriptor.java @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2008, Rickard Ãberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.zest.api.composite; + +import java.lang.reflect.Field; + +/** + * Composite injected field descriptor. + */ +public interface InjectedFieldDescriptor +{ + Field field(); + + DependencyDescriptor dependency(); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/composite/InjectedMethodDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/composite/InjectedMethodDescriptor.java b/core/api/src/main/java/org/apache/zest/api/composite/InjectedMethodDescriptor.java new file mode 100644 index 0000000..917e454 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/composite/InjectedMethodDescriptor.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2008, Rickard Ãberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.zest.api.composite; + +import java.lang.reflect.Method; + +/** + * Composite injected method descriptor. + */ +public interface InjectedMethodDescriptor +{ + Method method(); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/composite/InjectedParametersDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/composite/InjectedParametersDescriptor.java b/core/api/src/main/java/org/apache/zest/api/composite/InjectedParametersDescriptor.java new file mode 100644 index 0000000..76121e2 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/composite/InjectedParametersDescriptor.java @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2008, Rickard Ãberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.zest.api.composite; + +/** + * Composite constructors and method injected parameters descriptor. + */ +public interface InjectedParametersDescriptor +{ +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/composite/InvalidCompositeException.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/composite/InvalidCompositeException.java b/core/api/src/main/java/org/apache/zest/api/composite/InvalidCompositeException.java new file mode 100644 index 0000000..82fb572 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/composite/InvalidCompositeException.java @@ -0,0 +1,29 @@ +/* Copyright 2007 Niclas Hedhman. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zest.api.composite; + +/** + * This exception is thrown if a Composite is invalid. + */ +public class InvalidCompositeException + extends RuntimeException +{ + public InvalidCompositeException( String message ) + { + super( message ); + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/composite/InvalidValueCompositeException.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/composite/InvalidValueCompositeException.java b/core/api/src/main/java/org/apache/zest/api/composite/InvalidValueCompositeException.java new file mode 100644 index 0000000..a77acd4 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/composite/InvalidValueCompositeException.java @@ -0,0 +1,30 @@ +/* + * Copyright 2009 Niclas Hedhman. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.zest.api.composite; + +/** + * This exception is thrown if a ValueComposite is invalid. + */ +public class InvalidValueCompositeException + extends RuntimeException +{ + public InvalidValueCompositeException( String message ) + { + super( message ); + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/composite/MethodDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/composite/MethodDescriptor.java b/core/api/src/main/java/org/apache/zest/api/composite/MethodDescriptor.java new file mode 100644 index 0000000..df408c9 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/composite/MethodDescriptor.java @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2008, Rickard Ãberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.apache.zest.api.composite; + +import java.lang.reflect.Method; + +/** + * Composite Method Descriptor. + */ +public interface MethodDescriptor +{ + Method method(); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/composite/MissingMethodException.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/composite/MissingMethodException.java b/core/api/src/main/java/org/apache/zest/api/composite/MissingMethodException.java new file mode 100644 index 0000000..009f5e9 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/composite/MissingMethodException.java @@ -0,0 +1,36 @@ +/* + * Copyright 2009 Niclas Hedhman. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.zest.api.composite; + +/** + * This exception is thrown if client code tries to invoke a non-existing Composite method. + */ +public class MissingMethodException + extends RuntimeException +{ + public MissingMethodException( String message ) + { + super( message ); + } + + public MissingMethodException( String message, NoSuchMethodException e ) + { + super(message,e); + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/composite/ModelDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/composite/ModelDescriptor.java b/core/api/src/main/java/org/apache/zest/api/composite/ModelDescriptor.java new file mode 100644 index 0000000..a1bef87 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/composite/ModelDescriptor.java @@ -0,0 +1,33 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.apache.zest.api.composite; + +import org.apache.zest.api.common.Visibility; +import org.apache.zest.api.structure.MetaInfoHolder; +import org.apache.zest.api.type.HasTypes; + +/** + * Composite ModelDescriptor. + */ +public interface ModelDescriptor extends HasTypes, MetaInfoHolder +{ + Visibility visibility(); + + boolean isAssignableTo( Class<?> type ); +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/composite/NoSuchCompositeException.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/composite/NoSuchCompositeException.java b/core/api/src/main/java/org/apache/zest/api/composite/NoSuchCompositeException.java new file mode 100644 index 0000000..3583322 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/composite/NoSuchCompositeException.java @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2008, Niclas Hedhman. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.apache.zest.api.composite; + +import org.apache.zest.api.common.InvalidApplicationException; + +/** + * This exception is thrown if client code tries to create a non-existing Composite type. + */ +public class NoSuchCompositeException + extends InvalidApplicationException +{ + private static final long serialVersionUID = 1L; + + private final String compositeType; + private final String moduleName; + + protected NoSuchCompositeException( String metaType, String compositeType, String moduleName ) + { + super( "Could not find any visible " + metaType + " of type [" + compositeType + "] in module [" + + moduleName + "]." ); + this.compositeType = compositeType; + this.moduleName = moduleName; + } + + public String compositeType() + { + return compositeType; + } + + public String moduleName() + { + return moduleName; + } +} http://git-wip-us.apache.org/repos/asf/zest-java/blob/8744a67f/core/api/src/main/java/org/apache/zest/api/composite/NoSuchTransientException.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/apache/zest/api/composite/NoSuchTransientException.java b/core/api/src/main/java/org/apache/zest/api/composite/NoSuchTransientException.java new file mode 100644 index 0000000..5cd6046 --- /dev/null +++ b/core/api/src/main/java/org/apache/zest/api/composite/NoSuchTransientException.java @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2012, Niclas Hedhman. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * You may obtain a copy of the License at + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.zest.api.composite; + +/** + * This exception is thrown if client code tries to create a non-existing TransientComposite type. + */ +public class NoSuchTransientException extends NoSuchCompositeException +{ + public NoSuchTransientException( String typeName, String moduleName ) + { + super( "TransientComposite", typeName, moduleName ); + } +}
