openwebbeans-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From rmannibu...@apache.org
Subject svn commit: r1769479 [14/16] - in /openwebbeans/microwave/trunk: ./ meecrowave-arquillian/ meecrowave-arquillian/src/ meecrowave-arquillian/src/main/ meecrowave-arquillian/src/main/java/ meecrowave-arquillian/src/main/java/org/ meecrowave-arquillian/sr...
Date Sun, 13 Nov 2016 09:34:10 GMT
Added: openwebbeans/microwave/trunk/meecrowave-gradle-plugin/src/main/java/org/apache/meecrowave/gradle/MeecrowaveTask.java
URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/meecrowave-gradle-plugin/src/main/java/org/apache/meecrowave/gradle/MeecrowaveTask.java?rev=1769479&view=auto
==============================================================================
--- openwebbeans/microwave/trunk/meecrowave-gradle-plugin/src/main/java/org/apache/meecrowave/gradle/MeecrowaveTask.java (added)
+++ openwebbeans/microwave/trunk/meecrowave-gradle-plugin/src/main/java/org/apache/meecrowave/gradle/MeecrowaveTask.java Sun Nov 13 09:34:07 2016
@@ -0,0 +1,885 @@
+/*
+ * 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.meecrowave.gradle;
+
+import org.apache.meecrowave.gradle.classloader.FilterGradleClassLoader;
+import org.gradle.api.DefaultTask;
+import org.gradle.api.GradleException;
+import org.gradle.api.Project;
+import org.gradle.api.artifacts.Configuration;
+import org.gradle.api.tasks.Input;
+import org.gradle.api.tasks.Optional;
+import org.gradle.api.tasks.TaskAction;
+
+import java.io.File;
+import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Scanner;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.stream.Stream;
+
+import static java.util.Arrays.asList;
+import static java.util.Optional.ofNullable;
+import static java.util.stream.Collectors.toList;
+
+public class MeecrowaveTask extends DefaultTask {
+    private Configuration classpath;
+
+    @Input
+    @Optional
+    private int httpPort = 8080;
+
+    @Input
+    @Optional
+    private int httpsPort = 8443;
+
+    @Input
+    @Optional
+    private int stopPort = -1;
+
+    @Input
+    @Optional
+    private String host = "localhost";
+
+    @Input
+    @Optional
+    private String dir;
+
+    @Input
+    @Optional
+    private String sharedLibraries;
+
+    @Input
+    @Optional
+    private File serverXml;
+
+    @Input
+    @Optional
+    private boolean keepServerXmlAsThis;
+
+    @Input
+    @Optional
+    private boolean tomcatWrapLoader = false;
+
+    @Input
+    @Optional
+    private Map<String, String> properties;
+
+    @Input
+    @Optional
+    private boolean quickSession = true;
+
+    @Input
+    @Optional
+    private boolean jaxrsLogProviders = false;
+
+    @Input
+    @Optional
+    private boolean useTomcatDefaults = true;
+    @Input
+    @Optional
+    private boolean skipHttp;
+
+    @Input
+    @Optional
+    private boolean ssl;
+
+    @Input
+    @Optional
+    private String keystoreFile;
+
+    @Input
+    @Optional
+    private String keystorePass;
+
+    @Input
+    @Optional
+    private String keystoreType;
+
+    @Input
+    @Optional
+    private String clientAuth;
+
+    @Input
+    @Optional
+    private String keyAlias;
+
+    @Input
+    @Optional
+    private String sslProtocol;
+
+    @Input
+    @Optional
+    private String webXml;
+
+    @Input
+    @Optional
+    private String tomcatFilter;
+
+    @Input
+    @Optional
+    private String loginConfig;
+
+    @Input
+    @Optional
+    private Collection<String> securityConstraints = new LinkedList<>();
+
+    @Input
+    @Optional
+    private Map<String, String> users;
+
+    @Input
+    @Optional
+    private Map<String, String> roles;
+
+    @Input
+    @Optional
+    private Map<String, String> cxfServletParams;
+
+    @Input
+    @Optional
+    private boolean http2;
+
+    @Input
+    @Optional
+    private String tempDir;
+
+    @Input
+    @Optional
+    private boolean webResourceCached;
+
+    @Input
+    @Optional
+    private boolean useLog4j2JulLogManager = System.getProperty("java.util.logging.manager") == null;
+
+    @Input
+    @Optional
+    private String conf;
+
+    @Input
+    @Optional
+    private boolean deleteBaseOnStartup = true;
+
+    @Input
+    @Optional
+    private String jaxrsMapping = "/*";
+
+    @Input
+    @Optional
+    private boolean jaxrsProviderSetup = true;
+
+    @Input
+    @Optional
+    private String jaxrsDefaultProviders;
+
+    @Input
+    @Optional
+    private boolean loggingGlobalSetup = true;
+
+    @Input
+    @Optional
+    private boolean cdiConversation;
+
+    @Input
+    @Optional
+    private boolean skip;
+
+    @Input
+    @Optional
+    private boolean tomcatScanning = true;
+
+    @Input
+    @Optional
+    private boolean tomcatAutoSetup = true;
+
+    @Input
+    @Optional
+    private boolean useShutdownHook = true;
+
+    @Input
+    @Optional
+    private List<File> modules;
+
+    @Input
+    @Optional
+    private Collection<String> applicationScopes = new HashSet<>(asList("compile", "runtime"));
+
+    @Input
+    @Optional
+    private Collection<String> classloaderFilteredPackages;
+
+    @Input
+    @Optional
+    private String context = "";
+
+    @Input
+    @Optional
+    private File webapp;
+
+    @TaskAction
+    public void bake() {
+        fixConfig();
+
+        final Thread thread = Thread.currentThread();
+        final ClassLoader tccl = thread.getContextClassLoader();
+        thread.setContextClassLoader(createLoader(tccl));
+        try {
+            doRun();
+        } finally {
+            thread.setContextClassLoader(tccl);
+        }
+    }
+
+    private void doRun() {
+        final Thread thread = Thread.currentThread();
+        final ClassLoader loader = thread.getContextClassLoader();
+
+        final AtomicBoolean running = new AtomicBoolean(false);
+        Thread hook = null;
+        AutoCloseable container;
+        try {
+            final Class<?> containerClass = loader.loadClass("org.apache.meecrowave.Meecrowave");
+            final Class<?> configClass = loader.loadClass("org.apache.meecrowave.Meecrowave$Builder");
+
+            final Object config = getConfig(configClass);
+
+            running.set(true);
+            container = AutoCloseable.class.cast(containerClass.getConstructor(configClass).newInstance(config));
+
+            final AutoCloseable finalContainer = container;
+            hook = new Thread() {
+                @Override
+                public void run() {
+                    if (running.compareAndSet(true, false)) {
+                        final Thread thread = Thread.currentThread();
+                        final ClassLoader old = thread.getContextClassLoader();
+                        thread.setContextClassLoader(loader);
+                        try {
+                            finalContainer.close();
+                        } catch (final NoClassDefFoundError noClassDefFoundError) {
+                            // debug cause it is too late to shutdown properly so don't pollute logs
+                            getLogger().debug("can't stop Meecrowave", noClassDefFoundError);
+                        } catch (final Exception e) {
+                            getLogger().error("can't stop Meecrowave", e);
+                        } finally {
+                            thread.setContextClassLoader(old);
+                        }
+                    }
+                }
+            };
+            hook.setName("Meecrowave-Embedded-ShutdownHook");
+            Runtime.getRuntime().addShutdownHook(hook);
+
+            containerClass.getMethod("start").invoke(container);
+            final String fixedContext = ofNullable(context).orElse("");
+            if (webapp == null) {
+                containerClass.getMethod("deployClasspath", String.class).invoke(container, fixedContext);
+            } else {
+                containerClass.getMethod("deployWebapp", String.class, File.class).invoke(container, fixedContext, webapp);
+            }
+
+            getLogger().info("Meecrowave started on " + configClass.getMethod("getHost").invoke(config) + ":" + configClass.getMethod("getHttpPort").invoke(config));
+        } catch (final Exception e) {
+            ofNullable(hook).ifPresent(h -> {
+                try {
+                    h.run();
+                } finally {
+                    Runtime.getRuntime().removeShutdownHook(h);
+                }
+            });
+            throw new GradleException(e.getMessage(), e);
+        }
+
+        try {
+            String line;
+            final Scanner scanner = new Scanner(System.in);
+            while ((line = scanner.nextLine()) != null) {
+                final String cmd = line.trim().toLowerCase(Locale.ENGLISH);
+                switch (cmd) {
+                    case "exit":
+                    case "quit":
+                        running.set(false);
+                        try {
+                            hook.run();
+                        } finally {
+                            Runtime.getRuntime().removeShutdownHook(hook);
+                        }
+                        return;
+                    default:
+                        getLogger().warn("Unknown: '" + cmd + "', use 'exit' or 'quit'");
+                }
+            }
+        } catch (final Exception e) {
+            Thread.interrupted();
+        } finally {
+            thread.setContextClassLoader(loader);
+        }
+    }
+
+    private Object getConfig(final Class<?> configClass) throws Exception {
+        final Object config = configClass.newInstance();
+        for (final Field field : MeecrowaveTask.class.getDeclaredFields()) {
+            try {
+                final Field configField = configClass.getDeclaredField(field.getName());
+                if (!configField.getType().equals(field.getType())) {
+                    getLogger().debug("Skipping " + field.getName() + " since type doesnt match");
+                    continue;
+                }
+                if (!field.isAccessible()) {
+                    field.setAccessible(true);
+                }
+
+                final Object value = field.get(this);
+                if (value != null) {
+                    if (!configField.isAccessible()) {
+                        configField.setAccessible(true);
+                    }
+                    configField.set(config, value);
+                    getLogger().debug("using " + field.getName() + " = " + value);
+                }
+            } catch (final NoSuchFieldException nsfe) {
+                // ignored
+            } catch (final Exception e) {
+                getLogger().warn("can't initialize attribute " + field.getName(), e);
+            }
+        }
+
+        if (securityConstraints != null) {
+            configClass.getMethod("setSecurityConstraints", Collection.class).invoke(config, securityConstraints.stream()
+                    .map(item -> {
+                        try {
+                            final Class<?> recipeType = configClass.getClassLoader().loadClass("org.apache.xbean.recipe.ObjectRecipe");
+                            final Class<?> builderType = configClass.getClassLoader().loadClass("org.apache.meecrowave.Meecrowave$SecurityConstaintBuilder");
+                            final Object recipe = recipeType.getConstructor(Class.class).newInstance(builderType);
+                            Stream.of(item.split(";"))
+                                    .map(v -> v.split("="))
+                                    .forEach(v -> {
+                                        try {
+                                            recipe.getClass().getMethod("setProperty", String.class, String.class).invoke(recipe, v[0], v[1]);
+                                        } catch (final NoSuchMethodException | IllegalAccessException e) {
+                                            throw new IllegalStateException(e);
+                                        } catch (final InvocationTargetException e) {
+                                            throw new IllegalStateException(e.getCause());
+                                        }
+                                    });
+                            return recipe.getClass().getMethod("create", ClassLoader.class).invoke(recipe, configClass.getClassLoader());
+                        } catch (final Exception cnfe) {
+                            throw new IllegalArgumentException(item);
+                        }
+                    }).collect(toList()));
+        }
+        ofNullable(loginConfig).ifPresent(lc -> {
+            try {
+                final Class<?> recipeType = configClass.getClassLoader().loadClass("org.apache.xbean.recipe.ObjectRecipe");
+                final Class<?> builderType = configClass.getClassLoader().loadClass("org.apache.meecrowave.Meecrowave$LoginConfigBuilder");
+                final Object recipe = recipeType.getConstructor(Class.class).newInstance(builderType);
+                Stream.of(loginConfig.split(";"))
+                        .map(v -> v.split("="))
+                        .forEach(v -> {
+                            try {
+                                recipe.getClass().getMethod("setProperty", String.class, String.class).invoke(recipe, v[0], v[1]);
+                            } catch (final NoSuchMethodException | IllegalAccessException e) {
+                                throw new IllegalStateException(e);
+                            } catch (final InvocationTargetException e) {
+                                throw new IllegalStateException(e.getCause());
+                            }
+                        });
+                configClass.getMethod("setLoginConfig", Collection.class)
+                        .invoke(config, recipe.getClass().getMethod("create", ClassLoader.class).invoke(recipe, configClass.getClassLoader()));
+            } catch (final Exception cnfe) {
+                throw new IllegalArgumentException(loginConfig);
+            }
+        });
+
+        return config;
+    }
+
+    private ClassLoader createLoader(final ClassLoader parent) {
+        final Collection<URL> urls = new LinkedHashSet<>(64);
+
+        addFiles(modules, urls);
+
+        for (final Configuration cc : getProject().getConfigurations()) {
+            if (applicationScopes.contains(cc.getName())) {
+                addFiles(cc.getFiles(), urls);
+            }
+        }
+
+        addFiles(classpath.getFiles(), urls);
+
+        // use JVM loader to avoid the noise of gradle and its plugins
+        return new URLClassLoader(urls.toArray(new URL[urls.size()]), new FilterGradleClassLoader(parent, classloaderFilteredPackages));
+    }
+
+    private void addFiles(final Collection<File> files, final Collection<URL> urls) {
+        if (files == null || files.isEmpty()) {
+            return;
+        }
+        for (final File f : files) {
+            final String name = f.getName();
+            if (name.startsWith("slf4j-api") || name.startsWith("slf4j-jdk14")) {
+                continue; // use gradle
+            }
+            try {
+                urls.add(f.toURI().toURL());
+            } catch (final MalformedURLException e) {
+                throw new IllegalArgumentException(e);
+            }
+        }
+    }
+
+    private void fixConfig() {
+        final Project project = getProject();
+
+        // defaults
+        if (classpath == null) {
+            classpath = project.getConfigurations().getByName(MeecrowavePlugin.NAME);
+        }
+
+        if (dir == null) {
+            dir = new File(project.getBuildDir(), "meecrowave/run").getAbsolutePath();
+        }
+
+        // extension override
+        final MeecrowaveExtension extension = MeecrowaveExtension.class.cast(project.getExtensions().findByName(MeecrowavePlugin.NAME));
+        if (extension != null) {
+            for (final Field f : MeecrowaveTask.class.getDeclaredFields()) {
+                if (f.isAnnotationPresent(Input.class)) {
+                    try {
+                        final Field extField = MeecrowaveExtension.class.getDeclaredField(f.getName());
+                        if (!extField.isAccessible()) {
+                            extField.setAccessible(true);
+                        }
+                        final Object val = extField.get(extension);
+                        if (val != null) {
+                            if (!f.isAccessible()) {
+                                f.setAccessible(true);
+                            }
+                            f.set(this, val);
+                        }
+                    } catch (final IllegalAccessException | NoSuchFieldException e) {
+                        getLogger().debug("No field " + f.getName() + " in " + extension, e);
+                    }
+                }
+            }
+        }
+    }
+
+    public Configuration getClasspath() {
+        return classpath;
+    }
+
+    public void setClasspath(final Configuration classpath) {
+        this.classpath = classpath;
+    }
+
+    public int getHttpPort() {
+        return httpPort;
+    }
+
+    public void setHttpPort(final int httpPort) {
+        this.httpPort = httpPort;
+    }
+
+    public int getHttpsPort() {
+        return httpsPort;
+    }
+
+    public void setHttpsPort(final int httpsPort) {
+        this.httpsPort = httpsPort;
+    }
+
+    public int getStopPort() {
+        return stopPort;
+    }
+
+    public void setStopPort(final int stopPort) {
+        this.stopPort = stopPort;
+    }
+
+    public String getHost() {
+        return host;
+    }
+
+    public void setHost(final String host) {
+        this.host = host;
+    }
+
+    public String getDir() {
+        return dir;
+    }
+
+    public void setDir(final String dir) {
+        this.dir = dir;
+    }
+
+    public File getServerXml() {
+        return serverXml;
+    }
+
+    public void setServerXml(final File serverXml) {
+        this.serverXml = serverXml;
+    }
+
+    public boolean isKeepServerXmlAsThis() {
+        return keepServerXmlAsThis;
+    }
+
+    public void setKeepServerXmlAsThis(final boolean keepServerXmlAsThis) {
+        this.keepServerXmlAsThis = keepServerXmlAsThis;
+    }
+
+    public Map<String, String> getProperties() {
+        return properties;
+    }
+
+    public void setProperties(final Map<String, String> properties) {
+        this.properties = properties;
+    }
+
+    public boolean isQuickSession() {
+        return quickSession;
+    }
+
+    public void setQuickSession(final boolean quickSession) {
+        this.quickSession = quickSession;
+    }
+
+    public boolean isSkipHttp() {
+        return skipHttp;
+    }
+
+    public void setSkipHttp(final boolean skipHttp) {
+        this.skipHttp = skipHttp;
+    }
+
+    public boolean isSsl() {
+        return ssl;
+    }
+
+    public void setSsl(final boolean ssl) {
+        this.ssl = ssl;
+    }
+
+    public String getKeystoreFile() {
+        return keystoreFile;
+    }
+
+    public void setKeystoreFile(final String keystoreFile) {
+        this.keystoreFile = keystoreFile;
+    }
+
+    public String getKeystorePass() {
+        return keystorePass;
+    }
+
+    public void setKeystorePass(final String keystorePass) {
+        this.keystorePass = keystorePass;
+    }
+
+    public String getKeystoreType() {
+        return keystoreType;
+    }
+
+    public void setKeystoreType(final String keystoreType) {
+        this.keystoreType = keystoreType;
+    }
+
+    public String getClientAuth() {
+        return clientAuth;
+    }
+
+    public void setClientAuth(final String clientAuth) {
+        this.clientAuth = clientAuth;
+    }
+
+    public String getKeyAlias() {
+        return keyAlias;
+    }
+
+    public void setKeyAlias(final String keyAlias) {
+        this.keyAlias = keyAlias;
+    }
+
+    public String getSslProtocol() {
+        return sslProtocol;
+    }
+
+    public void setSslProtocol(final String sslProtocol) {
+        this.sslProtocol = sslProtocol;
+    }
+
+    public String getWebXml() {
+        return webXml;
+    }
+
+    public void setWebXml(final String webXml) {
+        this.webXml = webXml;
+    }
+
+    public String getLoginConfig() {
+        return loginConfig;
+    }
+
+    public void setLoginConfig(final String loginConfig) {
+        this.loginConfig = loginConfig;
+    }
+
+    public Collection<String> getSecurityConstraints() {
+        return securityConstraints;
+    }
+
+    public void setSecurityConstraints(final Collection<String> securityConstraints) {
+        this.securityConstraints = securityConstraints;
+    }
+
+    public Map<String, String> getUsers() {
+        return users;
+    }
+
+    public void setUsers(final Map<String, String> users) {
+        this.users = users;
+    }
+
+    public Map<String, String> getRoles() {
+        return roles;
+    }
+
+    public void setRoles(final Map<String, String> roles) {
+        this.roles = roles;
+    }
+
+    public Map<String, String> getCxfServletParams() {
+        return cxfServletParams;
+    }
+
+    public void setCxfServletParams(final Map<String, String> cxfServletParams) {
+        this.cxfServletParams = cxfServletParams;
+    }
+
+    public boolean isHttp2() {
+        return http2;
+    }
+
+    public void setHttp2(final boolean http2) {
+        this.http2 = http2;
+    }
+
+    public String getTempDir() {
+        return tempDir;
+    }
+
+    public void setTempDir(final String tempDir) {
+        this.tempDir = tempDir;
+    }
+
+    public boolean isWebResourceCached() {
+        return webResourceCached;
+    }
+
+    public void setWebResourceCached(final boolean webResourceCached) {
+        this.webResourceCached = webResourceCached;
+    }
+
+    public String getConf() {
+        return conf;
+    }
+
+    public void setConf(final String conf) {
+        this.conf = conf;
+    }
+
+    public boolean isDeleteBaseOnStartup() {
+        return deleteBaseOnStartup;
+    }
+
+    public void setDeleteBaseOnStartup(final boolean deleteBaseOnStartup) {
+        this.deleteBaseOnStartup = deleteBaseOnStartup;
+    }
+
+    public String getJaxrsMapping() {
+        return jaxrsMapping;
+    }
+
+    public void setJaxrsMapping(final String jaxrsMapping) {
+        this.jaxrsMapping = jaxrsMapping;
+    }
+
+    public boolean isJaxrsProviderSetup() {
+        return jaxrsProviderSetup;
+    }
+
+    public void setJaxrsProviderSetup(final boolean jaxrsProviderSetup) {
+        this.jaxrsProviderSetup = jaxrsProviderSetup;
+    }
+
+    public boolean isLoggingGlobalSetup() {
+        return loggingGlobalSetup;
+    }
+
+    public void setLoggingGlobalSetup(final boolean loggingGlobalSetup) {
+        this.loggingGlobalSetup = loggingGlobalSetup;
+    }
+
+    public boolean isCdiConversation() {
+        return cdiConversation;
+    }
+
+    public void setCdiConversation(final boolean cdiConversation) {
+        this.cdiConversation = cdiConversation;
+    }
+
+    public boolean isSkip() {
+        return skip;
+    }
+
+    public void setSkip(final boolean skip) {
+        this.skip = skip;
+    }
+
+    public boolean isTomcatScanning() {
+        return tomcatScanning;
+    }
+
+    public void setTomcatScanning(final boolean tomcatScanning) {
+        this.tomcatScanning = tomcatScanning;
+    }
+
+    public List<File> getModules() {
+        return modules;
+    }
+
+    public void setModules(final List<File> modules) {
+        this.modules = modules;
+    }
+
+    public Collection<String> getApplicationScopes() {
+        return applicationScopes;
+    }
+
+    public void setApplicationScopes(final Collection<String> applicationScopes) {
+        this.applicationScopes = applicationScopes;
+    }
+
+    public Collection<String> getClassloaderFilteredPackages() {
+        return classloaderFilteredPackages;
+    }
+
+    public void setClassloaderFilteredPackages(final Collection<String> classloaderFilteredPackages) {
+        this.classloaderFilteredPackages = classloaderFilteredPackages;
+    }
+
+    public String getContext() {
+        return context;
+    }
+
+    public void setContext(final String context) {
+        this.context = context;
+    }
+
+    public File getWebapp() {
+        return webapp;
+    }
+
+    public void setWebapp(final File webapp) {
+        this.webapp = webapp;
+    }
+
+    public boolean isTomcatAutoSetup() {
+        return tomcatAutoSetup;
+    }
+
+    public void setTomcatAutoSetup(final boolean tomcatAutoSetup) {
+        this.tomcatAutoSetup = tomcatAutoSetup;
+    }
+
+    public boolean isUseShutdownHook() {
+        return useShutdownHook;
+    }
+
+    public void setUseShutdownHook(final boolean useShutdownHook) {
+        this.useShutdownHook = useShutdownHook;
+    }
+
+    public String getTomcatFilter() {
+        return tomcatFilter;
+    }
+
+    public void setTomcatFilter(final String tomcatFilter) {
+        this.tomcatFilter = tomcatFilter;
+    }
+
+    public boolean isUseTomcatDefaults() {
+        return useTomcatDefaults;
+    }
+
+    public void setUseTomcatDefaults(final boolean useTomcatDefaults) {
+        this.useTomcatDefaults = useTomcatDefaults;
+    }
+
+    public boolean isJaxrsLogProviders() {
+        return jaxrsLogProviders;
+    }
+
+    public void setJaxrsLogProviders(final boolean jaxrsLogProviders) {
+        this.jaxrsLogProviders = jaxrsLogProviders;
+    }
+
+    public boolean isTomcatWrapLoader() {
+        return tomcatWrapLoader;
+    }
+
+    public void setTomcatWrapLoader(final boolean tomcatWrapLoader) {
+        this.tomcatWrapLoader = tomcatWrapLoader;
+    }
+
+    public String getJaxrsDefaultProviders() {
+        return jaxrsDefaultProviders;
+    }
+
+    public void setJaxrsDefaultProviders(final String jaxrsDefaultProviders) {
+        this.jaxrsDefaultProviders = jaxrsDefaultProviders;
+    }
+
+    public String getSharedLibraries() {
+        return sharedLibraries;
+    }
+
+    public void setSharedLibraries(final String sharedLibraries) {
+        this.sharedLibraries = sharedLibraries;
+    }
+
+    public boolean isUseLog4j2JulLogManager() {
+        return useLog4j2JulLogManager;
+    }
+
+    public void setUseLog4j2JulLogManager(final boolean useLog4j2JulLogManager) {
+        this.useLog4j2JulLogManager = useLog4j2JulLogManager;
+    }
+}

Added: openwebbeans/microwave/trunk/meecrowave-gradle-plugin/src/main/java/org/apache/meecrowave/gradle/classloader/FilterGradleClassLoader.java
URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/meecrowave-gradle-plugin/src/main/java/org/apache/meecrowave/gradle/classloader/FilterGradleClassLoader.java?rev=1769479&view=auto
==============================================================================
--- openwebbeans/microwave/trunk/meecrowave-gradle-plugin/src/main/java/org/apache/meecrowave/gradle/classloader/FilterGradleClassLoader.java (added)
+++ openwebbeans/microwave/trunk/meecrowave-gradle-plugin/src/main/java/org/apache/meecrowave/gradle/classloader/FilterGradleClassLoader.java Sun Nov 13 09:34:07 2016
@@ -0,0 +1,142 @@
+/*
+ * 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.meecrowave.gradle.classloader;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.Collection;
+import java.util.Enumeration;
+
+import static java.util.Collections.emptyEnumeration;
+
+public class FilterGradleClassLoader extends ClassLoader {
+    private final ClassLoader delegate;
+    private final Collection<String> filtered;
+
+    public FilterGradleClassLoader(final ClassLoader gradle, final Collection<String> filtered) {
+        super(gradle.getParent());
+        this.delegate = gradle;
+        this.filtered = filtered;
+    }
+
+    @Override
+    public Class<?> loadClass(final String name) throws ClassNotFoundException {
+        checkClass(name);
+        return delegate.loadClass(name);
+    }
+
+    @Override
+    public Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
+        return loadClass(name);
+    }
+
+    @Override
+    public URL getResource(final String name) {
+        if (!checkResource(name)) {
+            return null;
+        }
+        return delegate.getResource(name);
+    }
+
+    @Override
+    public Enumeration<URL> getResources(final String name) throws IOException {
+        final Enumeration<URL> resources = delegate.getResources(name);
+        if (!checkResource(name)) {
+            return emptyEnumeration();
+        }
+        return resources;
+    }
+
+    @Override
+    public InputStream getResourceAsStream(final String name) {
+        if (!checkResource(name)) {
+            return null;
+        }
+        return delegate.getResourceAsStream(name);
+    }
+
+    private void checkClass(final String name) throws ClassNotFoundException { // let slf4j+gradle go to reuse it
+        if (name != null && (
+                name.startsWith("aQute") ||
+                        name.startsWith("bsh") ||
+                        name.startsWith("com.amazon") ||
+                        name.startsWith("com.beust") ||
+                        name.startsWith("com.esot") ||
+                        name.startsWith("com.google") ||
+                        name.startsWith("com.jackson") ||
+                        name.startsWith("com.jcraft") ||
+                        name.startsWith("com.tonixsystems") ||
+                        name.startsWith("javax.el") ||
+                        name.startsWith("javax.inject") ||
+                        name.startsWith("javax.servlet") ||
+                        name.startsWith("jcifs.") ||
+                        name.startsWith("junit.") ||
+                        name.startsWith("groovy") ||
+                        name.startsWith("mozilla.") ||
+                        name.startsWith("net.jcip.") ||
+                        name.startsWith("net.ruby") ||
+                        name.startsWith("org.apache.") ||
+                        name.startsWith("org.bouncycastle.") ||
+                        name.startsWith("org.codehaus.") ||
+                        name.startsWith("org.cyber") ||
+                        name.startsWith("org.dom4j.") ||
+                        name.startsWith("org.eclipse.") ||
+                        name.startsWith("org.fusesource.") ||
+                        name.startsWith("org.hamcrest.") ||
+                        name.startsWith("org.jaxen.") ||
+                        name.startsWith("org.mortbay.") ||
+                        name.startsWith("org.mozilla.") ||
+                        name.startsWith("org.objectweb.") ||
+                        name.startsWith("org.objenesis.") ||
+                        name.startsWith("org.osgi.") ||
+                        name.startsWith("org.simpleframework.") ||
+                        name.startsWith("org.sonar.") ||
+                        name.startsWith("org.sonatype.") ||
+                        name.startsWith("org.testng.") ||
+                        name.startsWith("org.yaml.") ||
+                        isForbiddenGradleClass(name) ||
+                        isFiltered(name)
+        )) {
+            throw new ClassNotFoundException();
+        }
+    }
+
+    private boolean isFiltered(final String name) {
+        if (filtered == null || name == null) {
+            return false;
+        }
+        for (final String pck : filtered) {
+            if (name.startsWith(pck)) {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private boolean isForbiddenGradleClass(final String name) { // we need logging classes but we don't want to scan gradle
+        return name.startsWith("org.gradle.initialization") || name.startsWith("org.gradle.launcher")
+                || name.startsWith("org.gradle.execution") || name.startsWith("org.gradle.internal")
+                || name.startsWith("org.gradle.tooling") || name.startsWith("org.gradle.api.internal.tasks")
+                || name.startsWith("org.gradle.util") || name.startsWith("org.gradle.wrapper");
+    }
+
+    private boolean checkResource(final String name) {
+        return name != null && !name.startsWith("META-INF/services/com.fasterxml");
+    }
+}
+

Added: openwebbeans/microwave/trunk/meecrowave-gradle-plugin/src/main/resources/META-INF/LICENSE
URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/meecrowave-gradle-plugin/src/main/resources/META-INF/LICENSE?rev=1769479&view=auto
==============================================================================
--- openwebbeans/microwave/trunk/meecrowave-gradle-plugin/src/main/resources/META-INF/LICENSE (added)
+++ openwebbeans/microwave/trunk/meecrowave-gradle-plugin/src/main/resources/META-INF/LICENSE Sun Nov 13 09:34:07 2016
@@ -0,0 +1,201 @@
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

Added: openwebbeans/microwave/trunk/meecrowave-gradle-plugin/src/main/resources/META-INF/NOTICE
URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/meecrowave-gradle-plugin/src/main/resources/META-INF/NOTICE?rev=1769479&view=auto
==============================================================================
--- openwebbeans/microwave/trunk/meecrowave-gradle-plugin/src/main/resources/META-INF/NOTICE (added)
+++ openwebbeans/microwave/trunk/meecrowave-gradle-plugin/src/main/resources/META-INF/NOTICE Sun Nov 13 09:34:07 2016
@@ -0,0 +1,5 @@
+Apache Microwave
+Copyright 2016 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).

Added: openwebbeans/microwave/trunk/meecrowave-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.apache.microwave.microwave.properties
URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/meecrowave-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.apache.microwave.microwave.properties?rev=1769479&view=auto
==============================================================================
--- openwebbeans/microwave/trunk/meecrowave-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.apache.microwave.microwave.properties (added)
+++ openwebbeans/microwave/trunk/meecrowave-gradle-plugin/src/main/resources/META-INF/gradle-plugins/org.apache.microwave.microwave.properties Sun Nov 13 09:34:07 2016
@@ -0,0 +1,17 @@
+#
+# 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.
+#
+implementation-class=org.apache.meecrowave.gradle.MeecrowavePlugin

Added: openwebbeans/microwave/trunk/meecrowave-jpa/pom.xml
URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/meecrowave-jpa/pom.xml?rev=1769479&view=auto
==============================================================================
--- openwebbeans/microwave/trunk/meecrowave-jpa/pom.xml (added)
+++ openwebbeans/microwave/trunk/meecrowave-jpa/pom.xml Sun Nov 13 09:34:07 2016
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+    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.
+-->
+<project xmlns="http://maven.apache.org/POM/4.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="
+            http://maven.apache.org/POM/4.0.0
+            http://maven.apache.org/xsd/maven-4.0.0.xsd">
+  <parent>
+    <artifactId>meecrowave</artifactId>
+    <groupId>org.apache.meecrowave</groupId>
+    <version>0.0.1-SNAPSHOT</version>
+  </parent>
+  <modelVersion>4.0.0</modelVersion>
+
+  <artifactId>meecrowave-jpa</artifactId>
+  <name>Meecrowave :: JPA</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-jpa_2.1_spec</artifactId>
+      <version>1.0-alpha-1</version>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.meecrowave</groupId>
+      <artifactId>meecrowave-core</artifactId>
+      <version>${project.version}</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.openjpa</groupId>
+      <artifactId>openjpa</artifactId>
+      <version>2.4.1</version>
+    </dependency>
+
+    <dependency>
+      <groupId>org.apache.meecrowave</groupId>
+      <artifactId>meecrowave-junit</artifactId>
+      <version>${project.version}</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>com.h2database</groupId>
+      <artifactId>h2</artifactId>
+      <version>1.4.192</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons</groupId>
+      <artifactId>commons-dbcp2</artifactId>
+      <version>2.1</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>
\ No newline at end of file

Added: openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/EntityManagerScoped.java
URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/EntityManagerScoped.java?rev=1769479&view=auto
==============================================================================
--- openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/EntityManagerScoped.java (added)
+++ openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/EntityManagerScoped.java Sun Nov 13 09:34:07 2016
@@ -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.meecrowave.jpa.api;
+
+import javax.enterprise.context.NormalScope;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@NormalScope
+@Target({METHOD, TYPE})
+@Retention(RUNTIME)
+public @interface EntityManagerScoped {
+}

Added: openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/Jpa.java
URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/Jpa.java?rev=1769479&view=auto
==============================================================================
--- openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/Jpa.java (added)
+++ openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/Jpa.java Sun Nov 13 09:34:07 2016
@@ -0,0 +1,34 @@
+/*
+ * 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.meecrowave.jpa.api;
+
+import javax.interceptor.InterceptorBinding;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@InterceptorBinding
+@Target({METHOD, TYPE})
+@Retention(RUNTIME)
+public @interface Jpa {
+    boolean transactional() default true;
+}

Added: openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/PersistenceUnitInfoBuilder.java
URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/PersistenceUnitInfoBuilder.java?rev=1769479&view=auto
==============================================================================
--- openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/PersistenceUnitInfoBuilder.java (added)
+++ openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/PersistenceUnitInfoBuilder.java Sun Nov 13 09:34:07 2016
@@ -0,0 +1,284 @@
+/*
+ * 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.meecrowave.jpa.api;
+
+import javax.enterprise.inject.Vetoed;
+import javax.persistence.SharedCacheMode;
+import javax.persistence.ValidationMode;
+import javax.persistence.spi.ClassTransformer;
+import javax.persistence.spi.PersistenceProvider;
+import javax.persistence.spi.PersistenceUnitInfo;
+import javax.persistence.spi.PersistenceUnitTransactionType;
+import javax.sql.DataSource;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.ServiceLoader;
+
+import static java.util.Collections.emptyList;
+import static java.util.Objects.requireNonNull;
+import static java.util.stream.Collectors.toList;
+import static javax.persistence.spi.PersistenceUnitTransactionType.RESOURCE_LOCAL;
+
+@Vetoed
+public class PersistenceUnitInfoBuilder {
+    private String unitName;
+    private String providerClass;
+    private DataSource dataSource;
+    private List<String> mappingFiles = emptyList();
+    private List<URL> jarFiles = emptyList();
+    private URL rootUrl;
+    private List<String> managedClasses = new ArrayList<>();
+    private boolean excludeUnlistedClasses;
+    private SharedCacheMode sharedCacheMode = SharedCacheMode.UNSPECIFIED;
+    private ValidationMode validationMode = ValidationMode.AUTO;
+    private Properties properties = new Properties();
+    private String version = "2.0";
+    private ClassLoader loader = Thread.currentThread().getContextClassLoader();
+
+    public String getUnitName() {
+        return unitName;
+    }
+
+    public PersistenceUnitInfoBuilder setUnitName(final String unitName) {
+        this.unitName = unitName;
+        return this;
+    }
+
+    public String getProviderClass() {
+        return providerClass;
+    }
+
+    public PersistenceUnitInfoBuilder setProviderClass(final String providerClass) {
+        this.providerClass = providerClass;
+        return this;
+    }
+
+    public DataSource getDataSource() {
+        return dataSource;
+    }
+
+    public PersistenceUnitInfoBuilder setDataSource(final DataSource dataSource) {
+        this.dataSource = dataSource;
+        return this;
+    }
+
+    public List<String> getMappingFiles() {
+        return mappingFiles;
+    }
+
+    public PersistenceUnitInfoBuilder setMappingFiles(final List<String> mappingFiles) {
+        this.mappingFiles = mappingFiles;
+        return this;
+    }
+
+    public List<URL> getJarFiles() {
+        return jarFiles;
+    }
+
+    public PersistenceUnitInfoBuilder setJarFiles(final List<URL> jarFiles) {
+        this.jarFiles = jarFiles;
+        return this;
+    }
+
+    public URL getRootUrl() {
+        return rootUrl;
+    }
+
+    public PersistenceUnitInfoBuilder setRootUrl(final URL rootUrl) {
+        this.rootUrl = rootUrl;
+        return this;
+    }
+
+    public List<String> getManagedClasses() {
+        return managedClasses;
+    }
+
+    public PersistenceUnitInfoBuilder addManagedClazz(final Class<?> clazz) {
+        managedClasses.add(clazz.getName());
+        return this;
+    }
+
+    public PersistenceUnitInfoBuilder setManagedClassNames(final List<String> managedClasses) {
+        this.managedClasses = managedClasses;
+        return this;
+    }
+
+    public PersistenceUnitInfoBuilder setManagedClasses(final List<Class<?>> managedClasses) {
+        this.managedClasses = managedClasses.stream().map(Class::getName).collect(toList());
+        return this;
+    }
+
+    public boolean isExcludeUnlistedClasses() {
+        return excludeUnlistedClasses;
+    }
+
+    public PersistenceUnitInfoBuilder setExcludeUnlistedClasses(final boolean excludeUnlistedClasses) {
+        this.excludeUnlistedClasses = excludeUnlistedClasses;
+        return this;
+    }
+
+    public SharedCacheMode getSharedCacheMode() {
+        return sharedCacheMode;
+    }
+
+    public PersistenceUnitInfoBuilder setSharedCacheMode(final SharedCacheMode sharedCacheMode) {
+        this.sharedCacheMode = sharedCacheMode;
+        return this;
+    }
+
+    public ValidationMode getValidationMode() {
+        return validationMode;
+    }
+
+    public PersistenceUnitInfoBuilder setValidationMode(final ValidationMode validationMode) {
+        this.validationMode = validationMode;
+        return this;
+    }
+
+    public Properties getProperties() {
+        return properties;
+    }
+
+    public PersistenceUnitInfoBuilder addProperty(final String key, final String value) {
+        if (properties == null) {
+            properties = new Properties();
+        }
+        properties.setProperty(key, value);
+        return this;
+    }
+
+    public PersistenceUnitInfoBuilder setProperties(final Properties properties) {
+        this.properties = properties;
+        return this;
+    }
+
+    public String getVersion() {
+        return version;
+    }
+
+    public PersistenceUnitInfoBuilder setVersion(final String version) {
+        this.version = version;
+        return this;
+    }
+
+    public ClassLoader getLoader() {
+        return loader;
+    }
+
+    public PersistenceUnitInfoBuilder setLoader(final ClassLoader loader) {
+        this.loader = loader;
+        return this;
+    }
+
+    public PersistenceUnitInfo toInfo() {
+        if (providerClass == null) {
+            providerClass = ServiceLoader.load(PersistenceProvider.class).iterator().next().getClass().getName();
+        }
+        requireNonNull(dataSource, "datasource not provided");
+        return new PersistenceUnitInfo() {
+            @Override
+            public String getPersistenceUnitName() {
+                return unitName;
+            }
+
+            @Override
+            public String getPersistenceProviderClassName() {
+                return providerClass;
+            }
+
+            @Override
+            public PersistenceUnitTransactionType getTransactionType() {
+                return RESOURCE_LOCAL;
+            }
+
+            @Override
+            public DataSource getJtaDataSource() {
+                return null;
+            }
+
+            @Override
+            public DataSource getNonJtaDataSource() {
+                return dataSource;
+            }
+
+            @Override
+            public List<String> getMappingFileNames() {
+                return mappingFiles;
+            }
+
+            @Override
+            public List<URL> getJarFileUrls() {
+                return jarFiles;
+            }
+
+            @Override
+            public URL getPersistenceUnitRootUrl() {
+                return rootUrl;
+            }
+
+            @Override
+            public List<String> getManagedClassNames() {
+                return managedClasses;
+            }
+
+            @Override
+            public boolean excludeUnlistedClasses() {
+                return excludeUnlistedClasses;
+            }
+
+            @Override
+            public SharedCacheMode getSharedCacheMode() {
+                return sharedCacheMode;
+            }
+
+            @Override
+            public ValidationMode getValidationMode() {
+                return validationMode;
+            }
+
+            @Override
+            public Properties getProperties() {
+                return properties;
+            }
+
+            @Override
+            public String getPersistenceXMLSchemaVersion() {
+                return version;
+            }
+
+            @Override
+            public ClassLoader getClassLoader() {
+                return loader;
+            }
+
+            @Override
+            public void addTransformer(final ClassTransformer transformer) {
+                // no-op: not supported
+            }
+
+            @Override
+            public ClassLoader getNewTempClassLoader() {
+                return new URLClassLoader(new URL[0], Thread.currentThread().getContextClassLoader());
+            }
+        };
+    }
+}

Added: openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/Unit.java
URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/Unit.java?rev=1769479&view=auto
==============================================================================
--- openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/Unit.java (added)
+++ openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/api/Unit.java Sun Nov 13 09:34:07 2016
@@ -0,0 +1,37 @@
+/*
+ * 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.meecrowave.jpa.api;
+
+import javax.inject.Qualifier;
+import javax.persistence.SynchronizationType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.ElementType.METHOD;
+import static java.lang.annotation.ElementType.PARAMETER;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+@Qualifier
+@Target({FIELD, METHOD, PARAMETER})
+@Retention(RUNTIME)
+public @interface Unit {
+    String name();
+    SynchronizationType synchronization() default SynchronizationType.SYNCHRONIZED;
+}

Added: openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/internal/AnyLiteral.java
URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/internal/AnyLiteral.java?rev=1769479&view=auto
==============================================================================
--- openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/internal/AnyLiteral.java (added)
+++ openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/internal/AnyLiteral.java Sun Nov 13 09:34:07 2016
@@ -0,0 +1,51 @@
+/*
+ * 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.meecrowave.jpa.internal;
+
+import javax.enterprise.inject.Any;
+import javax.enterprise.util.AnnotationLiteral;
+import java.lang.annotation.Annotation;
+
+public class AnyLiteral extends AnnotationLiteral<Any> implements Any {
+    public static final AnyLiteral INSTANCE = new AnyLiteral();
+
+    private static final String TOSTRING = "@javax.enterprise.inject.Any()";
+    private static final long serialVersionUID = -8922048102786275371L;
+
+    @Override
+    public Class<? extends Annotation> annotationType() {
+        return Any.class;
+    }
+
+    @Override
+    public boolean equals(final Object other) {
+        return Any.class.isInstance(other)
+                || (AnnotationLiteral.class.isInstance(other) && AnnotationLiteral.class.cast(other).annotationType() == annotationType());
+    }
+
+    @Override
+    public int hashCode() {
+        return 0;
+    }
+
+    @Override
+    public String toString() {
+        return TOSTRING;
+    }
+}

Added: openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/internal/AutoJpaAnnotationType.java
URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/internal/AutoJpaAnnotationType.java?rev=1769479&view=auto
==============================================================================
--- openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/internal/AutoJpaAnnotationType.java (added)
+++ openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/internal/AutoJpaAnnotationType.java Sun Nov 13 09:34:07 2016
@@ -0,0 +1,88 @@
+/*
+ * 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.meecrowave.jpa.internal;
+
+import org.apache.meecrowave.jpa.api.Jpa;
+
+import javax.enterprise.inject.spi.AnnotatedConstructor;
+import javax.enterprise.inject.spi.AnnotatedField;
+import javax.enterprise.inject.spi.AnnotatedMethod;
+import javax.enterprise.inject.spi.AnnotatedType;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.HashSet;
+import java.util.Set;
+
+import static java.util.Optional.ofNullable;
+
+class AutoJpaAnnotationType<T> implements AnnotatedType<T> {
+    private final AnnotatedType<T> delegate;
+    private final Set<Annotation> annotations = new HashSet<>();
+
+    AutoJpaAnnotationType(final AnnotatedType<T> delegate) {
+        this.delegate = delegate;
+        this.annotations.addAll(delegate.getAnnotations());
+        this.annotations.add(JpaLiteral.DEFAULT);
+    }
+
+    @Override
+    public Class<T> getJavaClass() {
+        return delegate.getJavaClass();
+    }
+
+    @Override
+    public Set<AnnotatedConstructor<T>> getConstructors() {
+        return delegate.getConstructors();
+    }
+
+    @Override
+    public Set<AnnotatedMethod<? super T>> getMethods() {
+        return delegate.getMethods();
+    }
+
+    @Override
+    public Set<AnnotatedField<? super T>> getFields() {
+        return delegate.getFields();
+    }
+
+    @Override
+    public Type getBaseType() {
+        return delegate.getBaseType();
+    }
+
+    @Override
+    public Set<Type> getTypeClosure() {
+        return delegate.getTypeClosure();
+    }
+
+    @Override
+    public <T extends Annotation> T getAnnotation(final Class<T> annotationType) {
+        return ofNullable(delegate.getAnnotation(annotationType)).orElseGet(() -> annotationType == Jpa.class ? (T) JpaLiteral.DEFAULT : null);
+    }
+
+    @Override
+    public Set<Annotation> getAnnotations() {
+        return annotations;
+    }
+
+    @Override
+    public boolean isAnnotationPresent(final Class<? extends Annotation> annotationType) {
+        return delegate.isAnnotationPresent(annotationType) || annotationType == Jpa.class;
+    }
+}

Added: openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/internal/EntityManagerBean.java
URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/internal/EntityManagerBean.java?rev=1769479&view=auto
==============================================================================
--- openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/internal/EntityManagerBean.java (added)
+++ openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/internal/EntityManagerBean.java Sun Nov 13 09:34:07 2016
@@ -0,0 +1,148 @@
+package org.apache.meecrowave.jpa.internal;
+
+import org.apache.meecrowave.jpa.api.EntityManagerScoped;
+
+import javax.enterprise.context.spi.CreationalContext;
+import javax.enterprise.inject.Vetoed;
+import javax.enterprise.inject.spi.Bean;
+import javax.enterprise.inject.spi.BeanManager;
+import javax.enterprise.inject.spi.InjectionPoint;
+import javax.enterprise.inject.spi.PassivationCapable;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.SynchronizationType;
+import javax.persistence.ValidationMode;
+import javax.persistence.spi.PersistenceProvider;
+import javax.persistence.spi.PersistenceUnitInfo;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.function.Supplier;
+
+import static java.util.Arrays.asList;
+import static java.util.Collections.emptySet;
+import static java.util.Collections.singletonList;
+import static java.util.Optional.ofNullable;
+
+@Vetoed
+public class EntityManagerBean implements Bean<EntityManager>, PassivationCapable {
+    private final Set<Type> types = new HashSet<>(singletonList(EntityManager.class));
+    private final Set<Annotation> qualifiers = new HashSet<>();
+    private final EntityManagerContext entityManagerContext;
+    private final SynchronizationType synchronization;
+    private final String id;
+    private Supplier<EntityManager> instanceFactory;
+
+    EntityManagerBean(final EntityManagerContext context, final String name, final SynchronizationType synchronization) {
+        this.entityManagerContext = context;
+        this.qualifiers.addAll(asList(new UnitLiteral(name, synchronization), AnyLiteral.INSTANCE));
+        this.id = "meecrowave::jpa::entitymanager::" + name + "/" + synchronization.name();
+        this.synchronization = synchronization;
+    }
+
+    void init(final PersistenceUnitInfo info, final BeanManager bm) {
+        final PersistenceProvider provider;
+        try {
+            provider = PersistenceProvider.class.cast(
+                    Thread.currentThread().getContextClassLoader().loadClass(info.getPersistenceProviderClassName()).newInstance());
+        } catch (final InstantiationException | IllegalAccessException | ClassNotFoundException e) {
+            throw new IllegalArgumentException("Bad provider: " + info.getPersistenceProviderClassName());
+        }
+        final EntityManagerFactory factory = provider.createContainerEntityManagerFactory(info, new HashMap() {{
+            put("javax.persistence.bean.manager", bm);
+            if (ValidationMode.NONE != info.getValidationMode()) {
+                ofNullable(findValidatorFactory(bm)).ifPresent(factory -> put("javax.persistence.validation.factory", factory));
+            }
+        }});
+        instanceFactory = synchronization == SynchronizationType.SYNCHRONIZED ? factory::createEntityManager : () -> factory.createEntityManager(synchronization);
+    }
+
+    private Object findValidatorFactory(final BeanManager bm) {
+        try {
+            final Class<?> type = Thread.currentThread().getContextClassLoader().loadClass("javax.validation.ValidatorFactory");
+            final Bean<?> bean = bm.resolve(bm.getBeans(type));
+            if (bean == null || !bm.isNormalScope(bean.getScope())) {
+                return null;
+            }
+            return bm.getReference(bean, type, bm.createCreationalContext(null));
+        } catch (final NoClassDefFoundError | ClassNotFoundException e) {
+            return null;
+        }
+    }
+
+    @Override
+    public EntityManager create(final CreationalContext<EntityManager> context) {
+        final EntityManager entityManager = instanceFactory.get();
+        if (entityManagerContext.isTransactional()) {
+            entityManager.getTransaction().begin();
+        }
+        return entityManager;
+    }
+
+    @Override
+    public void destroy(final EntityManager instance, final CreationalContext<EntityManager> context) {
+        try {
+            if (entityManagerContext.isTransactional()) {
+                if (entityManagerContext.hasFailed()) {
+                    instance.getTransaction().rollback();
+                } else {
+                    instance.getTransaction().commit();
+                }
+            }
+        } finally {
+            instance.close();
+        }
+    }
+
+    @Override
+    public Set<InjectionPoint> getInjectionPoints() {
+        return emptySet();
+    }
+
+    @Override
+    public Class<?> getBeanClass() {
+        return EntityManager.class;
+    }
+
+    @Override
+    public boolean isNullable() {
+        return false;
+    }
+
+    @Override
+    public Set<Type> getTypes() {
+        return types;
+    }
+
+    @Override
+    public Set<Annotation> getQualifiers() {
+        return qualifiers;
+    }
+
+    @Override
+    public Class<? extends Annotation> getScope() {
+        return EntityManagerScoped.class;
+    }
+
+    @Override
+    public String getName() {
+        return null;
+    }
+
+    @Override
+    public Set<Class<? extends Annotation>> getStereotypes() {
+        return emptySet();
+    }
+
+    @Override
+    public boolean isAlternative() {
+        return false;
+    }
+
+    @Override
+    public String getId() {
+        return id;
+    }
+}

Added: openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/internal/EntityManagerContext.java
URL: http://svn.apache.org/viewvc/openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/internal/EntityManagerContext.java?rev=1769479&view=auto
==============================================================================
--- openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/internal/EntityManagerContext.java (added)
+++ openwebbeans/microwave/trunk/meecrowave-jpa/src/main/java/org/apache/meecrowave/jpa/internal/EntityManagerContext.java Sun Nov 13 09:34:07 2016
@@ -0,0 +1,152 @@
+/*
+ * 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.meecrowave.jpa.internal;
+
+import org.apache.meecrowave.jpa.api.EntityManagerScoped;
+
+import javax.enterprise.context.spi.AlterableContext;
+import javax.enterprise.context.spi.Contextual;
+import javax.enterprise.context.spi.CreationalContext;
+import java.io.Serializable;
+import java.lang.annotation.Annotation;
+import java.util.HashMap;
+import java.util.Map;
+
+import static java.util.Optional.ofNullable;
+
+public class EntityManagerContext implements AlterableContext {
+    private final ThreadLocal<ThreadContext> context = new ThreadLocal<>();
+
+    public boolean enter(final boolean transactional) {
+        if (context.get() != null) {
+            return false;
+        }
+        final ThreadContext value = new ThreadContext();
+        value.transactional = transactional;
+        context.set(value);
+        return true;
+    }
+
+    public void failed() {
+        context.get().failed = true;
+    }
+
+    public void exit(final boolean created) {
+        if (created) {
+            context.get().exit();
+            context.remove();
+        }
+    }
+
+    @Override
+    public Class<? extends Annotation> getScope() {
+        return EntityManagerScoped.class;
+    }
+
+    @Override
+    public void destroy(final Contextual<?> contextual) {
+        context.get().destroy(contextual);
+    }
+
+    @Override
+    public <T> T get(final Contextual<T> component, final CreationalContext<T> creationalContext) {
+        return context.get().get(component, creationalContext);
+    }
+
+    @Override
+    public <T> T get(final Contextual<T> component) {
+        return context.get().get(component);
+    }
+
+    @Override
+    public boolean isActive() {
+        final boolean active = context.get() != null;
+        if (!active) {
+            context.remove();
+        }
+        return active;
+    }
+
+    public boolean hasFailed() {
+        return context.get().failed;
+    }
+
+    public boolean isTransactional() {
+        return context.get().transactional;
+    }
+
+    private static class ThreadContext implements AlterableContext {
+        private final Map<Contextual<?>, BeanInstanceBag<?>> components = new HashMap<>();
+        private boolean failed;
+        private boolean transactional;
+
+        @Override
+        public Class<? extends Annotation> getScope() {
+            return EntityManagerScoped.class;
+        }
+
+        @Override
+        public <T> T get(final Contextual<T> component, final CreationalContext<T> creationalContext) {
+            BeanInstanceBag<T> bag = (BeanInstanceBag<T>) components.get(component);
+            if (bag == null) {
+                bag = new BeanInstanceBag<>(creationalContext);
+                components.put(component, bag);
+            }
+            if (bag.beanInstance == null) {
+                bag.beanInstance = component.create(creationalContext);
+            }
+            return bag.beanInstance;
+        }
+
+        @Override
+        public <T> T get(final Contextual<T> component) {
+            final BeanInstanceBag<?> bag = components.get(component);
+            return bag == null ? null : (T) bag.beanInstance;
+        }
+
+        @Override
+        public void destroy(final Contextual<?> contextual) {
+            final BeanInstanceBag remove = components.remove(contextual);
+            ofNullable(remove).ifPresent(b -> doDestroy(contextual, b));
+        }
+
+        private <T> void doDestroy(final Contextual<T> contextual, final BeanInstanceBag<T> bag) {
+            contextual.destroy(bag.beanInstance, bag.beanCreationalContext);
+            bag.beanCreationalContext.release();
+        }
+
+        @Override
+        public boolean isActive() {
+            return true;
+        }
+
+        private void exit() {
+            components.forEach((k, bag) -> doDestroy(k, BeanInstanceBag.class.cast(bag)));
+        }
+    }
+
+    private static class BeanInstanceBag<T> implements Serializable {
+        private final CreationalContext<T> beanCreationalContext;
+        private T beanInstance;
+
+        private BeanInstanceBag(final CreationalContext<T> beanCreationalContext) {
+            this.beanCreationalContext = beanCreationalContext;
+        }
+    }
+}



Mime
View raw message