EXTSCRIPT-107: CDI Bootstrapping now working

git-svn-id: https://svn.apache.org/repos/asf/myfaces/extensions/scripting/trunk@1325237 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/extscript-core-root/extscript-cdi/readme.txt b/extscript-core-root/extscript-cdi/readme.txt
new file mode 100644
index 0000000..72d35d2
--- /dev/null
+++ b/extscript-core-root/extscript-cdi/readme.txt
@@ -0,0 +1,20 @@
+struberg: ThreadContextClassLoader
+[4:46pm] werpu_: mhh thats what I have been replacing weird
+[4:48pm] werpu_: ok enough for today
+[4:48pm] werpu_: i really have to debug this out on the owb side of things
+[4:48pm] werpu_: any hint which file does the bean classloading in the owb impl?
+[4:49pm] werpu_: outside of that using an owb extension to bootstrap my system worked like a charm
+[4:49pm] werpu_:
+[4:50pm] struberg: ScannerService
+[4:50pm] struberg: this is the SPI interface
+[4:50pm] struberg: check which one is used in your installation
+[4:50pm] werpu_: DefaultScannerService
+[4:50pm] werpu_: i assume
+[4:50pm] werpu_:
+[4:50pm] struberg: yup
+[4:51pm] werpu_: given that it is a standard web environment
+[4:51pm] werpu_: i will have a look
+[4:51pm] struberg: well, in WebApps there is another one
+[4:51pm] werpu_: ah
+[4:51pm] werpu_: ok
+[4:51pm] struberg: yup, needs to take WEB-INF/classes into consideration as well
\ No newline at end of file
diff --git a/extscript-core-root/extscript-cdi/src/main/java/org/apache/myfaces/extensions/scripting/cdi/core/CDIThrowAwayClassloader.java b/extscript-core-root/extscript-cdi/src/main/java/org/apache/myfaces/extensions/scripting/cdi/core/CDIThrowAwayClassloader.java
new file mode 100644
index 0000000..c89f080
--- /dev/null
+++ b/extscript-core-root/extscript-cdi/src/main/java/org/apache/myfaces/extensions/scripting/cdi/core/CDIThrowAwayClassloader.java
@@ -0,0 +1,145 @@
+/*
+ * 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.scripting.cdi.core;
+
+import org.apache.myfaces.extensions.scripting.core.api.WeavingContext;
+import org.apache.myfaces.extensions.scripting.core.engine.ThrowAwayClassloader;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Enumeration;
+
+/**
+ * @author Werner Punz (latest modification by $Author$)
+ * @version $Revision$ $Date$
+ *          <p/>
+ *          We use
+ */
+
+public class CDIThrowAwayClassloader extends ClassLoader
+{
+    ThrowAwayClassloader _delegate;
+
+    public CDIThrowAwayClassloader(ClassLoader classLoader)
+    {
+        super(classLoader);
+        _delegate = new ThrowAwayClassloader(classLoader);
+    }
+
+    public CDIThrowAwayClassloader()
+    {
+        super();
+        _delegate = new ThrowAwayClassloader();
+    }
+
+    @Override
+    public Class<?> loadClass(String className) throws ClassNotFoundException
+    {
+        return _delegate.loadClass(className);
+    }
+
+    @Override
+    public InputStream getResourceAsStream(String name)
+    {
+        return _delegate.getResourceAsStream(name);
+    }
+
+    @Override
+    public URL getResource(String s)
+    {
+        if (s.contains("META-INF/beans.xml"))
+        {
+            //return target dir
+            try
+            {
+                return WeavingContext.getInstance().getConfiguration().getCompileTarget().toURI().toURL();
+            }
+            catch (MalformedURLException e)
+            {
+                //cannot really happen
+                e.printStackTrace();
+            }
+            return null;
+        }
+        return _delegate.getResource(s);
+    }
+
+    @Override
+    public Enumeration<URL> getResources(String s) throws IOException
+    {
+        Enumeration<URL> urls = _delegate.getResources(s);
+        if (s.contains("META-INF/beans.xml"))
+        {
+            ArrayList<URL> tmpList = Collections.list(urls);
+            tmpList.add(WeavingContext.getInstance().getConfiguration().getCompileTarget().toURI().toURL());
+            return Collections.enumeration(tmpList);
+        }
+        return urls;
+    }
+
+    public static URL getSystemResource(String s)
+    {
+        return ClassLoader.getSystemResource(s);
+    }
+
+    public static Enumeration<URL> getSystemResources(String s) throws IOException
+    {
+        return ClassLoader.getSystemResources(s);
+    }
+
+    public static InputStream getSystemResourceAsStream(String s)
+    {
+        return ClassLoader.getSystemResourceAsStream(s);
+    }
+
+    public static ClassLoader getSystemClassLoader()
+    {
+        return ClassLoader.getSystemClassLoader();
+    }
+
+
+    @Override
+    public void setDefaultAssertionStatus(boolean b)
+    {
+        _delegate.setDefaultAssertionStatus(b);
+    }
+
+    @Override
+    public void setPackageAssertionStatus(String s, boolean b)
+    {
+        _delegate.setPackageAssertionStatus(s, b);
+    }
+
+    @Override
+    public void setClassAssertionStatus(String s, boolean b)
+    {
+        _delegate.setClassAssertionStatus(s, b);
+    }
+
+    @Override
+    public void clearAssertionStatus()
+    {
+        _delegate.clearAssertionStatus();
+    }
+}
diff --git a/extscript-core-root/extscript-cdi/src/main/java/org/apache/myfaces/extensions/scripting/cdi/core/ExtScriptScannerService.java b/extscript-core-root/extscript-cdi/src/main/java/org/apache/myfaces/extensions/scripting/cdi/core/ExtScriptScannerService.java
new file mode 100644
index 0000000..768da39
--- /dev/null
+++ b/extscript-core-root/extscript-cdi/src/main/java/org/apache/myfaces/extensions/scripting/cdi/core/ExtScriptScannerService.java
@@ -0,0 +1,215 @@
+/*
+ * 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.scripting.cdi.core;
+
+import org.apache.myfaces.extensions.scripting.core.api.WeavingContext;
+import org.apache.myfaces.extensions.scripting.jsf.startup.StartupServletContextPluginChainLoader;
+import org.apache.webbeans.config.OWBLogConst;
+import org.apache.webbeans.corespi.scanner.AbstractMetaDataDiscovery;
+import org.apache.webbeans.corespi.scanner.AnnotationDB;
+import org.apache.webbeans.corespi.se.BeansXmlAnnotationDB;
+import org.apache.webbeans.exception.WebBeansConfigurationException;
+import org.apache.webbeans.logger.WebBeansLogger;
+import org.apache.webbeans.util.WebBeansUtil;
+import org.scannotation.WarUrlFinder;
+
+import javax.servlet.ServletContext;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Configures the web application to find beans.
+ */
+public class ExtScriptScannerService extends AbstractMetaDataDiscovery
+{
+    private final WebBeansLogger logger = WebBeansLogger.getLogger(ExtScriptScannerService.class);
+
+    private boolean configure = false;
+
+    protected ServletContext servletContext = null;
+
+    public ExtScriptScannerService()
+    {
+
+    }
+
+    public void init(Object context)
+    {
+        super.init(context);
+        this.servletContext = (ServletContext) context;
+        try
+        {
+            StartupServletContextPluginChainLoader.startup(servletContext);
+        }
+        catch (IOException e)
+        {
+            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
+        }
+    }
+
+    protected void configure()
+    {
+        try
+        {
+            if (!configure)
+            {
+                Set<String> arcs = getArchives();
+                String[] urls = new String[arcs.size()];
+                urls = arcs.toArray(urls);
+
+                getAnnotationDB().scanArchives(urls);
+
+                configure = true;
+            }
+
+        }
+        catch (Exception e)
+        {
+            throw new WebBeansConfigurationException(logger.getTokenString(OWBLogConst.ERROR_0002), e);
+        }
+
+    }
+
+    /**
+     * @return all beans.xml paths
+     */
+    private Set<String> getArchives() throws Exception
+    {
+        Set<String> lists = createURLFromMarkerFile();
+        String warUrlPath = createURLFromWARFile();
+        String targetUrlPath = createURLFromTargetPath();
+
+        if (warUrlPath != null)
+        {
+            lists.add(warUrlPath);
+        }
+        lists.add(targetUrlPath);
+
+        return lists;
+    }
+
+    protected String createURLFromTargetPath()
+    {
+        File targetPath = WeavingContext.getInstance().getConfiguration().getCompileTarget();
+        return "file:" + targetPath.getAbsolutePath();
+    }
+
+    /* Creates URLs from the marker file */
+    protected Set<String> createURLFromMarkerFile() throws Exception
+    {
+        Set<String> listURL = new HashSet<String>();
+
+        // Root with beans.xml marker.
+        String[] urls = findBeansXmlBases("META-INF/beans.xml", WebBeansUtil.getCurrentClassLoader());
+
+        if (urls != null)
+        {
+            String addPath;
+            for (String url : urls)
+            {
+                String fileDir = new URL(url).getFile();
+                if (fileDir.endsWith(".jar!/"))
+                {
+                    fileDir = fileDir.substring(0, fileDir.lastIndexOf("/")) + "/META-INF/beans.xml";
+
+                    //fix for weblogic
+                    if (!fileDir.startsWith("file:/"))
+                    {
+                        fileDir = "file:/" + fileDir;
+                        //TODO switch to a more stable approach
+                        //url = new URL("jar:" + fileDir);
+                    }
+
+                    if (logger.wblWillLogDebug())
+                    {
+                        logger.debug("OpenWebBeans found the following url while doing web scanning: " + fileDir);
+                    }
+
+                    addPath = "jar:" + fileDir;
+
+                    if (logger.wblWillLogDebug())
+                    {
+                        logger.debug("OpenWebBeans added the following jar based path while doing web scanning: " +
+                                addPath);
+                    }
+                } else
+                {
+                    //X TODO check!
+                    addPath = "file:" + url + "META-INF/beans.xml";
+
+                    if (logger.wblWillLogDebug())
+                    {
+                        logger.debug("OpenWebBeans added the following file based path while doing web scanning: " +
+                                addPath);
+                    }
+
+                }
+
+                listURL.add(url);
+            }
+        }
+
+        return listURL;
+    }
+
+    /**
+     * Returns the web application class path if it contains
+     * a beans.xml marker file.
+     *
+     * @return the web application class path
+     * @throws Exception if any exception occurs
+     */
+    protected String createURLFromWARFile() throws Exception
+    {
+        if (servletContext == null)
+        {
+            // this may happen if we are running in a test container, in IDE development, etc
+            return null;
+        }
+
+        URL url = servletContext.getResource("/WEB-INF/beans.xml");
+
+        if (url != null)
+        {
+            addWebBeansXmlLocation(url);
+            URL resourceUrl = WarUrlFinder.findWebInfClassesPath(this.servletContext);
+
+            if (resourceUrl == null)
+            {
+                return null;
+            }
+
+            //set resource to beans.xml mapping
+            AnnotationDB annotationDB = getAnnotationDB();
+
+            if (annotationDB instanceof BeansXmlAnnotationDB)
+            {
+                ((BeansXmlAnnotationDB) annotationDB).setResourceBeansXml(resourceUrl.toExternalForm(), url.toExternalForm());
+            }
+            return resourceUrl.toExternalForm();
+        }
+
+        return null;
+    }
+
+}
diff --git a/extscript-core-root/extscript-cdi/src/main/java/org/apache/myfaces/extensions/scripting/cdi/startup/CDIServletContainerInitializer.java b/extscript-core-root/extscript-cdi/src/main/java/org/apache/myfaces/extensions/scripting/cdi/startup/CDIServletContainerInitializer.java
deleted file mode 100644
index 1badd95..0000000
--- a/extscript-core-root/extscript-cdi/src/main/java/org/apache/myfaces/extensions/scripting/cdi/startup/CDIServletContainerInitializer.java
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package org.apache.myfaces.extensions.scripting.cdi.startup;
-
-import javax.servlet.ServletContainerInitializer;
-import javax.servlet.ServletContext;
-import java.lang.ref.WeakReference;
-import java.util.Set;
-
-/**
- * @author Werner Punz (latest modification by $Author$)
- * @version $Revision$ $Date$
- *
- * Initializer which stores the servlet context
- * for later non servlet based references.
- *
- * This is the first stage in the servlet lifecycle
- * and starts before the cdi container.
- *
- * Stage 0 of our startup cycle
- */
-
-public class CDIServletContainerInitializer implements ServletContainerInitializer
-{
-    private static WeakReference<ServletContext> _contextHolder = null;
-
-    public void onStartup(Set<Class<?>> c, ServletContext cx)
-    {
-        _contextHolder = new WeakReference(cx);
-    }
-
-    public static ServletContext getContext()
-    {
-        return _contextHolder.get();
-    }
-
-}
diff --git a/extscript-core-root/extscript-cdi/src/main/java/org/apache/myfaces/extensions/scripting/cdi/startup/StartupExtension.java b/extscript-core-root/extscript-cdi/src/main/java/org/apache/myfaces/extensions/scripting/cdi/startup/StartupExtension.java
index 8e1a0df..814e2f5 100644
--- a/extscript-core-root/extscript-cdi/src/main/java/org/apache/myfaces/extensions/scripting/cdi/startup/StartupExtension.java
+++ b/extscript-core-root/extscript-cdi/src/main/java/org/apache/myfaces/extensions/scripting/cdi/startup/StartupExtension.java
@@ -19,6 +19,7 @@
 
 package org.apache.myfaces.extensions.scripting.cdi.startup;
 
+import org.apache.myfaces.extensions.scripting.cdi.core.CDIThrowAwayClassloader;
 import org.apache.myfaces.extensions.scripting.core.engine.ThrowAwayClassloader;
 import org.apache.myfaces.extensions.scripting.jsf.startup.StartupServletContextPluginChainLoader;
 
@@ -50,16 +51,8 @@
         //the compile runs but not with the daemon thread
         //after that we can load the classes
         //by temporarily plugging in our throw away classloader
-        try
-        {
-            StartupServletContextPluginChainLoader.startup(CDIServletContainerInitializer.getContext());
-            _classLoaderHolder.set(Thread.currentThread().getContextClassLoader());
-            Thread.currentThread().setContextClassLoader(new ThrowAwayClassloader());
-        }
-        catch (IOException e)
-        {
-            e.printStackTrace();  //To change body of catch statement use File | Settings | File Templates.
-        }
+       _classLoaderHolder.set(Thread.currentThread().getContextClassLoader());
+       Thread.currentThread().setContextClassLoader(new CDIThrowAwayClassloader(Thread.currentThread().getContextClassLoader()));
     }
 
     void afterBeanDiscovery(@Observes AfterBeanDiscovery abd)
diff --git a/extscript-core-root/extscript-cdi/src/main/resources/META-INF/openwebbeans/openwebbeans.properties b/extscript-core-root/extscript-cdi/src/main/resources/META-INF/openwebbeans/openwebbeans.properties
new file mode 100644
index 0000000..2f8c29c
--- /dev/null
+++ b/extscript-core-root/extscript-cdi/src/main/resources/META-INF/openwebbeans/openwebbeans.properties
@@ -0,0 +1,6 @@
+configuration.ordinal=12
+
+################################### WEB Scanner Service ####################################
+#Default implementation of org.apache.webbeans.corespi.ScannerService.
+org.apache.webbeans.spi.ScannerService=org.apache.myfaces.extensions.scripting.cdi.core.ExtScriptScannerService
+################################################################################################
\ No newline at end of file
diff --git a/extscript-core-root/extscript-cdi/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer b/extscript-core-root/extscript-cdi/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer
deleted file mode 100644
index 0ddf67b..0000000
--- a/extscript-core-root/extscript-cdi/src/main/resources/META-INF/services/javax.servlet.ServletContainerInitializer
+++ /dev/null
@@ -1,20 +0,0 @@
-#####################################################################################
-# Licensed to the Apache Software Foundation (ASF) under one
-# or more contributor license agreements. See the NOTICE file
-# distributed with this work for additional information
-# regarding copyright ownership. The ASF licenses this file
-# to you under the Apache License, Version 2.0 (the
-# "License"); you may not use this file except in compliance
-# with the License. You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing,
-# software distributed under the License is distributed on an
-# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-# KIND, either express or implied. See the License for the
-# specific language governing permissions and limitations
-# under the License.
-#####################################################################################
-
-org.apache.myfaces.extensions.scripting.cdi.startup.CDIServletContainerInitializer
\ No newline at end of file