You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by gp...@apache.org on 2011/07/21 00:44:51 UTC

svn commit: r1148960 - in /myfaces/extensions/cdi/trunk/core: api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/projectstage/ api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/provider/ api/src/main/java/org/apache/myfaces/extensi...

Author: gpetracek
Date: Wed Jul 20 22:44:46 2011
New Revision: 1148960

URL: http://svn.apache.org/viewvc?rev=1148960&view=rev
Log:
EXTCDI-198 and EXTCDI-209 (first draft) including a refactoring and unit tests

Added:
    myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/provider/ServiceProvider.java
    myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/provider/ServiceProviderContext.java
    myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/tools/AbstractPropertyExpressionInterpreter.java
    myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/tools/SimpleOperationEnum.java
      - copied, changed from r1146737, myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/activation/SimpleOperationEnum.java
    myfaces/extensions/cdi/trunk/core/api/src/test/java/org/apache/myfaces/extensions/cdi/core/custom/
    myfaces/extensions/cdi/trunk/core/api/src/test/java/org/apache/myfaces/extensions/cdi/core/custom/provider/
    myfaces/extensions/cdi/trunk/core/api/src/test/java/org/apache/myfaces/extensions/cdi/core/custom/provider/ServiceProvider.java
    myfaces/extensions/cdi/trunk/core/api/src/test/java/org/apache/myfaces/extensions/cdi/core/custom/provider/ServiceProviderContext.java
    myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/provider/
    myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/provider/ServiceProvider.java
    myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/provider/ServiceProviderContext.java
    myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/provider/SystemPropertyExpressionInterpreter.java
    myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/util/ActivationUtils.java
    myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/custom/
    myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/custom/provider/
    myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/custom/provider/ServiceProvider.java
    myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/test/impl/serviceloader/
    myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/test/impl/serviceloader/ServiceProviderTest.java
Removed:
    myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/activation/SimpleOperationEnum.java
Modified:
    myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/projectstage/ProjectStage.java
    myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/startup/CodiStartupBroadcaster.java
    myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/tools/InvocationOrderComparator.java
    myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/activation/ActivationExtension.java
    myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/activation/PropertyExpressionInterpreter.java
    myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/config/AbstractConfiguredValueResolver.java
    myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/config/ServiceLoaderResolver.java
    myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/util/ConfiguredArtifactUtils.java
    myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/test/impl/config/TestConfiguredValueResolver.java
    myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/test/impl/config/TestImpl.java
    myfaces/extensions/cdi/trunk/core/impl/src/test/resources/META-INF/services/org.apache.myfaces.extensions.cdi.core.test.impl.config.TestInterface

Modified: myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/projectstage/ProjectStage.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/projectstage/ProjectStage.java?rev=1148960&r1=1148959&r2=1148960&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/projectstage/ProjectStage.java (original)
+++ myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/projectstage/ProjectStage.java Wed Jul 20 22:44:46 2011
@@ -18,11 +18,13 @@
  */
 package org.apache.myfaces.extensions.cdi.core.api.projectstage;
 
+import org.apache.myfaces.extensions.cdi.core.api.provider.ServiceProvider;
+
 import javax.enterprise.inject.Typed;
 import java.io.Serializable;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
-import java.util.ServiceLoader;
 import java.util.logging.Logger;
 
 /**
@@ -124,8 +126,8 @@ public abstract class ProjectStage imple
      */
     static
     {
-        ServiceLoader<ProjectStageHolder> projectStageHolderLoader = ServiceLoader.load(ProjectStageHolder.class);
-        for (ProjectStageHolder projectStageHolder : projectStageHolderLoader)
+        List<ProjectStageHolder> projectStageHolderList = ServiceProvider.loadServices(ProjectStageHolder.class);
+        for (ProjectStageHolder projectStageHolder : projectStageHolderList)
         {
             LOG.fine("registering ProjectStages from ProjectStageHolder " + projectStageHolder.getClass().getName());
         }

Added: myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/provider/ServiceProvider.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/provider/ServiceProvider.java?rev=1148960&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/provider/ServiceProvider.java (added)
+++ myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/provider/ServiceProvider.java Wed Jul 20 22:44:46 2011
@@ -0,0 +1,134 @@
+/*
+ * 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.myfaces.extensions.cdi.core.api.provider;
+
+import org.apache.myfaces.extensions.cdi.core.api.util.ClassUtils;
+
+import java.lang.reflect.Constructor;
+import java.util.List;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * Replacement for the service-loader to support java 5 and to provide additional features like
+ * sorting and a basic version of {@link org.apache.myfaces.extensions.cdi.core.api.activation.ExpressionActivated}
+ * and injection as soon as it is available and demo.MyClass:optional
+ *
+ * @author Gerhard Petracek
+ */
+public abstract class ServiceProvider<T>
+{
+    protected static final String SERVICE_CONFIG = "META-INF/services/";
+    protected static final String FILE_ENCODING = "UTF-8";
+
+    protected Class<T> serviceType;
+    protected ServiceProviderContext serviceProviderContext;
+
+    private static final String CUSTOM_SERVICE_PROVIDER_NAME =
+            ServiceProvider.class.getName().replace(".api.", ".custom.");
+
+    private static final String DEFAULT_SERVICE_PROVIDER_NAME =
+            ServiceProvider.class.getName().replace(".api.", ".impl.");
+
+    private static final String CUSTOM_SERVICE_PROVIDER_CONTEXT_NAME =
+            ServiceProviderContext.class.getName().replace(".api.", ".custom.");
+
+    private static final String DEFAULT_SERVICE_PROVIDER_CONTEXT_NAME =
+            ServiceProviderContext.class.getName().replace(".api.", ".impl.");
+
+    protected static final Class<? extends ServiceProvider> SERVICE_PROVIDER_CLASS;
+
+    protected static final Class<? extends ServiceProviderContext> SERVICE_PROVIDER_CONTEXT_CLASS;
+
+    static
+    {
+        Class serviceProviderClass = ClassUtils.tryToLoadClassForName(CUSTOM_SERVICE_PROVIDER_NAME);
+
+        if(serviceProviderClass == null)
+        {
+            serviceProviderClass = ClassUtils.tryToLoadClassForName(DEFAULT_SERVICE_PROVIDER_NAME);
+        }
+
+        //TODO add null check
+        SERVICE_PROVIDER_CLASS = serviceProviderClass;
+
+        Class serviceProviderContextClass = ClassUtils.tryToLoadClassForName(CUSTOM_SERVICE_PROVIDER_CONTEXT_NAME);
+
+        if(serviceProviderContextClass == null)
+        {
+            serviceProviderContextClass = ClassUtils.tryToLoadClassForName(DEFAULT_SERVICE_PROVIDER_CONTEXT_NAME);
+        }
+
+        //TODO add null check
+        SERVICE_PROVIDER_CONTEXT_CLASS = serviceProviderContextClass;
+    }
+
+    public static <S> List<S> loadServices(Class<S> serviceType)
+    {
+        ServiceProviderContext<S> serviceProviderContext =
+                ClassUtils.tryToInstantiateClass(SERVICE_PROVIDER_CONTEXT_CLASS);
+
+        return loadServices(serviceType, serviceProviderContext);
+    }
+
+    public static <S> List<S> loadServices(Class<S> serviceType, ServiceProviderContext<S> serviceProviderContext)
+    {
+        //no fallback - would be possible via an add-on and a custom ServiceProvider
+        ServiceProvider<S> serviceProvider = getServiceProvider(serviceType, serviceProviderContext);
+
+        return serviceProvider.loadServiceImplementations();
+    }
+
+    private static <S> ServiceProvider<S> getServiceProvider(
+            Class<S> serviceType, ServiceProviderContext serviceProviderContext)
+    {
+        try
+        {
+            Constructor constructor =
+                    SERVICE_PROVIDER_CLASS.getDeclaredConstructor(Class.class, ServiceProviderContext.class);
+
+            constructor.setAccessible(true);
+
+            ServiceProvider<S> customServiceProvider =
+                    (ServiceProvider<S>) constructor.newInstance(serviceType, serviceProviderContext);
+
+            return customServiceProvider;
+        }
+        catch (Exception e)
+        {
+            Logger logger = Logger.getLogger(SERVICE_PROVIDER_CLASS.getName());
+
+            if(logger.isLoggable(Level.WARNING))
+            {
+                logger.log(Level.WARNING, "Can't instantiate " + SERVICE_PROVIDER_CLASS.getName(), e);
+            }
+        }
+
+        //TODO
+        return null;
+    }
+
+    protected ServiceProvider(Class<T> serviceType, ServiceProviderContext serviceProviderContext)
+    {
+        this.serviceType = serviceType;
+        this.serviceProviderContext = serviceProviderContext;
+    }
+
+    protected abstract List<T> loadServiceImplementations();
+}

Added: myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/provider/ServiceProviderContext.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/provider/ServiceProviderContext.java?rev=1148960&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/provider/ServiceProviderContext.java (added)
+++ myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/provider/ServiceProviderContext.java Wed Jul 20 22:44:46 2011
@@ -0,0 +1,36 @@
+/*
+ * 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.myfaces.extensions.cdi.core.api.provider;
+
+import java.util.List;
+
+/**
+ * @author Gerhard Petracek
+ */
+//TODO
+public abstract class ServiceProviderContext<T>
+{
+    public abstract ClassLoader getClassLoader();
+
+    public abstract T postConstruct(T instance, boolean containerBootstrapped);
+
+    public abstract boolean filterService(Class<T> serviceClass);
+
+    public abstract void preInstallServices(List<Class<?>> foundServiceClasses);
+}

Modified: myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/startup/CodiStartupBroadcaster.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/startup/CodiStartupBroadcaster.java?rev=1148960&r1=1148959&r2=1148960&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/startup/CodiStartupBroadcaster.java (original)
+++ myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/startup/CodiStartupBroadcaster.java Wed Jul 20 22:44:46 2011
@@ -18,6 +18,8 @@
  */
 package org.apache.myfaces.extensions.cdi.core.api.startup;
 
+import org.apache.myfaces.extensions.cdi.core.api.provider.ServiceProvider;
+import org.apache.myfaces.extensions.cdi.core.api.provider.ServiceProviderContext;
 import org.apache.myfaces.extensions.cdi.core.api.startup.event.StartupEventBroadcaster;
 import org.apache.myfaces.extensions.cdi.core.api.util.ClassUtils;
 import org.apache.myfaces.extensions.cdi.core.api.tools.InvocationOrderComparator;
@@ -27,7 +29,6 @@ import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
-import java.util.ServiceLoader;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
 import java.io.ObjectInputStream;
@@ -66,7 +67,7 @@ public abstract class CodiStartupBroadca
         }
     }
 
-    private static synchronized void invokeStartupEventBroadcaster(ClassLoader classLoader)
+    private static synchronized void invokeStartupEventBroadcaster(final ClassLoader classLoader)
     {
         // switch into paranoia mode
         if (initialized.containsKey(classLoader))
@@ -74,8 +75,36 @@ public abstract class CodiStartupBroadca
             return;
         }
 
-        ServiceLoader<StartupEventBroadcaster> eventBroadcasterServiceLoader =
-                ServiceLoader.load(StartupEventBroadcaster.class, classLoader);
+        List<StartupEventBroadcaster> startupEventBroadcasterList =
+                ServiceProvider.loadServices(StartupEventBroadcaster.class,
+                        new ServiceProviderContext<StartupEventBroadcaster>() {
+                    @Override
+                    public ClassLoader getClassLoader()
+                    {
+                        return classLoader;
+                    }
+
+                    @Override
+                    public StartupEventBroadcaster postConstruct(
+                            StartupEventBroadcaster instance, boolean containerBootstrapped)
+                    {
+                        //do nothing
+                        return instance;
+                    }
+
+                    @Override
+                    public boolean filterService(Class<StartupEventBroadcaster> serviceClass)
+                    {
+                        //do nothing
+                        return false;
+                    }
+
+                    @Override
+                    public void preInstallServices(List<Class<?>> foundServiceClasses)
+                    {
+                        //do nothing
+                    }
+                });
 
         List<Class<? extends StartupEventBroadcaster>> filter = broadcasterFilter.get(classLoader);
         if (filter == null)
@@ -86,7 +115,7 @@ public abstract class CodiStartupBroadca
 
         List<StartupEventBroadcaster> broadcasters = new ArrayList<StartupEventBroadcaster>();
 
-        for (StartupEventBroadcaster startupEventBroadcaster : eventBroadcasterServiceLoader)
+        for (StartupEventBroadcaster startupEventBroadcaster : startupEventBroadcasterList)
         {
             if (!filter.contains(startupEventBroadcaster.getClass()))
             {

Added: myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/tools/AbstractPropertyExpressionInterpreter.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/tools/AbstractPropertyExpressionInterpreter.java?rev=1148960&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/tools/AbstractPropertyExpressionInterpreter.java (added)
+++ myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/tools/AbstractPropertyExpressionInterpreter.java Wed Jul 20 22:44:46 2011
@@ -0,0 +1,109 @@
+/*
+ * 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.myfaces.extensions.cdi.core.api.tools;
+
+import org.apache.myfaces.extensions.cdi.core.api.activation.ExpressionActivated;
+import org.apache.myfaces.extensions.cdi.core.api.interpreter.ExpressionInterpreter;
+
+import javax.enterprise.inject.Typed;
+
+/**
+ * @author Gerhard Petracek
+ */
+@Typed()
+public abstract class AbstractPropertyExpressionInterpreter implements ExpressionInterpreter<String, Boolean>
+{
+    /**
+     * {@inheritDoc}
+     */
+    //TODO
+    public final Boolean evaluate(String expressions)
+    {
+        boolean result = false;
+        String[] foundExpressions = expressions.split(";");
+        String configFileName = null;
+
+        SimpleOperationEnum operation;
+        for(String expression : foundExpressions)
+        {
+            result = false;
+            if(expression.contains(SimpleOperationEnum.IS.getValue()))
+            {
+                operation = SimpleOperationEnum.IS;
+            }
+            else if(expression.contains(SimpleOperationEnum.NOT.getValue()))
+            {
+                operation = SimpleOperationEnum.NOT;
+            }
+            else if(expression.startsWith("configName:"))
+            {
+                configFileName = expression.split(":")[1];
+                //TODO refactor it - current impl. ensures backward compatibility (see PropertyFileResolver)
+                configFileName = configFileName.replace(".", "@");
+                continue;
+            }
+            else
+            {
+                throw new IllegalStateException("expression: " + expression + " isn't supported by " +
+                        ExpressionActivated.class.getName() +
+                        " supported operations: " + SimpleOperationEnum.getOperations() + "separator: ';'");
+            }
+
+            String[] keyValue = expression.split(operation.getValue());
+
+            String configuredValue = getConfiguredValue(keyValue[0]);
+
+            configuredValue = configuredValue.trim();
+
+            if("".equals(configuredValue))
+            {
+                //TODO refactor it - current impl. ensures backward compatibility (see PropertyFileResolver)
+                String internalKey = keyValue[0] + "_";
+
+                configuredValue = getConfiguredValue(configFileName + "." + internalKey);
+                configuredValue = configuredValue.trim();
+            }
+
+            if(!"*".equals(keyValue[1]) && "".equals(configuredValue))
+            {
+                continue;
+            }
+
+            if("*".equals(keyValue[1]) && !"".equals(configuredValue))
+            {
+                result = true;
+                continue;
+            }
+
+            if(SimpleOperationEnum.IS.equals(operation) && !keyValue[1].equalsIgnoreCase(configuredValue))
+            {
+                return false;
+            }
+            else if(SimpleOperationEnum.NOT.equals(operation) && keyValue[1].equalsIgnoreCase(configuredValue))
+            {
+                return false;
+            }
+            result = true;
+        }
+
+        return result;
+    }
+
+    protected abstract String getConfiguredValue(String key);
+}

Modified: myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/tools/InvocationOrderComparator.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/tools/InvocationOrderComparator.java?rev=1148960&r1=1148959&r2=1148960&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/tools/InvocationOrderComparator.java (original)
+++ myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/tools/InvocationOrderComparator.java Wed Jul 20 22:44:46 2011
@@ -37,16 +37,37 @@ public class InvocationOrderComparator<T
      */
     public int compare(T t1, T t2)
     {
-        if (hasPriority(t1) && hasPriority(t2))
+        Class<?> t1Class;
+        Class<?> t2Class;
+
+        if(t1 instanceof Class)
+        {
+            t1Class = (Class)t1;
+        }
+        else
+        {
+            t1Class = t1.getClass();
+        }
+
+        if(t2 instanceof Class)
+        {
+            t2Class = (Class)t2;
+        }
+        else
+        {
+            t2Class = t2.getClass();
+        }
+
+        if (hasPriority(t1Class) && hasPriority(t2Class))
         {
-            return isPriorityHigher(t1.getClass().getAnnotation(InvocationOrder.class),
-                    t2.getClass().getAnnotation(InvocationOrder.class));
+            return isPriorityHigher(t1Class.getAnnotation(InvocationOrder.class),
+                    t2Class.getAnnotation(InvocationOrder.class));
         }
-        if (!hasPriority(t1) && !hasPriority(t2))
+        if (!hasPriority(t1Class) && !hasPriority(t2Class))
         {
             return 0;
         }
-        return hasPriority(t1) ? -1 : 1;
+        return hasPriority(t1Class) ? -1 : 1;
     }
 
     private int isPriorityHigher(InvocationOrder priority1, InvocationOrder priority2)
@@ -59,8 +80,8 @@ public class InvocationOrderComparator<T
         return priority1.value() < priority2.value() ? -1 : 1;
     }
 
-    private boolean hasPriority(Object o)
+    private boolean hasPriority(Class o)
     {
-        return o.getClass().isAnnotationPresent(InvocationOrder.class);
+        return o.isAnnotationPresent(InvocationOrder.class);
     }
 }

Copied: myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/tools/SimpleOperationEnum.java (from r1146737, myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/activation/SimpleOperationEnum.java)
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/tools/SimpleOperationEnum.java?p2=myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/tools/SimpleOperationEnum.java&p1=myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/activation/SimpleOperationEnum.java&r1=1146737&r2=1148960&rev=1148960&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/activation/SimpleOperationEnum.java (original)
+++ myfaces/extensions/cdi/trunk/core/api/src/main/java/org/apache/myfaces/extensions/cdi/core/api/tools/SimpleOperationEnum.java Wed Jul 20 22:44:46 2011
@@ -16,7 +16,7 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-package org.apache.myfaces.extensions.cdi.core.impl.activation;
+package org.apache.myfaces.extensions.cdi.core.api.tools;
 
 /**
  * @author Gerhard Petracek

Added: myfaces/extensions/cdi/trunk/core/api/src/test/java/org/apache/myfaces/extensions/cdi/core/custom/provider/ServiceProvider.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/api/src/test/java/org/apache/myfaces/extensions/cdi/core/custom/provider/ServiceProvider.java?rev=1148960&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/core/api/src/test/java/org/apache/myfaces/extensions/cdi/core/custom/provider/ServiceProvider.java (added)
+++ myfaces/extensions/cdi/trunk/core/api/src/test/java/org/apache/myfaces/extensions/cdi/core/custom/provider/ServiceProvider.java Wed Jul 20 22:44:46 2011
@@ -0,0 +1,50 @@
+/*
+ * 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.myfaces.extensions.cdi.core.custom.provider;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ServiceLoader;
+
+/**
+ * @author Gerhard Petracek
+ */
+@Deprecated
+public class ServiceProvider<T> extends org.apache.myfaces.extensions.cdi.core.api.provider.ServiceProvider<T>
+{
+    protected ServiceProvider(Class<T> serviceType,
+              org.apache.myfaces.extensions.cdi.core.api.provider.ServiceProviderContext serviceProviderContext)
+    {
+        super(serviceType, serviceProviderContext);
+    }
+
+    @Override
+    protected List<T> loadServiceImplementations()
+    {
+        //just a simple version for testing - TODO move tests to core-impl so we don't need this class at all
+        ServiceLoader<T> serviceLoader = ServiceLoader.load(this.serviceType);
+
+        List<T> result = new ArrayList<T>();
+        for(T instance : serviceLoader)
+        {
+            result.add(instance);
+        }
+        return result;
+    }
+}

Added: myfaces/extensions/cdi/trunk/core/api/src/test/java/org/apache/myfaces/extensions/cdi/core/custom/provider/ServiceProviderContext.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/api/src/test/java/org/apache/myfaces/extensions/cdi/core/custom/provider/ServiceProviderContext.java?rev=1148960&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/core/api/src/test/java/org/apache/myfaces/extensions/cdi/core/custom/provider/ServiceProviderContext.java (added)
+++ myfaces/extensions/cdi/trunk/core/api/src/test/java/org/apache/myfaces/extensions/cdi/core/custom/provider/ServiceProviderContext.java Wed Jul 20 22:44:46 2011
@@ -0,0 +1,54 @@
+/*
+ * 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.myfaces.extensions.cdi.core.custom.provider;
+
+import java.util.List;
+
+/**
+ * @author Gerhard Petracek
+ */
+@Deprecated
+public class ServiceProviderContext<T> extends org.apache.myfaces.extensions.cdi.core.api.provider.ServiceProviderContext<T>
+{
+    @Override
+    public ClassLoader getClassLoader()
+    {
+        return getClass().getClassLoader();
+    }
+
+    @Override
+    public T postConstruct(T instance, boolean containerBootstrapped)
+    {
+        //do nothing
+        return instance;
+    }
+
+    @Override
+    public boolean filterService(Class<T> serviceClass)
+    {
+        //do nothing
+        return false;
+    }
+
+    @Override
+    public void preInstallServices(List<Class<?>> foundServiceClasses)
+    {
+        //do nothing
+    }
+}

Modified: myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/activation/ActivationExtension.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/activation/ActivationExtension.java?rev=1148960&r1=1148959&r2=1148960&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/activation/ActivationExtension.java (original)
+++ myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/activation/ActivationExtension.java Wed Jul 20 22:44:46 2011
@@ -18,23 +18,18 @@
  */
 package org.apache.myfaces.extensions.cdi.core.impl.activation;
 
-import javax.enterprise.event.Observes;
-import javax.enterprise.inject.spi.AfterDeploymentValidation;
-import javax.enterprise.inject.spi.Extension;
-import javax.enterprise.inject.spi.ProcessAnnotatedType;
-
-import org.apache.myfaces.extensions.cdi.core.api.activation.ExpressionActivated;
+import org.apache.myfaces.extensions.cdi.core.api.activation.Deactivatable;
 import org.apache.myfaces.extensions.cdi.core.api.activation.ProjectStageActivated;
-import org.apache.myfaces.extensions.cdi.core.api.interpreter.ExpressionInterpreter;
 import org.apache.myfaces.extensions.cdi.core.api.projectstage.ProjectStage;
 import org.apache.myfaces.extensions.cdi.core.api.startup.CodiStartupBroadcaster;
-import org.apache.myfaces.extensions.cdi.core.api.util.ClassUtils;
 import org.apache.myfaces.extensions.cdi.core.impl.projectstage.ProjectStageProducer;
+import org.apache.myfaces.extensions.cdi.core.impl.util.ActivationUtils;
 import org.apache.myfaces.extensions.cdi.core.impl.util.ClassDeactivation;
-import org.apache.myfaces.extensions.cdi.core.api.activation.Deactivatable;
 
-import java.util.logging.Level;
-import java.util.logging.Logger;
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterDeploymentValidation;
+import javax.enterprise.inject.spi.Extension;
+import javax.enterprise.inject.spi.ProcessAnnotatedType;
 
 
 /**
@@ -70,6 +65,9 @@ public class ActivationExtension impleme
         checkProjectStageActivated(processAnnotatedType);
 
         checkExpressionActivated(processAnnotatedType);
+
+        //placed here to ensue that no validation of a deactivated class will be performance
+        validateCodiImplementationRules(processAnnotatedType);
     }
 
     private void checkProjectStageActivated(ProcessAnnotatedType<Object> processAnnotatedType)
@@ -89,40 +87,11 @@ public class ActivationExtension impleme
 
     private void checkExpressionActivated(ProcessAnnotatedType<Object> processAnnotatedType)
     {
-        if (processAnnotatedType.getAnnotatedType().getJavaClass().isAnnotationPresent(ExpressionActivated.class))
-        {
-            ExpressionActivated expressionActivated = processAnnotatedType.getAnnotatedType().getJavaClass()
-                            .getAnnotation(ExpressionActivated.class);
+        Class<?> annotatedClass = processAnnotatedType.getAnnotatedType().getJavaClass();
 
-            String expressions = expressionActivated.value();
-
-            Class<? extends ExpressionInterpreter> interpreter = expressionActivated.interpreter();
-
-            if(interpreter.equals(ExpressionInterpreter.class))
-            {
-                interpreter = PropertyExpressionInterpreter.class;
-            }
-
-            ExpressionInterpreter<String, Boolean> expressionInterpreter =
-                    ClassUtils.tryToInstantiateClass(interpreter);
-
-            if(expressionInterpreter == null)
-            {
-                Logger logger = Logger.getLogger(getClass().getName());
-
-                if(logger.isLoggable(Level.WARNING))
-                {
-                    logger.warning("can't instantiate " + interpreter.getClass().getName());
-                }
-                return;
-            }
-
-            expressions = "configName:" + expressionActivated.configName() + ";" + expressions;
-            if (!expressionInterpreter.evaluate(expressions))
-            {
-                // this alternative shall not get used
-                processAnnotatedType.veto();
-            }
+        if(!ActivationUtils.isActivated(annotatedClass, PropertyExpressionInterpreter.class))
+        {
+            processAnnotatedType.veto();
         }
     }
 
@@ -143,6 +112,11 @@ public class ActivationExtension impleme
         return false;
     }
 
+    private void validateCodiImplementationRules(ProcessAnnotatedType<Object> processAnnotatedType)
+    {
+        //TODO
+    }
+
     /**
      * {@inheritDoc}
      */

Modified: myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/activation/PropertyExpressionInterpreter.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/activation/PropertyExpressionInterpreter.java?rev=1148960&r1=1148959&r2=1148960&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/activation/PropertyExpressionInterpreter.java (original)
+++ myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/activation/PropertyExpressionInterpreter.java Wed Jul 20 22:44:46 2011
@@ -18,8 +18,7 @@
  */
 package org.apache.myfaces.extensions.cdi.core.impl.activation;
 
-import org.apache.myfaces.extensions.cdi.core.api.activation.ExpressionActivated;
-import org.apache.myfaces.extensions.cdi.core.api.interpreter.ExpressionInterpreter;
+import org.apache.myfaces.extensions.cdi.core.api.tools.AbstractPropertyExpressionInterpreter;
 import org.apache.myfaces.extensions.cdi.core.impl.util.CodiUtils;
 
 import javax.enterprise.inject.Typed;
@@ -28,82 +27,14 @@ import javax.enterprise.inject.Typed;
  * @author Gerhard Petracek
  */
 @Typed()
-public class PropertyExpressionInterpreter implements ExpressionInterpreter<String, Boolean>
+public class PropertyExpressionInterpreter extends AbstractPropertyExpressionInterpreter
 {
     /**
      * {@inheritDoc}
      */
-    //TODO
-    public Boolean evaluate(String expressions)
+    @Override
+    protected String getConfiguredValue(String key)
     {
-        boolean result = false;
-        String[] foundExpressions = expressions.split(";");
-        String configFileName = null;
-
-        SimpleOperationEnum operation;
-        for(String expression : foundExpressions)
-        {
-            result = false;
-            if(expression.contains(SimpleOperationEnum.IS.getValue()))
-            {
-                operation = SimpleOperationEnum.IS;
-            }
-            else if(expression.contains(SimpleOperationEnum.NOT.getValue()))
-            {
-                operation = SimpleOperationEnum.NOT;
-            }
-            else if(expression.startsWith("configName:"))
-            {
-                configFileName = expression.split(":")[1];
-                //TODO refactor it - current impl. ensures backward compatibility (see PropertyFileResolver)
-                configFileName = configFileName.replace(".", "@");
-                continue;
-            }
-            else
-            {
-                throw new IllegalStateException("expression: " + expression + " isn't supported by " +
-                        ExpressionActivated.class.getName() +
-                        " supported operations: " + SimpleOperationEnum.getOperations() + "separator: ';'");
-            }
-
-            String[] keyValue = expression.split(operation.getValue());
-
-            String configuredValue = CodiUtils.lookupConfigFromEnvironment(keyValue[0], String.class, "");
-
-            configuredValue = configuredValue.trim();
-
-            if("".equals(configuredValue))
-            {
-                //TODO refactor it - current impl. ensures backward compatibility (see PropertyFileResolver)
-                String internalKey = keyValue[0] + "_";
-
-                configuredValue = CodiUtils
-                        .lookupConfigFromEnvironment(configFileName + "." + internalKey, String.class, "");
-                configuredValue = configuredValue.trim();
-            }
-
-            if(!"*".equals(keyValue[1]) && "".equals(configuredValue))
-            {
-                continue;
-            }
-
-            if("*".equals(keyValue[1]) && !"".equals(configuredValue))
-            {
-                result = true;
-                continue;
-            }
-
-            if(SimpleOperationEnum.IS.equals(operation) && !keyValue[1].equalsIgnoreCase(configuredValue))
-            {
-                return false;
-            }
-            else if(SimpleOperationEnum.NOT.equals(operation) && keyValue[1].equalsIgnoreCase(configuredValue))
-            {
-                return false;
-            }
-            result = true;
-        }
-
-        return result;
+        return CodiUtils.lookupConfigFromEnvironment(key, String.class, "");
     }
 }

Modified: myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/config/AbstractConfiguredValueResolver.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/config/AbstractConfiguredValueResolver.java?rev=1148960&r1=1148959&r2=1148960&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/config/AbstractConfiguredValueResolver.java (original)
+++ myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/config/AbstractConfiguredValueResolver.java Wed Jul 20 22:44:46 2011
@@ -21,10 +21,10 @@ package org.apache.myfaces.extensions.cd
 import org.apache.myfaces.extensions.cdi.core.api.activation.ClassDeactivator;
 import org.apache.myfaces.extensions.cdi.core.api.config.ConfiguredValueResolver;
 import org.apache.myfaces.extensions.cdi.core.api.util.ClassUtils;
+import org.apache.myfaces.extensions.cdi.core.impl.provider.ServiceProvider;
 
-import java.util.List;
 import java.util.ArrayList;
-import java.util.ServiceLoader;
+import java.util.List;
 
 /**
  * @author Gerhard Petracek
@@ -38,8 +38,8 @@ public abstract class AbstractConfigured
 
     protected AbstractConfiguredValueResolver()
     {
-        ServiceLoader<ClassDeactivator> serviceLoader =
-                ServiceLoader.load(ClassDeactivator.class, ClassUtils.getClassLoader(null));
+        List<ClassDeactivator> serviceLoader =
+                ServiceProvider.loadServices(ClassDeactivator.class);
 
         for(ClassDeactivator currentInstance : serviceLoader)
         {

Modified: myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/config/ServiceLoaderResolver.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/config/ServiceLoaderResolver.java?rev=1148960&r1=1148959&r2=1148960&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/config/ServiceLoaderResolver.java (original)
+++ myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/config/ServiceLoaderResolver.java Wed Jul 20 22:44:46 2011
@@ -19,12 +19,12 @@
 package org.apache.myfaces.extensions.cdi.core.impl.config;
 
 import org.apache.myfaces.extensions.cdi.core.api.InvocationOrder;
-import org.apache.myfaces.extensions.cdi.core.api.util.ClassUtils;
 import org.apache.myfaces.extensions.cdi.core.api.config.ConfiguredValueDescriptor;
+import org.apache.myfaces.extensions.cdi.core.impl.provider.ServiceProvider;
+import org.apache.myfaces.extensions.cdi.core.impl.provider.ServiceProviderContext;
 
 import javax.enterprise.inject.Typed;
 import java.util.List;
-import java.util.ServiceLoader;
 import java.util.ArrayList;
 import java.lang.reflect.Modifier;
 
@@ -45,9 +45,16 @@ public class ServiceLoaderResolver exten
         if(Modifier.isAbstract(targetType.getModifiers()) || Modifier.isInterface(targetType.getModifiers()))
         {
             @SuppressWarnings({"unchecked"})
-            ServiceLoader<T> serviceLoader = ServiceLoader.load(targetType, ClassUtils.getClassLoader(null));
+            List<T> services = ServiceProvider.loadServices(targetType, new ServiceProviderContext() {
+                @Override
+                public boolean filterService(Class serviceClass)
+                {
+                    //do nothing
+                    return false;
+                }
+            });
 
-            for(T currentInstance : serviceLoader)
+            for(T currentInstance : services)
             {
                 result.add(currentInstance);
             }

Added: myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/provider/ServiceProvider.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/provider/ServiceProvider.java?rev=1148960&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/provider/ServiceProvider.java (added)
+++ myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/provider/ServiceProvider.java Wed Jul 20 22:44:46 2011
@@ -0,0 +1,286 @@
+/*
+ * 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.myfaces.extensions.cdi.core.impl.provider;
+
+import org.apache.myfaces.extensions.cdi.core.api.UnhandledException;
+import org.apache.myfaces.extensions.cdi.core.api.provider.ServiceProviderContext;
+import org.apache.myfaces.extensions.cdi.core.api.util.ClassUtils;
+
+import javax.enterprise.event.Observes;
+import javax.enterprise.inject.spi.AfterDeploymentValidation;
+import java.io.BufferedReader;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.lang.reflect.Constructor;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * @author Gerhard Petracek
+ */
+public class ServiceProvider<T> extends org.apache.myfaces.extensions.cdi.core.api.provider.ServiceProvider<T>
+{
+    protected List<Class<?>> foundServiceClasses = new ArrayList<Class<?>>();
+    private static Map<ClassLoader, Boolean> allowInjection = new ConcurrentHashMap<ClassLoader, Boolean>();
+    private static Map<Class<?>, List<Class<?>>> serviceCache = new ConcurrentHashMap<Class<?>, List<Class<?>>>();
+
+    protected ServiceProvider(Class<T> serviceType, ServiceProviderContext serviceProviderContext)
+    {
+        super(serviceType, serviceProviderContext);
+    }
+
+    protected List<T> loadServiceImplementations()
+    {
+        List<Class<?>> result = serviceCache.get(this.serviceType);
+
+        if(result == null)
+        {
+            result = resolveServiceImplementations();
+        }
+
+        if(result == null)
+        {
+            return Collections.emptyList();
+        }
+
+        List<T> foundServices = new ArrayList<T>();
+
+        for(Class<?> serviceClass : result)
+        {
+            foundServices.add(createInstance(serviceClass));
+        }
+
+        return foundServices;
+    }
+
+    private List<Class<?>> resolveServiceImplementations()
+    {
+        for (URL configFile : getConfigFileList())
+        {
+            loadConfiguredServices(configFile);
+        }
+
+        this.serviceProviderContext.preInstallServices(this.foundServiceClasses);
+
+        serviceCache.put(this.serviceType, this.foundServiceClasses);
+        return this.foundServiceClasses;
+    }
+
+    protected void activateInjectionSupport(@Observes AfterDeploymentValidation afterDeploymentValidation)
+    {
+        allowInjection.put(ClassUtils.getClassLoader(null), Boolean.TRUE);
+    }
+
+    private List<URL> getConfigFileList()
+    {
+        List<URL> serviceFiles = new ArrayList<URL>();
+
+        try
+        {
+            Enumeration<URL> serviceFileEnumerator =
+                    this.serviceProviderContext.getClassLoader().getResources(getConfigFileLocation());
+
+            while (serviceFileEnumerator.hasMoreElements())
+            {
+                serviceFiles.add(serviceFileEnumerator.nextElement());
+            }
+        }
+        catch (Exception e)
+        {
+            throw new UnhandledException(
+                    "Failed to load " + this.serviceType.getName() + " configured in " + getConfigFileLocation(), e);
+        }
+        return serviceFiles;
+    }
+
+    private String getConfigFileLocation()
+    {
+        return SERVICE_CONFIG + this.serviceType.getName();
+    }
+
+    private void loadConfiguredServices(URL serviceFile)
+    {
+        InputStream inputStream = null;
+
+        try
+        {
+            String serviceClassName;
+            inputStream = serviceFile.openStream();
+            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, FILE_ENCODING));
+
+            while ((serviceClassName = bufferedReader.readLine()) != null)
+            {
+                serviceClassName = extractConfiguredServiceClassName(serviceClassName);
+                if (!"".equals(serviceClassName))
+                {
+                    boolean optionalService = false;
+                    if(serviceClassName.endsWith(":optional")) //TODO
+                    {
+                        optionalService = true;
+                        serviceClassName = serviceClassName.replace(":optional", "");
+                    }
+
+                    loadService(serviceClassName, optionalService);
+                }
+            }
+        }
+        catch (Exception e)
+        {
+            throw new UnhandledException("Failed to process service-config: " + serviceFile, e);
+        }
+        finally
+        {
+            if (inputStream != null)
+            {
+                try
+                {
+                    inputStream.close();
+                }
+                catch (Exception e)
+                {
+                    throw new UnhandledException("Failed to close " + serviceFile, e);
+                }
+            }
+        }
+    }
+
+    private String extractConfiguredServiceClassName(String currentConfigLine)
+    {
+        int startOfComment = currentConfigLine.indexOf('#');
+
+        if (startOfComment > -1)
+        {
+            currentConfigLine = currentConfigLine.substring(0, startOfComment);
+        }
+        return currentConfigLine.trim();
+    }
+
+    private void loadService(String serviceClassName, boolean isOptional)
+    {
+        Class<T> serviceClass = (Class<T>) loadClass(serviceClassName);
+
+        if (serviceClass != null && !this.foundServiceClasses.contains(serviceClass) &&
+                !this.serviceProviderContext.filterService(serviceClass))
+        {
+            this.foundServiceClasses.add(serviceClass);
+        }
+        else if(serviceClass == null)
+        {
+            if(isOptional)
+            {
+                Logger logger = Logger.getLogger(serviceClassName);
+
+                if(logger.isLoggable(Level.INFO))
+                {
+                    logger.info("Optional service " + serviceClassName + " not loaded.");
+                }
+            }
+            else
+            {
+                throw new IllegalStateException(serviceClassName + " couldn't be loaded. " +
+                        "Please ensure that this class is in the classpath or remove the entry from "
+                        + getConfigFileLocation() + ". Or mark it as optional.");
+            }
+        }
+    }
+
+    private Class<? extends T> loadClass(String serviceClassName)
+    {
+        Class<?> targetClass = ClassUtils.tryToLoadClassForName(serviceClassName);
+
+        if(targetClass == null)
+        {
+            targetClass = loadClassForName(serviceClassName, this.serviceProviderContext.getClassLoader());
+
+            if(targetClass == null)
+            {
+                targetClass = loadClassForName(serviceClassName, ClassUtils.getClassLoader(null));
+
+                if(targetClass == null)
+                {
+                    return null;
+                }
+            }
+        }
+
+        return targetClass.asSubclass(this.serviceType);
+    }
+
+    private static Class<?> loadClassForName(String serviceClassName, ClassLoader classLoader)
+    {
+        if(classLoader == null)
+        {
+            return null;
+        }
+
+        try
+        {
+            return classLoader.loadClass(serviceClassName);
+        }
+        catch (Exception e)
+        {
+            return loadClassForName(serviceClassName, classLoader.getParent());
+        }
+    }
+
+    private T createInstance(Class<?> serviceClass)
+    {
+        try
+        {
+            Constructor<?> constructor = serviceClass.getDeclaredConstructor();
+            constructor.setAccessible(true);
+            T instance = (T)constructor.newInstance();
+
+            this.serviceProviderContext.postConstruct(instance, isInjectionAllowed());
+
+            return instance;
+        }
+        catch (Exception e)
+        {
+            return null;
+        }
+    }
+
+    private boolean isInjectionAllowed()
+    {
+        return Boolean.TRUE.equals(allowInjection.get(ClassUtils.getClassLoader(null)));
+    }
+
+    protected void reset()
+    {
+        foundServiceClasses.clear();
+        serviceCache.clear();
+    }
+
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    public String toString()
+    {
+        return "Config file: " + getConfigFileLocation();
+    }
+}

Added: myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/provider/ServiceProviderContext.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/provider/ServiceProviderContext.java?rev=1148960&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/provider/ServiceProviderContext.java (added)
+++ myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/provider/ServiceProviderContext.java Wed Jul 20 22:44:46 2011
@@ -0,0 +1,65 @@
+/*
+ * 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.myfaces.extensions.cdi.core.impl.provider;
+
+import org.apache.myfaces.extensions.cdi.core.api.tools.InvocationOrderComparator;
+import org.apache.myfaces.extensions.cdi.core.api.util.ClassUtils;
+import org.apache.myfaces.extensions.cdi.core.impl.util.ActivationUtils;
+import org.apache.myfaces.extensions.cdi.core.impl.util.CodiUtils;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Gerhard Petracek
+ */
+public class ServiceProviderContext<T>
+        extends org.apache.myfaces.extensions.cdi.core.api.provider.ServiceProviderContext<T>
+{
+    @Override
+    public ClassLoader getClassLoader()
+    {
+        return ClassUtils.getClassLoader(null);
+    }
+
+    @Override
+    public T postConstruct(T instance, boolean containerBootstrapped)
+    {
+        if(containerBootstrapped)
+        {
+            CodiUtils.injectFields(instance, true);
+        }
+        return instance;
+    }
+
+    @Override
+    public boolean filterService(Class<T> serviceClass)
+    {
+        return !ActivationUtils.isActivated(serviceClass, SystemPropertyExpressionInterpreter.class);
+    }
+
+    @Override
+    public void preInstallServices(List<Class<?>> foundServiceClasses)
+    {
+        if(foundServiceClasses != null && !foundServiceClasses.isEmpty())
+        {
+            Collections.sort(foundServiceClasses, new InvocationOrderComparator<Object>());
+        }
+    }
+}

Added: myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/provider/SystemPropertyExpressionInterpreter.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/provider/SystemPropertyExpressionInterpreter.java?rev=1148960&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/provider/SystemPropertyExpressionInterpreter.java (added)
+++ myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/provider/SystemPropertyExpressionInterpreter.java Wed Jul 20 22:44:46 2011
@@ -0,0 +1,42 @@
+/*
+ * 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.myfaces.extensions.cdi.core.impl.provider;
+
+import org.apache.myfaces.extensions.cdi.core.api.tools.AbstractPropertyExpressionInterpreter;
+
+/**
+ * @author Gerhard Petracek
+ */
+public class SystemPropertyExpressionInterpreter extends AbstractPropertyExpressionInterpreter
+{
+    /**
+     * {@inheritDoc}
+     */
+    @Override
+    protected String getConfiguredValue(String key)
+    {
+        String result = System.getProperty(key);
+
+        if(result != null)
+        {
+            return result;
+        }
+        return System.getenv(key);
+    }
+}

Added: myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/util/ActivationUtils.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/util/ActivationUtils.java?rev=1148960&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/util/ActivationUtils.java (added)
+++ myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/util/ActivationUtils.java Wed Jul 20 22:44:46 2011
@@ -0,0 +1,68 @@
+/*
+ * 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.myfaces.extensions.cdi.core.impl.util;
+
+import org.apache.myfaces.extensions.cdi.core.api.activation.ExpressionActivated;
+import org.apache.myfaces.extensions.cdi.core.api.interpreter.ExpressionInterpreter;
+import org.apache.myfaces.extensions.cdi.core.api.util.ClassUtils;
+
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+/**
+ * @author Gerhard Petracek
+ */
+public class ActivationUtils
+{
+    public static boolean isActivated(Class<?> annotatedClass, Class defaultExpressionInterpreterClass)
+    {
+        ExpressionActivated expressionActivated = annotatedClass.getAnnotation(ExpressionActivated.class);
+
+        if (expressionActivated == null)
+        {
+            return true;
+        }
+
+        String expressions = expressionActivated.value();
+
+        Class<? extends ExpressionInterpreter> interpreterClass = expressionActivated.interpreter();
+
+        if(interpreterClass.equals(ExpressionInterpreter.class))
+        {
+            interpreterClass = defaultExpressionInterpreterClass;
+        }
+
+        ExpressionInterpreter<String, Boolean> expressionInterpreter =
+                ClassUtils.tryToInstantiateClass(interpreterClass);
+
+        if(expressionInterpreter == null)
+        {
+            Logger logger = Logger.getLogger(ActivationUtils.class.getName());
+
+            if(logger.isLoggable(Level.WARNING))
+            {
+                logger.warning("can't instantiate " + interpreterClass.getClass().getName());
+            }
+            return true;
+        }
+
+        expressions = "configName:" + expressionActivated.configName() + ";" + expressions;
+        return expressionInterpreter.evaluate(expressions);
+    }
+}

Modified: myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/util/ConfiguredArtifactUtils.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/util/ConfiguredArtifactUtils.java?rev=1148960&r1=1148959&r2=1148960&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/util/ConfiguredArtifactUtils.java (original)
+++ myfaces/extensions/cdi/trunk/core/impl/src/main/java/org/apache/myfaces/extensions/cdi/core/impl/util/ConfiguredArtifactUtils.java Wed Jul 20 22:44:46 2011
@@ -23,6 +23,7 @@ import org.apache.myfaces.extensions.cdi
 import org.apache.myfaces.extensions.cdi.core.api.config.ConfiguredValueResolver;
 import org.apache.myfaces.extensions.cdi.core.api.config.ConfiguredValueDescriptor;
 import org.apache.myfaces.extensions.cdi.core.api.tools.InvocationOrderComparator;
+import org.apache.myfaces.extensions.cdi.core.impl.provider.ServiceProvider;
 
 import javax.enterprise.inject.Typed;
 import java.lang.reflect.Field;
@@ -33,7 +34,6 @@ import java.util.HashSet;
 import java.util.Map;
 import java.util.HashMap;
 import java.util.Collections;
-import java.util.ServiceLoader;
 import java.util.Comparator;
 import java.util.concurrent.ConcurrentHashMap;
 import java.io.Serializable;
@@ -116,7 +116,7 @@ public abstract class ConfiguredArtifact
                                               T defaultImplementation)
     {
         List<T> results = new ArrayList<T>();
-        List<T> resolverResult = null;
+        List<T> resolverResult;
 
         List<ConfiguredValueResolver> resolvers = getConfiguredValueResolvers();
 
@@ -204,8 +204,8 @@ public abstract class ConfiguredArtifact
 
     private static List<ConfiguredValueResolver> getConfiguredValueResolvers()
     {
-        ServiceLoader<ConfiguredValueResolver> configuredValueResolvers =
-                ServiceLoader.load(ConfiguredValueResolver.class, ClassUtils.getClassLoader(null));
+        List<ConfiguredValueResolver> configuredValueResolvers =
+                ServiceProvider.loadServices(ConfiguredValueResolver.class);
 
         List<ConfiguredValueResolver> resolvers = new ArrayList<ConfiguredValueResolver>();
         Comparator<ConfiguredValueResolver> comparator = new InvocationOrderComparator<ConfiguredValueResolver>();

Added: myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/custom/provider/ServiceProvider.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/custom/provider/ServiceProvider.java?rev=1148960&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/custom/provider/ServiceProvider.java (added)
+++ myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/custom/provider/ServiceProvider.java Wed Jul 20 22:44:46 2011
@@ -0,0 +1,33 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.myfaces.extensions.cdi.core.custom.provider;
+
+import org.apache.myfaces.extensions.cdi.core.api.provider.ServiceProviderContext;
+
+/**
+ * @author Gerhard Petracek
+ */
+public class ServiceProvider extends org.apache.myfaces.extensions.cdi.core.impl.provider.ServiceProvider
+{
+    protected ServiceProvider(Class serviceType, ServiceProviderContext serviceProviderContext)
+    {
+        super(serviceType, serviceProviderContext);
+        reset(); //just for testing
+    }
+}

Modified: myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/test/impl/config/TestConfiguredValueResolver.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/test/impl/config/TestConfiguredValueResolver.java?rev=1148960&r1=1148959&r2=1148960&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/test/impl/config/TestConfiguredValueResolver.java (original)
+++ myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/test/impl/config/TestConfiguredValueResolver.java Wed Jul 20 22:44:46 2011
@@ -18,12 +18,14 @@
  */
 package org.apache.myfaces.extensions.cdi.core.test.impl.config;
 
+import org.apache.myfaces.extensions.cdi.core.api.InvocationOrder;
 import org.apache.myfaces.extensions.cdi.core.api.config.ConfiguredValueDescriptor;
 import org.apache.myfaces.extensions.cdi.core.api.config.ConfiguredValueResolver;
 
 import java.util.List;
 import java.util.Collections;
 
+@InvocationOrder(150)
 public class TestConfiguredValueResolver implements ConfiguredValueResolver
 {
     private static boolean called = false;

Modified: myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/test/impl/config/TestImpl.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/test/impl/config/TestImpl.java?rev=1148960&r1=1148959&r2=1148960&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/test/impl/config/TestImpl.java (original)
+++ myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/test/impl/config/TestImpl.java Wed Jul 20 22:44:46 2011
@@ -18,6 +18,9 @@
  */
 package org.apache.myfaces.extensions.cdi.core.test.impl.config;
 
+import org.apache.myfaces.extensions.cdi.core.api.activation.ExpressionActivated;
+
+@ExpressionActivated("env==prod")
 public class TestImpl implements TestInterface
 {
     private static final long serialVersionUID = -9190258825414992052L;

Added: myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/test/impl/serviceloader/ServiceProviderTest.java
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/test/impl/serviceloader/ServiceProviderTest.java?rev=1148960&view=auto
==============================================================================
--- myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/test/impl/serviceloader/ServiceProviderTest.java (added)
+++ myfaces/extensions/cdi/trunk/core/impl/src/test/java/org/apache/myfaces/extensions/cdi/core/test/impl/serviceloader/ServiceProviderTest.java Wed Jul 20 22:44:46 2011
@@ -0,0 +1,107 @@
+/*
+ * 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.myfaces.extensions.cdi.core.test.impl.serviceloader;
+
+import org.apache.myfaces.extensions.cdi.core.api.config.ConfiguredValueResolver;
+import org.apache.myfaces.extensions.cdi.core.api.provider.BeanManagerProvider;
+import org.apache.myfaces.extensions.cdi.core.impl.CodiDeactivatorExtension;
+import org.apache.myfaces.extensions.cdi.core.impl.activation.ActivationExtension;
+import org.apache.myfaces.extensions.cdi.core.impl.config.LocalJndiResolver;
+import org.apache.myfaces.extensions.cdi.core.impl.config.PropertyFileResolver;
+import org.apache.myfaces.extensions.cdi.core.impl.config.ServiceLoaderResolver;
+import org.apache.myfaces.extensions.cdi.core.impl.config.SystemPropertyResolver;
+import org.apache.myfaces.extensions.cdi.core.impl.provider.ServiceProvider;
+import org.apache.myfaces.extensions.cdi.core.test.impl.config.TestConfiguredValueResolver;
+import org.apache.myfaces.extensions.cdi.core.test.impl.config.TestInterface;
+import org.testng.Assert;
+import org.testng.annotations.Test;
+
+import javax.enterprise.inject.spi.Extension;
+import java.util.Iterator;
+import java.util.List;
+
+public class ServiceProviderTest
+{
+    @Test
+    public void testExtensions()
+    {
+        List<Extension> extensionList = ServiceProvider.loadServices(Extension.class);
+        Assert.assertEquals(extensionList.size(), 3);
+
+        Iterator<Extension> iterator = extensionList.iterator();
+
+        Extension extension;
+        while (iterator.hasNext())
+        {
+            extension = iterator.next();
+            Assert.assertTrue(extension instanceof ActivationExtension ||
+                extension instanceof BeanManagerProvider ||
+                extension instanceof CodiDeactivatorExtension);
+
+            iterator.remove();
+        }
+
+        Assert.assertEquals(extensionList.size(), 0);
+    }
+
+    @Test
+    public void testDeactivatedImplementationConditionalExtensions()
+    {
+        System.setProperty("env", "test");
+        List<TestInterface> extensionList = ServiceProvider.loadServices(TestInterface.class);
+
+        Assert.assertEquals(extensionList.size(), 0);
+    }
+
+    @Test
+    public void testActivatedImplementationConditionalExtensions()
+    {
+        System.setProperty("env", "prod");
+        List<TestInterface> extensionList = ServiceProvider.loadServices(TestInterface.class);
+
+        Assert.assertEquals(extensionList.size(), 1);
+    }
+
+    //TODO
+    @Test
+    public void testOptionalExtensions()
+    {
+        System.setProperty("env", "prod");
+        List<TestInterface> extensionList = ServiceProvider.loadServices(TestInterface.class);
+
+        Assert.assertEquals(extensionList.size(), 1);
+    }
+
+    @Test
+    public void testOrderedExtensions()
+    {
+        List<ConfiguredValueResolver> extensionList = ServiceProvider.loadServices(ConfiguredValueResolver.class);
+
+        Iterator<ConfiguredValueResolver> iterator = extensionList.iterator();
+
+        Assert.assertEquals(extensionList.size(), 5);
+
+        Assert.assertTrue(iterator.next() instanceof SystemPropertyResolver);
+        Assert.assertTrue(iterator.next() instanceof TestConfiguredValueResolver);
+        Assert.assertTrue(iterator.next() instanceof ServiceLoaderResolver);
+        Assert.assertTrue(iterator.next() instanceof LocalJndiResolver);
+        Assert.assertTrue(iterator.next() instanceof PropertyFileResolver);
+
+    }
+}

Modified: myfaces/extensions/cdi/trunk/core/impl/src/test/resources/META-INF/services/org.apache.myfaces.extensions.cdi.core.test.impl.config.TestInterface
URL: http://svn.apache.org/viewvc/myfaces/extensions/cdi/trunk/core/impl/src/test/resources/META-INF/services/org.apache.myfaces.extensions.cdi.core.test.impl.config.TestInterface?rev=1148960&r1=1148959&r2=1148960&view=diff
==============================================================================
--- myfaces/extensions/cdi/trunk/core/impl/src/test/resources/META-INF/services/org.apache.myfaces.extensions.cdi.core.test.impl.config.TestInterface (original)
+++ myfaces/extensions/cdi/trunk/core/impl/src/test/resources/META-INF/services/org.apache.myfaces.extensions.cdi.core.test.impl.config.TestInterface Wed Jul 20 22:44:46 2011
@@ -17,4 +17,5 @@
 # under the License.
 #####################################################################################
 
-org.apache.myfaces.extensions.cdi.core.test.impl.config.TestImpl
\ No newline at end of file
+org.apache.myfaces.extensions.cdi.core.test.impl.config.TestImpl
+org.apache.myfaces.extensions.cdi.core.test.impl.config.TestImpl2:optional
\ No newline at end of file