polygene-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From nic...@apache.org
Subject [44/81] [abbrv] [partial] zest-java git commit: First round of changes to move to org.apache.zest namespace.
Date Fri, 31 Jul 2015 02:59:24 GMT
http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/query/grammar/NamedAssociationFunction.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/query/grammar/NamedAssociationFunction.java b/core/api/src/main/java/org/apache/zest/api/query/grammar/NamedAssociationFunction.java
new file mode 100644
index 0000000..d60468e
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/query/grammar/NamedAssociationFunction.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2011-2012 Niclas Hedhman.
+ * Copyright 2014 Paul Merlin.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * ied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zest.api.query.grammar;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Member;
+import java.lang.reflect.Proxy;
+import org.apache.zest.api.association.AssociationStateHolder;
+import org.apache.zest.api.association.NamedAssociation;
+import org.apache.zest.api.composite.Composite;
+import org.apache.zest.api.composite.CompositeInstance;
+import org.apache.zest.functional.Function;
+
+/**
+ * Function to get Entity NamedAssociations.
+ */
+public class NamedAssociationFunction<T>
+    implements Function<Composite, NamedAssociation<T>>
+{
+    private final AssociationFunction<?> traversedAssociation;
+    private final ManyAssociationFunction<?> traversedManyAssociation;
+    private final NamedAssociationFunction<?> traversedNamedAssociation;
+    private final AccessibleObject accessor;
+
+    public NamedAssociationFunction( AssociationFunction<?> traversedAssociation,
+                                     ManyAssociationFunction<?> traversedManyAssociation,
+                                     NamedAssociationFunction<?> traversedNamedAssociation,
+                                     AccessibleObject accessor
+    )
+    {
+        this.traversedAssociation = traversedAssociation;
+        this.traversedManyAssociation = traversedManyAssociation;
+        this.traversedNamedAssociation = traversedNamedAssociation;
+        this.accessor = accessor;
+    }
+
+    public AssociationFunction<?> traversedAssociation()
+    {
+        return traversedAssociation;
+    }
+
+    public ManyAssociationFunction<?> traversedManyAssociation()
+    {
+        return traversedManyAssociation;
+    }
+
+    public NamedAssociationFunction<?> traversedNamedAssociation()
+    {
+        return traversedNamedAssociation;
+    }
+
+    public AccessibleObject accessor()
+    {
+        return accessor;
+    }
+
+    @Override
+    public NamedAssociation<T> map( Composite entity )
+    {
+        try
+        {
+            Object target = entity;
+            if( traversedAssociation != null )
+            {
+                target = traversedAssociation.map( entity ).get();
+            }
+            if( traversedManyAssociation != null )
+            {
+                throw new IllegalArgumentException( "Cannot traverse ManyAssociations" );
+            }
+            if( traversedNamedAssociation != null )
+            {
+                throw new IllegalArgumentException( "Cannot traverse NamedAssociations" );
+            }
+
+            CompositeInstance handler = (CompositeInstance) Proxy.getInvocationHandler( target );
+            return ( (AssociationStateHolder) handler.state() ).namedAssociationFor( accessor );
+        }
+        catch( IllegalArgumentException e )
+        {
+            throw e;
+        }
+        catch( Throwable e )
+        {
+            throw new IllegalArgumentException( e );
+        }
+    }
+
+    @Override
+    public String toString()
+    {
+        if( traversedAssociation != null )
+        {
+            return traversedAssociation.toString() + "." + ( (Member) accessor ).getName();
+        }
+        else
+        {
+            return ( (Member) accessor ).getName();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/query/grammar/NeSpecification.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/query/grammar/NeSpecification.java b/core/api/src/main/java/org/apache/zest/api/query/grammar/NeSpecification.java
new file mode 100644
index 0000000..42b26c7
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/query/grammar/NeSpecification.java
@@ -0,0 +1,43 @@
+/*
+ * 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.query.grammar;
+
+/**
+ * Not equals Specification.
+ */
+public class NeSpecification<T>
+    extends ComparisonSpecification<T>
+{
+    public NeSpecification( PropertyFunction<T> property, T value )
+    {
+        super( property, value );
+    }
+
+    @Override
+    protected boolean compare( T value )
+    {
+        return !value.equals( this.value );
+    }
+
+    @Override
+    public String toString()
+    {
+        return property.toString() + "!=" + value.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/query/grammar/NotSpecification.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/query/grammar/NotSpecification.java b/core/api/src/main/java/org/apache/zest/api/query/grammar/NotSpecification.java
new file mode 100644
index 0000000..046db37
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/query/grammar/NotSpecification.java
@@ -0,0 +1,53 @@
+/*
+ * 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.query.grammar;
+
+import org.apache.zest.api.composite.Composite;
+import org.apache.zest.functional.Specification;
+import org.apache.zest.functional.Specifications;
+
+/**
+ * NOT Specification.
+ */
+public class NotSpecification implements Specification<Composite>
+{
+    private Specification<Composite> operand;
+
+    public NotSpecification( Specification<Composite> operand )
+    {
+        this.operand = operand;
+    }
+
+    public Specification<Composite> operand()
+    {
+        return operand;
+    }
+
+    @Override
+    public boolean satisfiedBy( Composite item )
+    {
+        return Specifications.not( operand ).satisfiedBy( item );
+    }
+
+    @Override
+    public String toString()
+    {
+        return "!" + operand.toString();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/query/grammar/OrSpecification.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/query/grammar/OrSpecification.java b/core/api/src/main/java/org/apache/zest/api/query/grammar/OrSpecification.java
new file mode 100644
index 0000000..1daa1ad
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/query/grammar/OrSpecification.java
@@ -0,0 +1,56 @@
+/*
+ * 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.query.grammar;
+
+import org.apache.zest.api.composite.Composite;
+import org.apache.zest.functional.Specification;
+import org.apache.zest.functional.Specifications;
+
+/**
+ * OR Specification.
+ */
+public class OrSpecification
+    extends BinarySpecification
+{
+
+    public OrSpecification( Iterable<Specification<Composite>> operands )
+    {
+        super( operands );
+    }
+
+    @Override
+    public boolean satisfiedBy( Composite item )
+    {
+        return Specifications.or( operands ).satisfiedBy( item );
+    }
+
+    @Override
+    public String toString()
+    {
+        StringBuilder sb = new StringBuilder( "(" );
+        String or = "";
+        for( Specification<Composite> operand : operands )
+        {
+            sb.append( or ).append( operand );
+            or = " or ";
+        }
+        return sb.append( ")" ).toString();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/query/grammar/OrderBy.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/query/grammar/OrderBy.java b/core/api/src/main/java/org/apache/zest/api/query/grammar/OrderBy.java
new file mode 100644
index 0000000..4fac4d4
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/query/grammar/OrderBy.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright 2007 Niclas Hedhman.
+ * Copyright 2008 Alin Dreghiciu.
+ *
+ * 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.query.grammar;
+
+/**
+ * Query sorting segment.
+ */
+public class OrderBy
+{
+    /**
+     * Order direction.
+     */
+    public enum Order
+    {
+        ASCENDING, DESCENDING
+    }
+
+    /**
+     * Order.
+     */
+    private final PropertyFunction<?> propertyReference;
+    /**
+     * Direction.
+     */
+    private final Order order;
+
+    /**
+     * Constructor.
+     *
+     * @param propertyReference property that determines the order; cannot be null
+     * @param order             direction
+     *
+     * @throws IllegalArgumentException - If property is null
+     */
+    public OrderBy( final PropertyFunction<?> propertyReference,
+                    final Order order
+    )
+    {
+        if( propertyReference == null )
+        {
+            throw new IllegalArgumentException( "Ordering property cannot be null" );
+        }
+        this.propertyReference = propertyReference;
+        this.order = order;
+    }
+
+    /**
+     * Getter.
+     *
+     * @return property; cannot be null
+     */
+    public PropertyFunction<?> property()
+    {
+        return propertyReference;
+    }
+
+    /**
+     * Getter.
+     *
+     * @return direction; cannot be null
+     */
+    public Order order()
+    {
+        return order;
+    }
+
+    @Override
+    public String toString()
+    {
+        return new StringBuilder()
+            .append( propertyReference )
+            .append( " " )
+            .append( order )
+            .toString();
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/query/grammar/PropertyFunction.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/query/grammar/PropertyFunction.java b/core/api/src/main/java/org/apache/zest/api/query/grammar/PropertyFunction.java
new file mode 100644
index 0000000..7b6db53
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/query/grammar/PropertyFunction.java
@@ -0,0 +1,179 @@
+/*
+ * Copyright 2007-2011 Rickard Öberg.
+ * Copyright 2007-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
+ * ied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zest.api.query.grammar;
+
+import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.Member;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Proxy;
+import java.lang.reflect.Type;
+import org.apache.zest.api.association.Association;
+import org.apache.zest.api.composite.Composite;
+import org.apache.zest.api.composite.CompositeInstance;
+import org.apache.zest.api.property.GenericPropertyInfo;
+import org.apache.zest.api.property.Property;
+import org.apache.zest.api.query.NotQueryableException;
+import org.apache.zest.api.query.QueryExpressionException;
+import org.apache.zest.api.util.Classes;
+import org.apache.zest.functional.Function;
+
+import static org.apache.zest.api.util.Classes.typeOf;
+
+/**
+ * Function to get Entity Properties.
+ */
+public class PropertyFunction<T>
+    implements Function<Composite, Property<T>>
+{
+    private final PropertyFunction<?> traversedProperty;
+    private final AssociationFunction<?> traversedAssociation;
+    private final ManyAssociationFunction<?> traversedManyAssociation;
+    private final NamedAssociationFunction<?> traversedNamedAssociation;
+    private final AccessibleObject accessor;
+
+    public PropertyFunction( PropertyFunction<?> traversedProperty,
+                             AssociationFunction<?> traversedAssociation,
+                             ManyAssociationFunction<?> traversedManyAssociation,
+                             NamedAssociationFunction<?> traversedNamedAssociation,
+                             AccessibleObject accessor
+    )
+    {
+        this.traversedProperty = traversedProperty;
+        this.traversedAssociation = traversedAssociation;
+        this.traversedManyAssociation = traversedManyAssociation;
+        this.traversedNamedAssociation = traversedNamedAssociation;
+        this.accessor = accessor;
+
+        // Verify that the property accessor is not marked as non queryable
+        NotQueryableException.throwIfNotQueryable( accessor );
+        // Verify that the property type itself (value composites) is not marked as non queryable
+
+        Type returnType = typeOf( accessor );
+        if( !Property.class.isAssignableFrom( Classes.RAW_CLASS.map( returnType ) ) )
+        {
+            throw new QueryExpressionException( "Not a property type:" + returnType );
+        }
+        Type propertyTypeAsType = GenericPropertyInfo.toPropertyType( returnType );
+        if( propertyTypeAsType instanceof ParameterizedType )
+        {
+            propertyTypeAsType = ( (ParameterizedType) propertyTypeAsType ).getRawType();
+        }
+
+        if( !( propertyTypeAsType instanceof Class ) )
+        {
+            throw new QueryExpressionException( "Unsupported property type:" + propertyTypeAsType );
+        }
+        @SuppressWarnings( "unchecked" )
+        Class<T> type = (Class<T>) propertyTypeAsType;
+        NotQueryableException.throwIfNotQueryable( type );
+    }
+
+    public PropertyFunction<?> traversedProperty()
+    {
+        return traversedProperty;
+    }
+
+    public AssociationFunction<?> traversedAssociation()
+    {
+        return traversedAssociation;
+    }
+
+    public ManyAssociationFunction<?> traversedManyAssociation()
+    {
+        return traversedManyAssociation;
+    }
+
+    public NamedAssociationFunction<?> traversedNamedAssociation()
+    {
+        return traversedNamedAssociation;
+    }
+
+    public AccessibleObject accessor()
+    {
+        return accessor;
+    }
+
+    @Override
+    public Property<T> map( Composite entity )
+    {
+        try
+        {
+            Object target = entity;
+            if( traversedProperty != null )
+            {
+                Property<?> property = traversedProperty.map( entity );
+                if( property == null )
+                {
+                    return null;
+                }
+                target = property.get();
+            }
+            else if( traversedAssociation != null )
+            {
+                Association<?> association = traversedAssociation.map( entity );
+                if( association == null )
+                {
+                    return null;
+                }
+                target = association.get();
+            }
+            else if( traversedManyAssociation != null )
+            {
+                throw new IllegalArgumentException( "Cannot evaluate a ManyAssociation" );
+            }
+            else if( traversedNamedAssociation != null )
+            {
+                throw new IllegalArgumentException( "Cannot evaluate a NamedAssociation" );
+            }
+
+            if( target == null )
+            {
+                return null;
+            }
+
+            CompositeInstance handler = (CompositeInstance) Proxy.getInvocationHandler( target );
+            return handler.state().propertyFor( accessor );
+        }
+        catch( IllegalArgumentException e )
+        {
+            throw e;
+        }
+        catch( Throwable e )
+        {
+            throw new IllegalArgumentException( e );
+        }
+    }
+
+    @Override
+    public String toString()
+    {
+        if( traversedProperty != null )
+        {
+            return traversedProperty.toString() + "." + ( (Member) accessor ).getName();
+        }
+        else if( traversedAssociation != null )
+        {
+            return traversedAssociation.toString() + "." + ( (Member) accessor ).getName();
+        }
+        else
+        {
+            return ( (Member) accessor ).getName();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/query/grammar/PropertyNotNullSpecification.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/query/grammar/PropertyNotNullSpecification.java b/core/api/src/main/java/org/apache/zest/api/query/grammar/PropertyNotNullSpecification.java
new file mode 100644
index 0000000..c140542
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/query/grammar/PropertyNotNullSpecification.java
@@ -0,0 +1,60 @@
+/*
+ * 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.query.grammar;
+
+import org.apache.zest.api.composite.Composite;
+import org.apache.zest.api.property.Property;
+
+/**
+ * Property not null Specification.
+ */
+public class PropertyNotNullSpecification<T>
+    extends ExpressionSpecification
+{
+    private PropertyFunction<T> property;
+
+    public PropertyNotNullSpecification( PropertyFunction<T> property )
+    {
+        this.property = property;
+    }
+
+    public PropertyFunction<T> property()
+    {
+        return property;
+    }
+
+    @Override
+    public boolean satisfiedBy( Composite item )
+    {
+        Property<T> prop = property.map( item );
+
+        if( prop == null )
+        {
+            return false;
+        }
+
+        return prop.get() != null;
+    }
+
+    @Override
+    public String toString()
+    {
+        return property.toString() + "is not null";
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/query/grammar/PropertyNullSpecification.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/query/grammar/PropertyNullSpecification.java b/core/api/src/main/java/org/apache/zest/api/query/grammar/PropertyNullSpecification.java
new file mode 100644
index 0000000..b0acfa7
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/query/grammar/PropertyNullSpecification.java
@@ -0,0 +1,60 @@
+/*
+ * 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.query.grammar;
+
+import org.apache.zest.api.composite.Composite;
+import org.apache.zest.api.property.Property;
+
+/**
+ * Property null Specification.
+ */
+public class PropertyNullSpecification<T>
+    extends ExpressionSpecification
+{
+    private PropertyFunction<T> property;
+
+    public PropertyNullSpecification( PropertyFunction<T> property )
+    {
+        this.property = property;
+    }
+
+    public PropertyFunction<T> property()
+    {
+        return property;
+    }
+
+    @Override
+    public boolean satisfiedBy( Composite item )
+    {
+        Property<T> prop = property.map( item );
+
+        if( prop == null )
+        {
+            return true;
+        }
+
+        return prop.get() == null;
+    }
+
+    @Override
+    public String toString()
+    {
+        return property.toString() + "is null";
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/query/grammar/PropertyReference.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/query/grammar/PropertyReference.java b/core/api/src/main/java/org/apache/zest/api/query/grammar/PropertyReference.java
new file mode 100644
index 0000000..4b30a56
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/query/grammar/PropertyReference.java
@@ -0,0 +1,31 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.zest.api.query.grammar;
+
+import org.apache.zest.api.composite.Composite;
+import org.apache.zest.api.property.Property;
+import org.apache.zest.functional.Function;
+
+/**
+ * Property Reference.
+ */
+public interface PropertyReference
+{
+    <T> Function<Composite, Property<T>> reference();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/query/grammar/QuerySpecification.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/query/grammar/QuerySpecification.java b/core/api/src/main/java/org/apache/zest/api/query/grammar/QuerySpecification.java
new file mode 100644
index 0000000..a0ce311
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/query/grammar/QuerySpecification.java
@@ -0,0 +1,71 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.zest.api.query.grammar;
+
+import org.apache.zest.api.composite.Composite;
+import org.apache.zest.functional.Specification;
+
+/**
+ * This should be used when doing native queries, such as SQL, SPARQL or similar. EntityFinders can choose
+ * what type of query languages they can understand by checking the language property of a QuerySpecification
+ */
+public class QuerySpecification
+    implements Specification<Composite>
+{
+    public static boolean isQueryLanguage( String language, Specification<Composite> specification )
+    {
+        if( !( specification instanceof QuerySpecification ) )
+        {
+            return false;
+        }
+
+        return ( (QuerySpecification) specification ).language().equals( language );
+    }
+
+    private String language;
+    private String query;
+
+    public QuerySpecification( String language, String query )
+    {
+        this.language = language;
+        this.query = query;
+    }
+
+    public String language()
+    {
+        return language;
+    }
+
+    public String query()
+    {
+        return query;
+    }
+
+    @Override
+    public boolean satisfiedBy( Composite item )
+    {
+        return false;
+    }
+
+    @Override
+    public String toString()
+    {
+        return language + ":" + query;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/query/grammar/Variable.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/query/grammar/Variable.java b/core/api/src/main/java/org/apache/zest/api/query/grammar/Variable.java
new file mode 100644
index 0000000..0255d52
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/query/grammar/Variable.java
@@ -0,0 +1,43 @@
+/*
+ * 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.query.grammar;
+
+/**
+ * Query Variable name.
+ */
+public class Variable
+{
+    private String name;
+
+    public Variable( String name )
+    {
+        this.name = name;
+    }
+
+    public String variableName()
+    {
+        return name;
+    }
+
+    @Override
+    public String toString()
+    {
+        return name;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/query/grammar/package.html
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/query/grammar/package.html b/core/api/src/main/java/org/apache/zest/api/query/grammar/package.html
new file mode 100644
index 0000000..e0b80f6
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/query/grammar/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>Query Grammar.</h2>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/query/package.html
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/query/package.html b/core/api/src/main/java/org/apache/zest/api/query/package.html
new file mode 100644
index 0000000..27e4455
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/query/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>Query API.</h2>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/Availability.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/Availability.java b/core/api/src/main/java/org/apache/zest/api/service/Availability.java
new file mode 100644
index 0000000..b1b7d25
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/Availability.java
@@ -0,0 +1,34 @@
+/*
+ * 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.service;
+
+/**
+ * Services can implement this interface in order to allow Zest to ask
+ * it whether it is currently available for use or not. This is accessed
+ * by clients through the ServiceReference of the service. Services that do not
+ * implement this are always considered to be available.
+ */
+public interface Availability
+{
+    /**
+     * Implementations should return true if the underlying service is currently available for use.
+     *
+     * Reasons why a service might not be available is either if it has been configured not to be (see
+     * the Enabled interface), or if an underlying resource is currently unavailable.
+     *
+     * @return true if the service is available, false otherwise.
+     */
+    boolean isAvailable();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/DuplicateServiceIdentityException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/DuplicateServiceIdentityException.java b/core/api/src/main/java/org/apache/zest/api/service/DuplicateServiceIdentityException.java
new file mode 100644
index 0000000..54b663b
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/DuplicateServiceIdentityException.java
@@ -0,0 +1,29 @@
+/*
+ * 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.service;
+
+import org.apache.zest.api.common.InvalidApplicationException;
+
+/**
+ * Thrown when a duplicate service identity is detected.
+ */
+public class DuplicateServiceIdentityException
+    extends InvalidApplicationException
+{
+    public DuplicateServiceIdentityException( String string )
+    {
+        super( string );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/IdentityDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/IdentityDescriptor.java b/core/api/src/main/java/org/apache/zest/api/service/IdentityDescriptor.java
new file mode 100644
index 0000000..5539a60
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/IdentityDescriptor.java
@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.zest.api.service;
+
+/**
+ * Identity Descriptor.
+ */
+public interface IdentityDescriptor
+{
+    String identity();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/ImportedServiceDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/ImportedServiceDescriptor.java b/core/api/src/main/java/org/apache/zest/api/service/ImportedServiceDescriptor.java
new file mode 100644
index 0000000..95270da
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/ImportedServiceDescriptor.java
@@ -0,0 +1,28 @@
+/*
+ * 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.service;
+
+import org.apache.zest.api.composite.ModelDescriptor;
+
+/**
+ * {@code ServiceDescriptor} provides meta information of a service.
+ */
+public interface ImportedServiceDescriptor
+    extends ModelDescriptor, IdentityDescriptor
+{
+    Class<? extends ServiceImporter> serviceImporter();
+
+    Class<?> type();
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/NoSuchServiceException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/NoSuchServiceException.java b/core/api/src/main/java/org/apache/zest/api/service/NoSuchServiceException.java
new file mode 100644
index 0000000..cee08a3
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/NoSuchServiceException.java
@@ -0,0 +1,30 @@
+/*
+ * 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.service;
+
+import org.apache.zest.api.composite.NoSuchCompositeException;
+
+/**
+ * Thrown when no visible service of the requested type is found.
+ */
+public class NoSuchServiceException extends NoSuchCompositeException
+{
+    public NoSuchServiceException( String typeName, String moduleName )
+    {
+        super( "ServiceComposite", typeName, moduleName );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/ServiceActivation.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/ServiceActivation.java b/core/api/src/main/java/org/apache/zest/api/service/ServiceActivation.java
new file mode 100644
index 0000000..0ef3260
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/ServiceActivation.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2012 Paul Merlin.
+ *
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zest.api.service;
+
+import org.apache.zest.api.activation.Activators;
+
+/**
+ * Convenience interface for simple Service Activation.
+ *
+ * Let your ServiceComposite extends ServiceActivation and implement it in one of its Mixins.
+ * A corresponding Activator is automatically registered.
+ */
+@Activators( ServiceActivation.ServiceActivator.class )
+public interface ServiceActivation
+{
+
+    /**
+     * Called after ServiceComposite Activation.
+     */
+    void activateService()
+        throws Exception;
+
+    /**
+     * Called before ServiceComposite Passivation.
+     */
+    void passivateService()
+        throws Exception;
+
+    /**
+     * Service Activator.
+     */
+    class ServiceActivator
+        extends ServiceActivatorAdapter<ServiceActivation>
+    {
+
+        @Override
+        public void afterActivation( ServiceReference<ServiceActivation> activated )
+            throws Exception
+        {
+            activated.get().activateService();
+        }
+
+        @Override
+        public void beforePassivation( ServiceReference<ServiceActivation> passivating )
+            throws Exception
+        {
+            passivating.get().passivateService();
+        }
+
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/ServiceActivatorAdapter.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/ServiceActivatorAdapter.java b/core/api/src/main/java/org/apache/zest/api/service/ServiceActivatorAdapter.java
new file mode 100644
index 0000000..a2ee7a7
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/ServiceActivatorAdapter.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2014 Paul Merlin.
+ *
+ * Licensed  under the  Apache License,  Version 2.0  (the "License");
+ * you may not use  this file  except in  compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed  under the  License is distributed on an "AS IS" BASIS,
+ * WITHOUT  WARRANTIES OR CONDITIONS  OF ANY KIND, either  express  or
+ * implied.
+ *
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zest.api.service;
+
+import org.apache.zest.api.activation.Activator;
+
+/**
+ * Adapter for Service Activator.
+ *
+ * @param <ServiceType> Type of the service.
+ */
+public class ServiceActivatorAdapter<ServiceType>
+    implements Activator<ServiceReference<ServiceType>>
+{
+    /**
+     * Called before Service activation.
+     * @param activating Activating Service
+     */
+    @Override
+    public void beforeActivation( ServiceReference<ServiceType> activating )
+        throws Exception
+    {
+    }
+
+    /**
+     * Called after Service activation.
+     * @param activated Activated Service
+     */
+    @Override
+    public void afterActivation( ServiceReference<ServiceType> activated )
+        throws Exception
+    {
+    }
+
+    /**
+     * Called before Service passivation.
+     * @param passivating Passivating Service
+     */
+    @Override
+    public void beforePassivation( ServiceReference<ServiceType> passivating )
+        throws Exception
+    {
+    }
+
+    /**
+     * Called after Service passivation.
+     * @param passivated Passivated Service
+     */
+    @Override
+    public void afterPassivation( ServiceReference<ServiceType> passivated )
+        throws Exception
+    {
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/ServiceComposite.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/ServiceComposite.java b/core/api/src/main/java/org/apache/zest/api/service/ServiceComposite.java
new file mode 100644
index 0000000..6a40250
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/ServiceComposite.java
@@ -0,0 +1,27 @@
+/*
+ * 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.service;
+
+import org.apache.zest.api.composite.Composite;
+import org.apache.zest.api.entity.Identity;
+
+/**
+ * All Composites being used to implement Services
+ * must extend this interface.
+ */
+public interface ServiceComposite
+    extends Identity, Composite
+{
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/ServiceDescriptor.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/ServiceDescriptor.java b/core/api/src/main/java/org/apache/zest/api/service/ServiceDescriptor.java
new file mode 100644
index 0000000..98cfd89
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/ServiceDescriptor.java
@@ -0,0 +1,29 @@
+/*
+ * 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.service;
+
+import org.apache.zest.api.composite.CompositeDescriptor;
+import org.apache.zest.api.composite.StatefulCompositeDescriptor;
+
+/**
+ * {@code ServiceDescriptor} provides meta informations of a service.
+ */
+public interface ServiceDescriptor
+    extends CompositeDescriptor, IdentityDescriptor, StatefulCompositeDescriptor
+{
+    boolean isInstantiateOnStartup();
+
+    <T> Class<T> configurationType();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/ServiceFinder.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/ServiceFinder.java b/core/api/src/main/java/org/apache/zest/api/service/ServiceFinder.java
new file mode 100644
index 0000000..5f9be65
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/ServiceFinder.java
@@ -0,0 +1,87 @@
+/*
+ * 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.service;
+
+import java.lang.reflect.Type;
+
+/**
+ * Interface used to query for ServiceReferences.
+ * <p>
+ * Each ServiceFinder is
+ * obtained from a specific Module, and the lookup rules are the following:
+ * </p>
+ * <ol>
+ * <li>First look in the same Module as the ServiceFinder</li>
+ * <li>Then look in the same Layer as the ServiceFinder. Any Services declared
+ * with Visibility Layer and Application should be included</li>
+ * <li>Then look in the used Layers. Any Services declared with Visibility Application
+ * should be included</li>
+ * </ol>
+ * <p>
+ * Both native Zest services and imported services are considered, with preference to native services.
+ * </p>
+ */
+public interface ServiceFinder
+{
+    /**
+     * Find a ServiceReference that implements the given type.
+     *
+     * @param serviceType the type that the Service must implement
+     *
+     * @return a ServiceReference if one is found
+     *
+     * @throws NoSuchServiceException if no service of serviceType is found
+     */
+    <T> ServiceReference<T> findService( Class<T> serviceType )
+        throws NoSuchServiceException;
+
+    /**
+     * Find a ServiceReference that implements the given type.
+     *
+     * @param serviceType the type that the Service must implement
+     *
+     * @return a ServiceReference if one is found
+     *
+     * @throws NoSuchServiceException if no service of serviceType is found
+     */
+    <T> ServiceReference<T> findService( Type serviceType )
+        throws NoSuchServiceException;
+
+    /**
+     * Find ServiceReferences that implements the given type.
+     * <p>
+     * The order of the references is such that Services more local to the querying
+     * Module is earlier in the list.
+     * </p>
+     *
+     * @param serviceType the type that the Services must implement
+     *
+     * @return an iterable of ServiceReferences for the given type. It is empty if none exist
+     */
+    <T> Iterable<ServiceReference<T>> findServices( Class<T> serviceType );
+
+    /**
+     * Find ServiceReferences that implements the given type.
+     * <p>
+     * The order of the references is such that Services more local to the querying
+     * Module is earlier in the list.
+     * </p>
+     *
+     * @param serviceType the type that the Services must implement
+     *
+     * @return an iterable of ServiceReferences for the given type. It is empty if none exist
+     */
+    <T> Iterable<ServiceReference<T>> findServices( Type serviceType );
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/ServiceImporter.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/ServiceImporter.java b/core/api/src/main/java/org/apache/zest/api/service/ServiceImporter.java
new file mode 100644
index 0000000..c6b5bc3
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/ServiceImporter.java
@@ -0,0 +1,42 @@
+/*
+ * 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.service;
+
+/**
+ * Import a service from some external source.
+ */
+public interface ServiceImporter<T>
+{
+    /**
+     * Imports an instance of the service type described in the service descriptor.
+     *
+     * @param serviceDescriptor The service descriptor.
+     *
+     * @return The imported service instance.
+     *
+     * @throws ServiceImporterException if import failed.
+     */
+    T importService( ImportedServiceDescriptor serviceDescriptor )
+        throws ServiceImporterException;
+
+    /**
+     * Ask if the service is available or not.
+     *
+     * @param instance the instance to be checked
+     *
+     * @return true if the service is available, false if not
+     */
+    boolean isAvailable( T instance );
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/ServiceImporterException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/ServiceImporterException.java b/core/api/src/main/java/org/apache/zest/api/service/ServiceImporterException.java
new file mode 100644
index 0000000..116404b
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/ServiceImporterException.java
@@ -0,0 +1,42 @@
+/*
+ * 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.service;
+
+/**
+ * If a ServiceImporter could not import a service
+ * instance it must throw this exception.
+ */
+public class ServiceImporterException
+    extends RuntimeException
+{
+    public ServiceImporterException()
+    {
+    }
+
+    public ServiceImporterException( String string )
+    {
+        super( string );
+    }
+
+    public ServiceImporterException( String string, Throwable throwable )
+    {
+        super( string, throwable );
+    }
+
+    public ServiceImporterException( Throwable throwable )
+    {
+        super( throwable );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/ServiceReference.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/ServiceReference.java b/core/api/src/main/java/org/apache/zest/api/service/ServiceReference.java
new file mode 100644
index 0000000..dd17618
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/ServiceReference.java
@@ -0,0 +1,47 @@
+/*
+ * 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.service;
+
+import org.apache.zest.api.activation.ActivationEventListenerRegistration;
+import org.apache.zest.api.structure.MetaInfoHolder;
+import org.apache.zest.api.type.HasTypes;
+
+/**
+ * From a ServiceReference you can access and modify metadata about a service.
+ * You can also access the actual service through get(), that can then be invoked.
+ */
+public interface ServiceReference<T>
+    extends HasTypes, ActivationEventListenerRegistration, MetaInfoHolder
+{
+    /**
+     * @return the service's identity
+     */
+    String identity();
+
+    /**
+     * @return the actual service
+     */
+    T get();
+
+    /**
+     * @return TRUE if the service is active, otherwise return FALSE
+     */
+    boolean isActive();
+
+    /**
+     * @return TRUE if the service is available, otherwise return FALSE
+     */
+    boolean isAvailable();
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/ServiceUnavailableException.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/ServiceUnavailableException.java b/core/api/src/main/java/org/apache/zest/api/service/ServiceUnavailableException.java
new file mode 100644
index 0000000..c5ba3fd
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/ServiceUnavailableException.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2008 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.service;
+
+/**
+ * Thrown when no available service is found.
+ */
+public class ServiceUnavailableException
+    extends RuntimeException
+{
+    public ServiceUnavailableException( String message )
+    {
+        super( message );
+    }
+
+    public ServiceUnavailableException( String message, Throwable cause )
+    {
+        super( message, cause );
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/importer/InstanceImporter.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/importer/InstanceImporter.java b/core/api/src/main/java/org/apache/zest/api/service/importer/InstanceImporter.java
new file mode 100644
index 0000000..35e0bd0
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/importer/InstanceImporter.java
@@ -0,0 +1,80 @@
+/*
+ * 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.service.importer;
+
+import org.apache.zest.api.injection.scope.Structure;
+import org.apache.zest.api.service.ImportedServiceDescriptor;
+import org.apache.zest.api.service.ServiceImporter;
+import org.apache.zest.api.service.ServiceImporterException;
+import org.apache.zest.api.structure.Application;
+import org.apache.zest.api.structure.Layer;
+import org.apache.zest.api.structure.MetaInfoHolder;
+import org.apache.zest.api.structure.Module;
+import org.apache.zest.functional.Function;
+import org.apache.zest.functional.Iterables;
+
+import static org.apache.zest.functional.Iterables.filter;
+import static org.apache.zest.functional.Iterables.first;
+import static org.apache.zest.functional.Iterables.map;
+import static org.apache.zest.functional.Specifications.notNull;
+
+/**
+ * Return a predefined service instance that was provided as meta-info. Search for meta-info in the following order:
+ * the service itself, the module of the service, the layer of the service, the whole application.
+ */
+public final class InstanceImporter<T>
+    implements ServiceImporter<T>
+{
+    @Structure
+    private Application application;
+
+    @Structure
+    private Layer layer;
+
+    @Structure
+    private Module module;
+
+    @Override
+    public T importService( final ImportedServiceDescriptor serviceDescriptor )
+        throws ServiceImporterException
+    {
+        T instance = null;
+        Iterable<MetaInfoHolder> holders = Iterables.iterable( serviceDescriptor, module, layer, application );
+        for( final MetaInfoHolder metaInfoHolder : holders )
+        {
+            Function<Class<?>, T> metaFinder = new Function<Class<?>, T>()
+            {
+                @Override
+                @SuppressWarnings( "unchecked" )
+                public T map( Class<?> type )
+                {
+                    return (T) metaInfoHolder.metaInfo( type );
+                }
+            };
+            instance = first( filter( notNull(), map( metaFinder, serviceDescriptor.types() ) ) );
+            if( instance != null )
+            {
+                break;
+            }
+        }
+        return instance;
+    }
+
+    @Override
+    public boolean isAvailable( T instance )
+    {
+        return true;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/importer/NewObjectImporter.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/importer/NewObjectImporter.java b/core/api/src/main/java/org/apache/zest/api/service/importer/NewObjectImporter.java
new file mode 100644
index 0000000..55df2c0
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/importer/NewObjectImporter.java
@@ -0,0 +1,46 @@
+/*
+ * 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.service.importer;
+
+import org.apache.zest.api.injection.scope.Structure;
+import org.apache.zest.api.object.ObjectFactory;
+import org.apache.zest.api.service.ImportedServiceDescriptor;
+import org.apache.zest.api.service.ServiceImporter;
+import org.apache.zest.api.service.ServiceImporterException;
+import org.apache.zest.functional.Iterables;
+
+/**
+ * Import Services using a new registered Object instance.
+ */
+public final class NewObjectImporter<T>
+    implements ServiceImporter<T>
+{
+    @Structure
+    private ObjectFactory obf;
+
+    @Override
+    @SuppressWarnings( "unchecked" )
+    public T importService( ImportedServiceDescriptor serviceDescriptor )
+        throws ServiceImporterException
+    {
+        return obf.newObject( (Class<T>) Iterables.first( serviceDescriptor.types() ) );
+    }
+
+    @Override
+    public boolean isAvailable( T instance )
+    {
+        return true;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/importer/ServiceInstanceImporter.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/importer/ServiceInstanceImporter.java b/core/api/src/main/java/org/apache/zest/api/service/importer/ServiceInstanceImporter.java
new file mode 100644
index 0000000..5a497e6
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/importer/ServiceInstanceImporter.java
@@ -0,0 +1,80 @@
+/*
+ * 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.service.importer;
+
+import org.apache.zest.api.injection.scope.Structure;
+import org.apache.zest.api.service.ImportedServiceDescriptor;
+import org.apache.zest.api.service.ServiceFinder;
+import org.apache.zest.api.service.ServiceImporter;
+import org.apache.zest.api.service.ServiceImporterException;
+import org.apache.zest.api.service.ServiceReference;
+
+/**
+ * Use a registered service that implements ServiceImporter to do the actual
+ * import. The service id of the service that this importer should delegate to must
+ * be set as meta-info on this service. Example:
+ * <pre><code>
+ * module.services(MyServiceImporterService.class).identifiedBy("someid");
+ * module.importedServices(OtherService.class).importedBy(ServiceInstanceImporter.class).setMetaInfo("someid");
+ * </code></pre>
+ */
+public class ServiceInstanceImporter<T>
+    implements ServiceImporter<T>
+{
+    @Structure
+    ServiceFinder finder;
+
+    ServiceImporter<T> service;
+
+    String serviceId;
+
+    @Override
+    public T importService( ImportedServiceDescriptor importedServiceDescriptor )
+        throws ServiceImporterException
+    {
+        serviceId = importedServiceDescriptor.metaInfo( String.class );
+
+        return serviceImporter().importService( importedServiceDescriptor );
+    }
+
+    @Override
+    public boolean isAvailable( T instance )
+    {
+        return serviceImporter().isAvailable( instance );
+    }
+
+    @SuppressWarnings( {"raw", "unchecked"} )
+    private ServiceImporter<T> serviceImporter()
+    {
+        if( service == null )
+        {
+            for( ServiceReference<ServiceImporter> reference : finder.<ServiceImporter>findServices( ServiceImporter.class ) )
+            {
+                if( reference.identity().equals( serviceId ) )
+                {
+                    service = reference.get();
+                    break;
+                }
+            }
+        }
+
+        if( service == null )
+        {
+            throw new ServiceImporterException( "No service importer with id '" + serviceId + "' was found" );
+        }
+
+        return service;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/importer/ServiceSelectorImporter.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/importer/ServiceSelectorImporter.java b/core/api/src/main/java/org/apache/zest/api/service/importer/ServiceSelectorImporter.java
new file mode 100644
index 0000000..c1ced8c
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/importer/ServiceSelectorImporter.java
@@ -0,0 +1,78 @@
+/*
+ * 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.service.importer;
+
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.zest.api.injection.scope.Structure;
+import org.apache.zest.api.service.Availability;
+import org.apache.zest.api.service.ImportedServiceDescriptor;
+import org.apache.zest.api.service.ServiceFinder;
+import org.apache.zest.api.service.ServiceImporter;
+import org.apache.zest.api.service.ServiceImporterException;
+import org.apache.zest.api.service.ServiceReference;
+import org.apache.zest.api.service.qualifier.ServiceQualifier;
+import org.apache.zest.functional.Iterables;
+import org.apache.zest.functional.Specification;
+
+/**
+ * If several services are available with a given type, and you want to constrain
+ * the current module to use a specific one, then use this importer. Specify a
+ * Specification&lt;ServiceReference&lt;T&gt;&gt; criteria as meta-info for the service, which will be applied
+ * to the list of available services, and the first match will be chosen.
+ *
+ * This importer will avoid selecting itself, as could be possible if the ServiceQualifier.first()
+ * filter is used.
+ */
+public final class ServiceSelectorImporter<T>
+    implements ServiceImporter<T>
+{
+    @Structure
+    private ServiceFinder locator;
+
+    @Override
+    @SuppressWarnings( { "raw", "unchecked" } )
+    public T importService( ImportedServiceDescriptor serviceDescriptor )
+        throws ServiceImporterException
+    {
+        Specification<ServiceReference<?>> selector = serviceDescriptor.metaInfo( Specification.class );
+        Class serviceType = Iterables.first( serviceDescriptor.types() );
+        Iterable<ServiceReference<T>> services = locator.findServices( serviceType );
+        List<ServiceReference<T>> filteredServices = new ArrayList<>();
+        for( ServiceReference<T> service : services )
+        {
+            Specification selector1 = service.metaInfo( Specification.class );
+            if( selector1 != null && selector1 == selector )
+            {
+                continue;
+            }
+
+            filteredServices.add( service );
+        }
+        T service = ServiceQualifier.firstService( selector, filteredServices );
+        if( service == null )
+        {
+            throw new ServiceImporterException( "Could not find any service to import that matches the given specification for " + serviceDescriptor
+                .identity() );
+        }
+        return service;
+    }
+
+    @Override
+    public boolean isAvailable( T instance )
+    {
+        return !( instance instanceof Availability ) || ( (Availability) instance ).isAvailable();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/importer/package.html
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/importer/package.html b/core/api/src/main/java/org/apache/zest/api/service/importer/package.html
new file mode 100644
index 0000000..d960b3d
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/importer/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>Service Importers.</h2>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/package.html
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/package.html b/core/api/src/main/java/org/apache/zest/api/service/package.html
new file mode 100644
index 0000000..587937c
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/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>Service API.</h2>
+    </body>
+</html>

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/qualifier/Active.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/qualifier/Active.java b/core/api/src/main/java/org/apache/zest/api/service/qualifier/Active.java
new file mode 100644
index 0000000..c961eb9
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/qualifier/Active.java
@@ -0,0 +1,51 @@
+/*
+ * 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.service.qualifier;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import org.apache.zest.api.service.ServiceReference;
+import org.apache.zest.functional.Specification;
+
+/**
+ * Filter services based on whether they are active or not.
+ * <p>
+ * At an injection point you can do this:
+ * </p>
+ * <pre><code>
+ * &#64;Service &#64;Active MyService service;
+ * </code></pre>
+ * <p>
+ * to get only a service that is currently active.
+ * </p>
+ */
+@Retention( RetentionPolicy.RUNTIME )
+@Qualifier( Active.ActiveQualifier.class )
+public @interface Active
+{
+    /**
+     * Active Annotation Qualifier.
+     * See {@link Active}.
+     */
+    public final class ActiveQualifier
+        implements AnnotationQualifier<Active>
+    {
+        @Override
+        public <T> Specification<ServiceReference<?>> qualifier( Active active )
+        {
+            return ServiceQualifier.whereActive();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/qualifier/AnnotationQualifier.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/qualifier/AnnotationQualifier.java b/core/api/src/main/java/org/apache/zest/api/service/qualifier/AnnotationQualifier.java
new file mode 100644
index 0000000..38e45c5
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/qualifier/AnnotationQualifier.java
@@ -0,0 +1,27 @@
+/*
+ * 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.service.qualifier;
+
+import java.lang.annotation.Annotation;
+import org.apache.zest.api.service.ServiceReference;
+import org.apache.zest.functional.Specification;
+
+/**
+ * Constructs a Specification for a given qualifier annotation
+ */
+public interface AnnotationQualifier<QUALIFIER extends Annotation>
+{
+    public <T> Specification<ServiceReference<?>> qualifier( QUALIFIER qualifier );
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/qualifier/Available.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/qualifier/Available.java b/core/api/src/main/java/org/apache/zest/api/service/qualifier/Available.java
new file mode 100644
index 0000000..6638061
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/qualifier/Available.java
@@ -0,0 +1,49 @@
+/*
+ * 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.service.qualifier;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import org.apache.zest.api.service.ServiceReference;
+import org.apache.zest.functional.Specification;
+
+/**
+ * Filter services based on whether they are available or not.
+ *
+ * At an injection point you can do this:
+ *
+ * <pre><code>
+ * &#64;Service &#64;Available MyService service;
+ * </code></pre>
+ * to get only a service that is currently available.
+ */
+@Retention( RetentionPolicy.RUNTIME )
+@Qualifier( Available.AvailableQualifier.class )
+public @interface Available
+{
+    /**
+     * Available Annotation Qualifier.
+     * See {@link Available}.
+     */
+    public final class AvailableQualifier
+        implements AnnotationQualifier<Available>
+    {
+        @Override
+        public <T> Specification<ServiceReference<?>> qualifier( Available active )
+        {
+            return ServiceQualifier.whereAvailable();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/qualifier/HasMetaInfo.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/qualifier/HasMetaInfo.java b/core/api/src/main/java/org/apache/zest/api/service/qualifier/HasMetaInfo.java
new file mode 100644
index 0000000..887e5a7
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/qualifier/HasMetaInfo.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2009, 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.service.qualifier;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import org.apache.zest.api.service.ServiceReference;
+import org.apache.zest.functional.Specification;
+
+/**
+ * Filter services based on Meta Info being declared on the Service.
+ * <p>
+ * Meta Info of any type can be set on the service during assembly, e.g.;
+ * </p>
+ * <pre><code>
+ * module.addService( MyService.class ).setMetaInfo( new MyCustomInfo(someData) );
+ * </code></pre>
+ * <p>
+ * and then at an injection point you can do this:
+ * </p>
+ * <pre><code>
+ * &#64;Service &#64;HasMetaInfo(MyCustomInfo.class) MyService service;
+ * </code></pre>
+ * <p>
+ * to get only a service that has a MyCustomInfo instance set as meta info.
+ * </p>
+ */
+@Retention( RetentionPolicy.RUNTIME )
+@Qualifier( HasMetaInfo.HasMetaInfoQualifier.class )
+@Documented
+public @interface HasMetaInfo
+{
+    /**
+     * The Class(es) needed to have been defined in the Service meta info for a qualifier to evaluate true.
+     *
+     * @return One or more classes that should be defined in the service's meta info for the service to be considered
+     *         qualified. If more than one class is defined, the {@code anded()} parameter will define if they must be
+     *         AND'ed or OR'ed together.
+     */
+    Class[] value();
+
+    /**
+     * True if the Classes defined in the value() field should be AND'ed instead of OR'ed.
+     *
+     * @return If true, all the Class types defined in {@code value()} must be defined for the service for it to be
+     *         qualified. If false, if any of the Class types defined in {@code value()} is defined for the service
+     *         the service is qualified.
+     */
+    boolean anded() default false;
+
+    /**
+     * HasMetaInfo Annotation Qualifier.
+     * See {@link HasMetaInfo}.
+     */
+    public static class HasMetaInfoQualifier
+        implements AnnotationQualifier<HasMetaInfo>
+    {
+        @Override
+        public <T> Specification<ServiceReference<?>> qualifier( final HasMetaInfo hasMetaInfo )
+        {
+            return new Specification<ServiceReference<?>>()
+            {
+                @Override
+                @SuppressWarnings( {"raw", "unchecked"} )
+                public boolean satisfiedBy( ServiceReference<?> service )
+                {
+                    for( Class metaInfoType : hasMetaInfo.value() )
+                    {
+                        Object metaInfo = service.metaInfo( metaInfoType );
+                        if( hasMetaInfo.anded() )
+                        {
+                            if( metaInfo == null )
+                            {
+                                return false;
+                            }
+                        }
+                        else
+                        {
+                            if( metaInfo != null )
+                            {
+                                return true;
+                            }
+                        }
+                    }
+                    return false;
+                }
+            };
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zest-java/blob/061ddaa0/core/api/src/main/java/org/apache/zest/api/service/qualifier/IdentifiedBy.java
----------------------------------------------------------------------
diff --git a/core/api/src/main/java/org/apache/zest/api/service/qualifier/IdentifiedBy.java b/core/api/src/main/java/org/apache/zest/api/service/qualifier/IdentifiedBy.java
new file mode 100644
index 0000000..6f18f56
--- /dev/null
+++ b/core/api/src/main/java/org/apache/zest/api/service/qualifier/IdentifiedBy.java
@@ -0,0 +1,53 @@
+/*
+ * 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.service.qualifier;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import org.apache.zest.api.service.ServiceReference;
+import org.apache.zest.functional.Specification;
+
+/**
+ * Filter services based on identity. Identity can be set during assembly, like so:
+ * <pre><code>
+ * module.addService(MyService.class).identifiedBy("myservice1");
+ * </code></pre>
+ *
+ * and then at an injection point you can do this:
+ * <pre><code>
+ * &#64;Service @IdentifiedBy("myservice1") MyService service;
+ * </code></pre>
+ * to get only a service identified "myservice1".
+ */
+@Retention( RetentionPolicy.RUNTIME )
+@Qualifier( IdentifiedBy.IdentifiedByQualifier.class )
+public @interface IdentifiedBy
+{
+    public abstract String value();
+
+    /**
+     * IdentifiedBy Annotation Qualifier.
+     * See {@link IdentifiedBy}.
+     */
+    public final class IdentifiedByQualifier
+        implements AnnotationQualifier<IdentifiedBy>
+    {
+        @Override
+        public <T> Specification<ServiceReference<?>> qualifier( IdentifiedBy identifiedBy )
+        {
+            return ServiceQualifier.withId( identifiedBy.value() );
+        }
+    }
+}


Mime
View raw message