Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 1014E200D63 for ; Thu, 21 Dec 2017 08:12:02 +0100 (CET) Received: by cust-asf.ponee.io (Postfix) id 0E9EE160C32; Thu, 21 Dec 2017 07:12:02 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 20B93160C48 for ; Thu, 21 Dec 2017 08:11:58 +0100 (CET) Received: (qmail 10701 invoked by uid 500); 21 Dec 2017 07:11:58 -0000 Mailing-List: contact commits-help@polygene.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@polygene.apache.org Delivered-To: mailing list commits@polygene.apache.org Received: (qmail 10021 invoked by uid 99); 21 Dec 2017 07:11:57 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 21 Dec 2017 07:11:57 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id F27E5F31FB; Thu, 21 Dec 2017 07:11:55 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: niclas@apache.org To: commits@polygene.apache.org Date: Thu, 21 Dec 2017 07:12:32 -0000 Message-Id: In-Reply-To: <309c5146cae346f09aa06a2a98a9f065@git.apache.org> References: <309c5146cae346f09aa06a2a98a9f065@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [39/57] [abbrv] [partial] polygene-java git commit: Revert "First round of changes to move to org.apache.zest namespace." archived-at: Thu, 21 Dec 2017 07:12:02 -0000 http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/QualifiedName.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/common/QualifiedName.java b/core/api/src/main/java/org/qi4j/api/common/QualifiedName.java new file mode 100644 index 0000000..a869791 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.common; + +import java.io.Serializable; +import java.lang.reflect.AccessibleObject; +import java.lang.reflect.Member; +import org.qi4j.api.util.NullArgumentException; + +/** + * QualifiedName is a representation of Property names to their full declaration. + *

+ * 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. + *

+ *

+ * 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. + *

+ *

+ * 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 must be made in a backward-compatible manner + * . + *

+ *

+ * 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. + *

+ *

+ * 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, Serializable +{ + private final TypeName typeName; + private final String name; + + /** + * Creates a QualifiedName from a method. + *

+ * This factory method will create a QualifiedName from the Method itself. + * + *

+ * + * @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. + *

+ * 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. + *

+ * This factory method is the reverse of {@link QualifiedName#toString() } method, and creates a new QualifiedName + * instance from the string representation of the QualifiedName. + *

+ * + * @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. + * + *

+ * The normalized type name means that all dollar ($) characters have been replaced by dashes (-). + *

+ * + * @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. + * + *

+ * The URI is the {@link #toNamespace()} followed by the {@code name} component. + *

+ * + * @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. + *

+ * The URI of the {@link TypeName} component is in the form of; + *

+ *
+     * "urn:qi4j:type:" normalizedClassName
+     * 
+ *

+ * where {@code normalizedClassName} is the fully-qualified class name having had any dollar ($) characters replaced + * by URI friendly dashes (-), with a trailing hash (#). Examples; + *

+ *
+     * urn:qi4j:type:org.qi4j.api.common.QualifiedName#
+     * urn:qi4j:type:org.qi4j.samples.MyClass-MyInnerClass#
+     * 
+ * + * @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. + *

+ * This returns the {@link org.qi4j.api.common.TypeName#toString()} followed by the {@code name} component. + *

+ * + * @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/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/TypeName.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/common/TypeName.java b/core/api/src/main/java/org/qi4j/api/common/TypeName.java new file mode 100644 index 0000000..6a485e6 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.common; + +import java.io.Serializable; +import java.lang.reflect.Type; +import org.qi4j.api.util.Classes; +import org.qi4j.api.util.NullArgumentException; + +/** + * Represents a Type name. + */ +public final class TypeName + implements Serializable, Comparable +{ + 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/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/UseDefaults.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/common/UseDefaults.java b/core/api/src/main/java/org/qi4j/api/common/UseDefaults.java new file mode 100644 index 0000000..94f4446 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.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. + *

+ * These are the default values used for various types: + *

+ *
+ * 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
+ * 
+ *

+ * If this annotation is not used, the property will be set to null, and unless {@code @Optional} is declared + * is not allowed. + *

+ *

+ * 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. + *

+ *

+ * Example; + * Let's assume that we have the following mixin type; + * + *


+ * public interface SomeType
+ * {
+ *     @UseDefaults
+ *     Property<String> someValue();
+ * }
+ * 
+ * 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. + *

+ * public void assemble( ModuleAssembly module )
+ * {
+ *     module.forMixin( SomeType.class ).declareDefaults().someValue().set( "<unknown>" );
+ * }
+ * }
+ * 
+ */ +@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/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/Visibility.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/common/Visibility.java b/core/api/src/main/java/org/qi4j/api/common/Visibility.java new file mode 100644 index 0000000..0f38f36 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.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. + *

+ * 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. + *

+ */ +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/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/common/package.html ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/common/package.html b/core/api/src/main/java/org/qi4j/api/common/package.html new file mode 100644 index 0000000..f29de5d --- /dev/null +++ b/core/api/src/main/java/org/qi4j/api/common/package.html @@ -0,0 +1,81 @@ + + + +

Common API.

+

+ 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. +

+

+ In this package, you can safely ignore the following classes; +

+
    +
  • MetaInfo
  • +
  • QualifiedName
  • +
  • TypeName
  • +
+

UNLESS you are into deep integration into the Zest™ Runtime.

+ +

@AppliesTo and AppliesToFilter

+

+ This tandem of interface + annotation are primarily used for Generic Fragments, to indicate which methods on the + interface the fragment should be applied to. +

+ +

@Optional

+

+ 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. +

+ +

@UseDefaults

+

+ 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. +

+ +

@Visibility

+

+ 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; +

+
    +
  1. 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. +
  2. +
  3. Search all modules in the Layer of the caller for composite that has a declaration other than + Visibility.module. 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. +
  4. +
  5. Search all modules in the Layer(s) (if any) directly below of the caller for composite that has a declaration of + Visibility.application. 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. +
  6. +
  7. Throw an NoSuchCompositeException (or related) exception.
  8. +
+ + \ No newline at end of file http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/AmbiguousTypeException.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/AmbiguousTypeException.java b/core/api/src/main/java/org/qi4j/api/composite/AmbiguousTypeException.java new file mode 100644 index 0000000..34f3653 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.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. + *

+ * For instance; + *

+ *

+ * 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 );
+ * 
+ *

+ * In the code above, both the AbcComposite and DefComposite implement Abc, and therefore + * the newTransientBuilder method can not unambiguously figure out which + * one is intended. + *

+ */ +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/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/Composite.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/Composite.java b/core/api/src/main/java/org/qi4j/api/composite/Composite.java new file mode 100644 index 0000000..91662fb --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.composite; + +import org.qi4j.api.mixin.Mixins; +import org.qi4j.api.property.PropertyMixin; + +/** + * Base Composite interface. + *

+ * All Composite objects must implement this interface. Let the + * Composite interface extend this one. An implementation will be provided + * by the framework. + *

+ *

+ * Properties and associations are handled by default. + *

+ */ +@Mixins( { PropertyMixin.class } ) +public interface Composite +{ +} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/CompositeContext.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/CompositeContext.java b/core/api/src/main/java/org/qi4j/api/composite/CompositeContext.java new file mode 100644 index 0000000..d8a2aa7 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.composite; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import org.qi4j.api.Qi4j; +import org.qi4j.api.structure.Module; +import org.qi4j.functional.Iterables; + +import static org.qi4j.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 + extends ThreadLocal +{ + private Module module; + private Class type; + + public CompositeContext( Module module, Class type ) + { + this.module = module; + this.type = type; + } + + @Override + protected T initialValue() + { + return module.newTransient( type ); + } + + @SuppressWarnings( "unchecked" ) + public T proxy() + { + TransientComposite composite = get(); + + Iterable> types = Qi4j.FUNCTION_COMPOSITE_INSTANCE_OF.map( composite ).types(); + return (T) Proxy.newProxyInstance( + composite.getClass().getClassLoader(), + toArray( Class.class, Iterables.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/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/CompositeDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/CompositeDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/CompositeDescriptor.java new file mode 100644 index 0000000..40b4462 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.composite; + +/** + * Composite Descriptor. + */ +public interface CompositeDescriptor + extends ModelDescriptor +{ + Class primaryType(); + + Iterable> mixinTypes(); +} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/CompositeInstance.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/CompositeInstance.java b/core/api/src/main/java/org/qi4j/api/composite/CompositeInstance.java new file mode 100644 index 0000000..79f8d62 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.composite; + +import java.lang.reflect.InvocationHandler; +import org.qi4j.api.property.StateHolder; +import org.qi4j.api.structure.MetaInfoHolder; +import org.qi4j.api.structure.Module; +import org.qi4j.api.type.HasTypes; + +/** + * Composite Instance. + */ +public interface CompositeInstance + extends InvocationHandler, CompositeInvoker, HasTypes, MetaInfoHolder +{ + T proxy(); + + T newProxy( Class mixinType ) + throws IllegalArgumentException; + + Module module(); + + CompositeDescriptor descriptor(); + + StateHolder state(); +} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/CompositeInvoker.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/CompositeInvoker.java b/core/api/src/main/java/org/qi4j/api/composite/CompositeInvoker.java new file mode 100644 index 0000000..5bd8d11 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.composite; + +import java.lang.reflect.Method; + +/** + * Composite method invoker. + *

+ * All composites must implement this interface. Methods that are invoked + * may reside either in the public Composite interface or in any internal mixins. + *

+ *

+ * NOTE: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. + *

+ */ +public interface CompositeInvoker +{ + + Object invokeComposite( Method method, Object[] args ) + throws Throwable; + +} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/ConstructorDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/ConstructorDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/ConstructorDescriptor.java new file mode 100644 index 0000000..6e74dd9 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.composite; + +import java.lang.reflect.Constructor; + +/** + * Composite constructor descriptor. + */ +public interface ConstructorDescriptor +{ + Constructor constructor(); +} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/DecoratorMixin.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/DecoratorMixin.java b/core/api/src/main/java/org/qi4j/api/composite/DecoratorMixin.java new file mode 100644 index 0000000..6b81844 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.composite; + +import java.lang.reflect.InvocationHandler; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.Proxy; +import org.qi4j.api.injection.scope.Uses; + +/** + * Generic decorator mixin that allows a Composite to wrap + * any other Composite as long as they share an interface. + *

+ * Can be used to effectively implement + * singleton mixins, since the decorated object can be shared between + * many instances. + *

+ */ +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/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/DependencyDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/DependencyDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/DependencyDescriptor.java new file mode 100644 index 0000000..70d7d06 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.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/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/InjectedFieldDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/InjectedFieldDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/InjectedFieldDescriptor.java new file mode 100644 index 0000000..2f7297e --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.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/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/InjectedMethodDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/InjectedMethodDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/InjectedMethodDescriptor.java new file mode 100644 index 0000000..8888d32 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.composite; + +import java.lang.reflect.Method; + +/** + * Composite injected method descriptor. + */ +public interface InjectedMethodDescriptor +{ + Method method(); +} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/InjectedParametersDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/InjectedParametersDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/InjectedParametersDescriptor.java new file mode 100644 index 0000000..301c56d --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.composite; + +/** + * Composite constructors and method injected parameters descriptor. + */ +public interface InjectedParametersDescriptor +{ +} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/InvalidCompositeException.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/InvalidCompositeException.java b/core/api/src/main/java/org/qi4j/api/composite/InvalidCompositeException.java new file mode 100644 index 0000000..e5b86c0 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.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/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/InvalidValueCompositeException.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/InvalidValueCompositeException.java b/core/api/src/main/java/org/qi4j/api/composite/InvalidValueCompositeException.java new file mode 100644 index 0000000..60a48dd --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.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/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/MethodDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/MethodDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/MethodDescriptor.java new file mode 100644 index 0000000..2f88f35 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.composite; + +import java.lang.reflect.Method; + +/** + * Composite Method Descriptor. + */ +public interface MethodDescriptor +{ + Method method(); +} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/MissingMethodException.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/MissingMethodException.java b/core/api/src/main/java/org/qi4j/api/composite/MissingMethodException.java new file mode 100644 index 0000000..ae362cb --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.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/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/ModelDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/ModelDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/ModelDescriptor.java new file mode 100644 index 0000000..b0651f0 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.composite; + +import org.qi4j.api.common.Visibility; +import org.qi4j.api.structure.MetaInfoHolder; +import org.qi4j.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/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/NoSuchCompositeException.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/NoSuchCompositeException.java b/core/api/src/main/java/org/qi4j/api/composite/NoSuchCompositeException.java new file mode 100644 index 0000000..b404779 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.api.composite; + +import org.qi4j.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/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/NoSuchTransientException.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/NoSuchTransientException.java b/core/api/src/main/java/org/qi4j/api/composite/NoSuchTransientException.java new file mode 100644 index 0000000..e6a6f61 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/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.qi4j.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 ); + } +} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/PropertyMapper.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/PropertyMapper.java b/core/api/src/main/java/org/qi4j/api/composite/PropertyMapper.java new file mode 100644 index 0000000..054a369 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/api/composite/PropertyMapper.java @@ -0,0 +1,580 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.qi4j.api.composite; + +import java.io.IOException; +import java.io.InputStream; +import java.lang.reflect.Array; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.lang.reflect.ParameterizedType; +import java.lang.reflect.Type; +import java.math.BigDecimal; +import java.math.BigInteger; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Date; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.Set; +import org.qi4j.api.Qi4j; +import org.qi4j.api.property.GenericPropertyInfo; +import org.qi4j.api.property.Property; +import org.qi4j.api.util.Classes; +import org.qi4j.api.util.Dates; +import org.qi4j.api.value.ValueComposite; + +/** + * Transfer java.util.Properties to Composite properties + */ +public final class PropertyMapper +{ + + private final static Map STRATEGY; + + static + { + STRATEGY = new HashMap<>(); + STRATEGY.put( Integer.class, new IntegerMapper() ); + STRATEGY.put( Long.class, new LongMapper() ); + STRATEGY.put( Short.class, new ShortMapper() ); + STRATEGY.put( Byte.class, new ByteMapper() ); + STRATEGY.put( String.class, new StringMapper() ); + STRATEGY.put( Character.class, new CharMapper() ); + STRATEGY.put( Float.class, new FloatMapper() ); + STRATEGY.put( Double.class, new DoubleMapper() ); + STRATEGY.put( Date.class, new DateMapper() ); + STRATEGY.put( Boolean.class, new BooleanMapper() ); + STRATEGY.put( BigDecimal.class, new BigDecimalMapper() ); + STRATEGY.put( BigInteger.class, new BigIntegerMapper() ); + STRATEGY.put( Enum.class, new EnumMapper() ); + STRATEGY.put( Array.class, new ArrayMapper() ); + STRATEGY.put( Map.class, new MapMapper() ); + STRATEGY.put( List.class, new ListMapper() ); + STRATEGY.put( Set.class, new SetMapper() ); + STRATEGY.put( ValueComposite.class, new ValueCompositeMapper() ); + } + + /** + * Populate the Composite with properties from the given properties object. + * + * @param props properties object + * @param composite the composite instance + * + * @throws IllegalArgumentException if properties could not be transferred to composite + */ + public static void map( Properties props, Composite composite ) + throws IllegalArgumentException + { + for( Map.Entry objectObjectEntry : props.entrySet() ) + { + try + { + String methodName = objectObjectEntry.getKey().toString(); + Method propertyMethod = composite.getClass().getInterfaces()[ 0 ].getMethod( methodName ); + propertyMethod.setAccessible( true ); + Object value = objectObjectEntry.getValue(); + Type propertyType = GenericPropertyInfo.propertyTypeOf( propertyMethod ); + + value = mapToType( composite, propertyType, value.toString() ); + + @SuppressWarnings( "unchecked" ) + Property property = (Property) propertyMethod.invoke( composite ); + property.set( value ); + } + catch( NoSuchMethodException e ) + { + throw new IllegalArgumentException( "Could not find any property named " + objectObjectEntry.getKey() ); + } + catch( IllegalAccessException e ) + { + //noinspection ThrowableInstanceNeverThrown + throw new IllegalArgumentException( "Could not populate property named " + objectObjectEntry.getKey(), e ); + } + catch( InvocationTargetException e ) + { + //noinspection ThrowableInstanceNeverThrown + String message = "Could not populate property named " + objectObjectEntry.getKey(); + throw new IllegalArgumentException( message, e ); + } + } + } + + @SuppressWarnings( "raw" ) + private static Object mapToType( Composite composite, Type propertyType, Object value ) + { + final String stringValue = value.toString(); + MappingStrategy strategy; + if( propertyType instanceof Class ) + { + Class type = (Class) propertyType; + if( type.isArray() ) + { + strategy = STRATEGY.get( Array.class ); + } + else if( Enum.class.isAssignableFrom( Classes.RAW_CLASS.map( propertyType ) ) ) + { + strategy = STRATEGY.get( Enum.class ); + } + else + { + strategy = STRATEGY.get( type ); + } + if( strategy == null ) // If null, try with the ValueComposite Mapper... + { + strategy = STRATEGY.get( ValueComposite.class ); + } + } + else if( propertyType instanceof ParameterizedType ) + { + ParameterizedType type = ( (ParameterizedType) propertyType ); + + if( type.getRawType() instanceof Class ) + { + Class clazz = (Class) type.getRawType(); + if( List.class.isAssignableFrom( clazz ) ) + { + strategy = STRATEGY.get( List.class ); + } + else if( Set.class.isAssignableFrom( clazz ) ) + { + strategy = STRATEGY.get( Set.class ); + } + else if( Map.class.isAssignableFrom( clazz ) ) + { + strategy = STRATEGY.get( Map.class ); + } + else + { + throw new IllegalArgumentException( propertyType + " is not supported." ); + } + } + else + { + throw new IllegalArgumentException( propertyType + " is not supported." ); + } + } + else + { + throw new IllegalArgumentException( propertyType + " is not supported." ); + } + + if( strategy == null ) + { + throw new IllegalArgumentException( propertyType + " is not supported." ); + } + + return strategy.map( composite, propertyType, stringValue ); + } + + /** + * Load a Properties object from the given stream, close it, and then populate + * the Composite with the properties. + * + * @param propertyInputStream properties input stream + * @param composite the instance + * + * @throws IOException if the stream could not be read + */ + + public static void map( InputStream propertyInputStream, Composite composite ) + throws IOException + { + if( propertyInputStream != null ) + { + Properties configProps = new Properties(); + try + { + configProps.load( propertyInputStream ); + } + finally + { + propertyInputStream.close(); + } + map( configProps, composite ); + } + } + + /** + * Create Properties object which is backed by the given Composite. + * + * @param composite the instance + * + * @return properties instance + */ + public static Properties toJavaProperties( final Composite composite ) + { + return new Properties() + { + private static final long serialVersionUID = 3550125427530538865L; + + @Override + public Object get( Object o ) + { + try + { + Method propertyMethod = composite.getClass().getMethod( o.toString() ); + Property property = (Property) propertyMethod.invoke( composite ); + return property.get(); + } + catch( NoSuchMethodException | IllegalAccessException | InvocationTargetException e ) + { + return null; + } + } + + @Override + public Object put( Object o, Object o1 ) + { + Object oldValue = get( o ); + + try + { + Method propertyMethod = composite.getClass().getMethod( o.toString(), Object.class ); + propertyMethod.invoke( composite, o1 ); + } + catch( NoSuchMethodException | IllegalAccessException | InvocationTargetException e ) + { + e.printStackTrace(); + } + + return oldValue; + } + }; + } + + private static void tokenize( String valueString, boolean mapSyntax, TokenizerCallback callback ) + { + char[] data = valueString.toCharArray(); + + int oldPos = 0; + for( int pos = 0; pos < data.length; pos++ ) + { + char ch = data[ pos ]; + if( ch == '\"' ) + { + pos = resolveQuotes( valueString, callback, data, pos, '\"' ); + oldPos = pos; + } + if( ch == '\'' ) + { + pos = resolveQuotes( valueString, callback, data, pos, '\'' ); + oldPos = pos; + } + if( ch == ',' || ( mapSyntax && ch == ':' ) ) + { + String token = new String( data, oldPos, pos - oldPos ); + callback.token( token ); + oldPos = pos + 1; + } + } + String token = new String( data, oldPos, data.length - oldPos ); + callback.token( token ); + } + + private static int resolveQuotes( String valueString, + TokenizerCallback callback, + char[] data, + int pos, char quote + ) + { + boolean found = false; + for( int j = pos + 1; j < data.length; j++ ) + { + if( !found ) + { + if( data[ j ] == quote ) + { + String token = new String( data, pos + 1, j - pos - 1 ); + callback.token( token ); + found = true; + } + } + else + { + if( data[ j ] == ',' ) + { + return j + 1; + } + } + } + if( !found ) + { + throw new IllegalArgumentException( "String is not quoted correctly: " + valueString ); + } + return data.length; + } + + private interface TokenizerCallback + { + void token( String token ); + } + + private interface MappingStrategy + { + Object map( Composite composite, Type type, String value ); + } + + private static class StringMapper + implements MappingStrategy + { + @Override + public Object map( Composite composite, Type type, String value ) + { + return value; + } + } + + private static class IntegerMapper + implements MappingStrategy + { + @Override + public Object map( Composite composite, Type type, String value ) + { + return new Integer( value.trim() ); + } + } + + private static class FloatMapper + implements MappingStrategy + { + @Override + public Object map( Composite composite, Type type, String value ) + { + return new Float( value.trim() ); + } + } + + private static class DoubleMapper + implements MappingStrategy + { + @Override + public Object map( Composite composite, Type type, String value ) + { + return new Double( value.trim() ); + } + } + + private static class LongMapper + implements MappingStrategy + { + @Override + public Object map( Composite composite, Type type, String value ) + { + return new Long( value.trim() ); + } + } + + private static class ShortMapper + implements MappingStrategy + { + @Override + public Object map( Composite composite, Type type, String value ) + { + return new Short( value.trim() ); + } + } + + private static class ByteMapper + implements MappingStrategy + { + @Override + public Object map( Composite composite, Type type, String value ) + { + return new Byte( value.trim() ); + } + } + + private static class CharMapper + implements MappingStrategy + { + @Override + public Object map( Composite composite, Type type, String value ) + { + return value.trim().charAt( 0 ); + } + } + + private static class BigDecimalMapper + implements MappingStrategy + { + @Override + public Object map( Composite composite, Type type, String value ) + { + return new BigDecimal( value.trim() ); + } + } + + private static class BigIntegerMapper + implements MappingStrategy + { + @Override + public Object map( Composite composite, Type type, String value ) + { + return new BigInteger( value.trim() ); + } + } + + private static class EnumMapper + implements MappingStrategy + { + @Override + @SuppressWarnings( "unchecked" ) + public Object map( Composite composite, Type type, String value ) + { + return Enum.valueOf( (Class) type, value ); + } + } + + private static class DateMapper + implements MappingStrategy + { + @Override + public Object map( Composite composite, Type type, String value ) + { + return Dates.fromString( value.trim() ); + } + } + + private static class ValueCompositeMapper + implements MappingStrategy + { + @Override + @SuppressWarnings( "unchecked" ) + public Object map( Composite composite, Type type, String value ) + { + return Qi4j.FUNCTION_COMPOSITE_INSTANCE_OF.map( composite ).module().newValueFromSerializedState( (Class) type, value ); + } + } + + private static class ArrayMapper + implements MappingStrategy + { + @Override + @SuppressWarnings( {"raw", "unchecked"} ) + public Object map( final Composite composite, Type type, String value ) + { + final Class arrayType = ( (Class) type ).getComponentType(); + final ArrayList result = new ArrayList(); + tokenize( value, false, new TokenizerCallback() + { + @Override + public void token( String token ) + { + result.add( mapToType( composite, arrayType, token ) ); + } + } ); + return result.toArray( (Object[]) Array.newInstance( arrayType, result.size() ) ); + } + } + + private static class BooleanMapper + implements MappingStrategy + { + @Override + public Object map( final Composite composite, Type type, String value ) + { + return Boolean.valueOf( value.trim() ); + } + } + + private static class ListMapper + implements MappingStrategy + { + @Override + @SuppressWarnings( {"raw", "unchecked"} ) + public Object map( final Composite composite, Type type, String value ) + { + final Type dataType = ( (ParameterizedType) type ).getActualTypeArguments()[ 0 ]; + final Collection result = new ArrayList(); + tokenize( value, false, new TokenizerCallback() + { + @Override + public void token( String token ) + { + result.add( mapToType( composite, dataType, token ) ); + } + } ); + return result; + } + } + + private static class SetMapper + implements MappingStrategy + { + @Override + @SuppressWarnings( {"raw", "unchecked"} ) + public Object map( final Composite composite, Type type, String value ) + { + final Type dataType = ( (ParameterizedType) type ).getActualTypeArguments()[ 0 ]; + final Collection result = new HashSet(); + tokenize( value, false, new TokenizerCallback() + { + @Override + public void token( String token ) + { + result.add( mapToType( composite, dataType, token ) ); + } + } ); + return result; + } + } + + private static class MapMapper + implements MappingStrategy + { + @Override + @SuppressWarnings( {"raw", "unchecked"} ) + public Object map( final Composite composite, Type generictype, String value ) + { + ParameterizedType type = (ParameterizedType) generictype; + final Type keyType = type.getActualTypeArguments()[ 0 ]; + final Type valueType = type.getActualTypeArguments()[ 0 ]; + final Map result = new HashMap(); + tokenize( value, true, new TokenizerCallback() + { + boolean keyArrivingNext = true; + String key; + + @Override + public void token( String token ) + { + if( keyArrivingNext ) + { + key = token; + keyArrivingNext = false; + } + else + { + result.put( mapToType( composite, keyType, key ), mapToType( composite, valueType, token ) ); + keyArrivingNext = true; + } + } + } ); + return result; + } + } + + private PropertyMapper() + { + } +} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/StateDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/StateDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/StateDescriptor.java new file mode 100644 index 0000000..3eebcd4 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/api/composite/StateDescriptor.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2008, Rickard Öberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.qi4j.api.composite; + +import org.qi4j.api.common.QualifiedName; +import org.qi4j.api.property.PropertyDescriptor; + +/** + * Composite State Descriptor. + */ +public interface StateDescriptor +{ + PropertyDescriptor findPropertyModelByName( String name ) + throws IllegalArgumentException; + + PropertyDescriptor findPropertyModelByQualifiedName( QualifiedName name ) + throws IllegalArgumentException; + + Iterable properties(); +} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/StatefulCompositeDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/StatefulCompositeDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/StatefulCompositeDescriptor.java new file mode 100644 index 0000000..ba44494 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/api/composite/StatefulCompositeDescriptor.java @@ -0,0 +1,27 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package org.qi4j.api.composite; + +/** + * Stateful Composite Descriptor. + */ +public interface StatefulCompositeDescriptor +{ + StateDescriptor state(); +} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/TransientBuilder.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/TransientBuilder.java b/core/api/src/main/java/org/qi4j/api/composite/TransientBuilder.java new file mode 100644 index 0000000..58b4ef6 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/api/composite/TransientBuilder.java @@ -0,0 +1,68 @@ +/* Copyright 2007 Niclas Hedhman. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + * implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.qi4j.api.composite; + +import org.qi4j.api.common.ConstructionException; + +/** + * TransientBuilders are used to instantiate TransientComposites. They can be acquired from + * {@link TransientBuilderFactory#newTransientBuilder(Class)} and allows the client + * to provide additional settings before instantiating the TransientComposite. + */ +public interface TransientBuilder +{ + /** + * Provide objects that can be injected into mixins that has the @Uses + * dependency injection annotation. + * + * @param usedObjects The objects that can be injected into mixins. + * + * @return the transient builder instance + * + * @see org.qi4j.api.injection.scope.Uses + */ + TransientBuilder use( Object... usedObjects ); + + /** + * Get a representation of the state for the new Composite. + * It is possible to access and update properties and associations, + * even immutable ones since the builder represents the initial state. + * + * @return a proxy implementing the Composite type + */ + T prototype(); + + /** + * Get a representation of the state of the given type for the new Composite. + * This is primarily used if you want to provide state for a private mixin type. + * + * @param mixinType the mixin which you want to provide state for + * + * @return a proxy implementing the given mixin type + */ + K prototypeFor( Class mixinType ); + + /** + * Create a new Composite instance. + * + * @return a new Composite instance + * + * @throws ConstructionException thrown if it was not possible to instantiate the Composite + */ + T newInstance() + throws ConstructionException; +} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/TransientBuilderFactory.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/TransientBuilderFactory.java b/core/api/src/main/java/org/qi4j/api/composite/TransientBuilderFactory.java new file mode 100644 index 0000000..b06c58f --- /dev/null +++ b/core/api/src/main/java/org/qi4j/api/composite/TransientBuilderFactory.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2007, Rickard Öberg. All Rights Reserved. + * Copyright (c) 2007, Niclas Hedhman. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +package org.qi4j.api.composite; + +import org.qi4j.api.common.ConstructionException; + +/** + * This factory creates TransientComposites and the TransientBuilders. + * + * TransientComposite instances are very flexible in what it can reference, but are restricted in where they + * can be used. So, TransientComposites are mainly recommended where Values, Entities and Services can not be used, + * but they can also not be used to store state, be serialized across a network or have automatic equals/hashCode + * calculations. + */ +public interface TransientBuilderFactory +{ + /** + * Create a builder for creating new TransientComposites that implements the given TransientComposite type. + * + * @param mixinType an interface that describes the TransientComposite to be instantiated + * + * @return a TransientBuilder for creation of TransientComposites implementing the interface + * + * @throws NoSuchTransientException if no composite extending the mixinType has been registered + */ + TransientBuilder newTransientBuilder( Class mixinType ) + throws NoSuchTransientException; + + /** + * Instantiate a TransientComposite of the given type. + * + * @param mixinType the TransientComposite type to instantiate + * + * @return a new TransientComposite instance + * + * @throws NoSuchTransientException if no composite extending the mixinType has been registered + * @throws org.qi4j.api.common.ConstructionException + * if the composite could not be instantiated + */ + T newTransient( Class mixinType, Object... uses ) + throws NoSuchTransientException, ConstructionException; +} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/TransientComposite.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/TransientComposite.java b/core/api/src/main/java/org/qi4j/api/composite/TransientComposite.java new file mode 100644 index 0000000..8b21e88 --- /dev/null +++ b/core/api/src/main/java/org/qi4j/api/composite/TransientComposite.java @@ -0,0 +1,35 @@ +/* + * 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.qi4j.api.composite; + +/** + * Transient Composite Type. + * + * TransientComposites have the following criteria; + *
    + *
  • Does not persist its state, and is not serializable
  • + *
  • Can not be referenced from Properties, Associations, ValueComposites nor Entities
  • + *
  • Can reference all types
  • + *
  • No lifecycle
  • + *
  • equals/hashCode is delegated to a single Mixin implementing the methods, like any other method
  • + *
+ */ +public interface TransientComposite + extends Composite +{ +} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/TransientDescriptor.java ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/TransientDescriptor.java b/core/api/src/main/java/org/qi4j/api/composite/TransientDescriptor.java new file mode 100644 index 0000000..0df706c --- /dev/null +++ b/core/api/src/main/java/org/qi4j/api/composite/TransientDescriptor.java @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2008, Rickard Öberg. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package org.qi4j.api.composite; + +/** + * TransientComposite Descriptor. + */ +public interface TransientDescriptor + extends CompositeDescriptor, StatefulCompositeDescriptor +{ +} http://git-wip-us.apache.org/repos/asf/polygene-java/blob/a789141d/core/api/src/main/java/org/qi4j/api/composite/package.html ---------------------------------------------------------------------- diff --git a/core/api/src/main/java/org/qi4j/api/composite/package.html b/core/api/src/main/java/org/qi4j/api/composite/package.html new file mode 100644 index 0000000..00feaed --- /dev/null +++ b/core/api/src/main/java/org/qi4j/api/composite/package.html @@ -0,0 +1,21 @@ + + + +

Composite API.

+ +