You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by rm...@apache.org on 2013/10/22 11:07:49 UTC

svn commit: r1534546 - in /commons/sandbox/monitoring/trunk: ./ aop/src/main/java/org/apache/commons/monitoring/aop/ core/src/main/java/org/apache/commons/monitoring/counters/ jdbc/ jpa/ jpa/src/ jpa/src/main/ jpa/src/main/java/ jpa/src/main/java/org/ ...

Author: rmannibucau
Date: Tue Oct 22 09:07:48 2013
New Revision: 1534546

URL: http://svn.apache.org/r1534546
Log:
adding jpa module - doc todo

Added:
    commons/sandbox/monitoring/trunk/jpa/
    commons/sandbox/monitoring/trunk/jpa/pom.xml
    commons/sandbox/monitoring/trunk/jpa/src/
    commons/sandbox/monitoring/trunk/jpa/src/main/
    commons/sandbox/monitoring/trunk/jpa/src/main/java/
    commons/sandbox/monitoring/trunk/jpa/src/main/java/org/
    commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/
    commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/
    commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/
    commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/
    commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/JPAProxyFactory.java
    commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/MonitoringPersistence.java
    commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/OverridePersistenceXmlClassLoader.java
    commons/sandbox/monitoring/trunk/jpa/src/main/resources/
    commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/
    commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/services/
    commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/services/javax.persistence.spi.PersistenceProvider
    commons/sandbox/monitoring/trunk/jpa/src/test/
    commons/sandbox/monitoring/trunk/jpa/src/test/java/
    commons/sandbox/monitoring/trunk/jpa/src/test/java/org/
    commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/
    commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/
    commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/
    commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/
    commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/EMFTest.java
    commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/QueryTest.java
    commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/
    commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Address.java
    commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Person.java
    commons/sandbox/monitoring/trunk/jpa/src/test/resources/
    commons/sandbox/monitoring/trunk/jpa/src/test/resources/META-INF/
    commons/sandbox/monitoring/trunk/jpa/src/test/resources/META-INF/persistence.xml
Modified:
    commons/sandbox/monitoring/trunk/aop/src/main/java/org/apache/commons/monitoring/aop/AbstractPerformanceInterceptor.java
    commons/sandbox/monitoring/trunk/core/src/main/java/org/apache/commons/monitoring/counters/DefaultCounter.java
    commons/sandbox/monitoring/trunk/jdbc/pom.xml
    commons/sandbox/monitoring/trunk/pom.xml

Modified: commons/sandbox/monitoring/trunk/aop/src/main/java/org/apache/commons/monitoring/aop/AbstractPerformanceInterceptor.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/aop/src/main/java/org/apache/commons/monitoring/aop/AbstractPerformanceInterceptor.java?rev=1534546&r1=1534545&r2=1534546&view=diff
==============================================================================
--- commons/sandbox/monitoring/trunk/aop/src/main/java/org/apache/commons/monitoring/aop/AbstractPerformanceInterceptor.java (original)
+++ commons/sandbox/monitoring/trunk/aop/src/main/java/org/apache/commons/monitoring/aop/AbstractPerformanceInterceptor.java Tue Oct 22 09:07:48 2013
@@ -51,7 +51,7 @@ public abstract class AbstractPerformanc
             return proceed(invocation);
         }
 
-        final Counter monitor = Repository.INSTANCE.getCounter(new Counter.Key(Role.PERFORMANCES, name));
+        final Counter monitor = Repository.INSTANCE.getCounter(new Counter.Key(getRole(), name));
         final StopWatch stopwatch = Repository.INSTANCE.start(monitor);
         Throwable error = null;
         try {
@@ -69,6 +69,10 @@ public abstract class AbstractPerformanc
         }
     }
 
+    protected Role getRole() {
+        return Role.PERFORMANCES;
+    }
+
     protected abstract Object proceed(T invocation) throws Throwable;
 
     protected abstract String getCounterName(T invocation);

Modified: commons/sandbox/monitoring/trunk/core/src/main/java/org/apache/commons/monitoring/counters/DefaultCounter.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/core/src/main/java/org/apache/commons/monitoring/counters/DefaultCounter.java?rev=1534546&r1=1534545&r2=1534546&view=diff
==============================================================================
--- commons/sandbox/monitoring/trunk/core/src/main/java/org/apache/commons/monitoring/counters/DefaultCounter.java (original)
+++ commons/sandbox/monitoring/trunk/core/src/main/java/org/apache/commons/monitoring/counters/DefaultCounter.java Tue Oct 22 09:07:48 2013
@@ -171,4 +171,15 @@ public class DefaultCounter implements C
     public ReadWriteLock getLock() {
         return lock;
     }
+
+    @Override
+    public String toString() {
+        return "DefaultCounter{" +
+            "concurrency=" + concurrency +
+            ", key=" + key +
+            ", dataStore=" + dataStore +
+            ", maxConcurrency=" + maxConcurrency +
+            ", statistics=" + statistics +
+            '}';
+    }
 }

Modified: commons/sandbox/monitoring/trunk/jdbc/pom.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jdbc/pom.xml?rev=1534546&r1=1534545&r2=1534546&view=diff
==============================================================================
--- commons/sandbox/monitoring/trunk/jdbc/pom.xml (original)
+++ commons/sandbox/monitoring/trunk/jdbc/pom.xml Tue Oct 22 09:07:48 2013
@@ -42,8 +42,6 @@
     <dependency>
       <groupId>org.hsqldb</groupId>
       <artifactId>hsqldb</artifactId>
-      <version>2.2.9</version>
-      <scope>test</scope>
     </dependency>
     <dependency>
       <groupId>junit</groupId>

Added: commons/sandbox/monitoring/trunk/jpa/pom.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/pom.xml?rev=1534546&view=auto
==============================================================================
--- commons/sandbox/monitoring/trunk/jpa/pom.xml (added)
+++ commons/sandbox/monitoring/trunk/jpa/pom.xml Tue Oct 22 09:07:48 2013
@@ -0,0 +1,69 @@
+<?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/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+
+  <parent>
+    <artifactId>commons-monitoring-parent</artifactId>
+    <groupId>org.apache.commons.monitoring</groupId>
+    <version>1.0-SNAPSHOT</version>
+  </parent>
+
+  <artifactId>commons-monitoring-jpa</artifactId>
+  <version>1.0-SNAPSHOT</version>
+  <name>Commons Monitoring (Sandbox) :: JPA</name>
+
+  <dependencies>
+    <dependency>
+      <groupId>org.apache.geronimo.specs</groupId>
+      <artifactId>geronimo-jpa_2.0_spec</artifactId>
+      <version>1.1</version>
+      <scope>provided</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons.monitoring</groupId>
+      <artifactId>commons-monitoring-core</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.commons.monitoring</groupId>
+      <artifactId>commons-monitoring-aop</artifactId>
+      <exclusions>
+        <exclusion>
+          <groupId>org.apache.commons</groupId>
+          <artifactId>commons-proxy</artifactId>
+        </exclusion>
+      </exclusions>
+    </dependency>
+
+    <dependency>
+      <groupId>org.hsqldb</groupId>
+      <artifactId>hsqldb</artifactId>
+    </dependency>
+    <dependency>
+      <groupId>org.apache.openjpa</groupId>
+      <artifactId>openjpa</artifactId>
+      <version>2.2.2</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+    </dependency>
+  </dependencies>
+</project>
\ No newline at end of file

Added: commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/JPAProxyFactory.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/JPAProxyFactory.java?rev=1534546&view=auto
==============================================================================
--- commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/JPAProxyFactory.java (added)
+++ commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/JPAProxyFactory.java Tue Oct 22 09:07:48 2013
@@ -0,0 +1,103 @@
+/*
+ * 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.commons.monitoring.jpa;
+
+import org.apache.commons.monitoring.Role;
+import org.apache.commons.monitoring.aop.AbstractPerformanceInterceptor;
+import org.apache.commons.monitoring.util.ClassLoaders;
+
+import java.io.Serializable;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+
+public final class JPAProxyFactory {
+    // more designed as internal than user friendly, that's why it is not in aop module
+    public static Object monitor(final Class<?>[] classes, final Object instance, final Role role, final boolean cascade) {
+        return classes[0].cast(
+            Proxy.newProxyInstance(ClassLoaders.current(), classes, new JSEMonitoringHandler(instance, role, cascade)));
+    }
+
+    private JPAProxyFactory() {
+        // no-op
+    }
+
+    private static class JSEMonitoringHandler extends AbstractPerformanceInterceptor<Invocation> implements InvocationHandler {
+        private final Object instance;
+        private final Role role;
+        private final boolean cascade;
+
+        public JSEMonitoringHandler(final Object instance, final Role role, final boolean cascade) {
+            this.instance = instance;
+            this.role = role;
+            this.cascade = cascade;
+        }
+
+        @Override
+        public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+            if ("toString".equals(method.getName())) {
+                return "MonitoringProxy[" + instance + "]";
+            }
+
+            final Object o = doInvoke(new Invocation(instance, method, args));
+            final Class<?> returnType = method.getReturnType();
+            if (cascade && returnType.isInterface()) { // not java.*
+                return monitor(classes(returnType, o), o, role, cascade);
+            }
+            return o;
+        }
+
+        @Override
+        protected Object proceed(final Invocation invocation) throws Throwable {
+            try {
+                return invocation.method.invoke(invocation.target, invocation.args);
+            } catch (final InvocationTargetException ite) {
+                throw ite.getCause();
+            }
+        }
+
+        @Override
+        protected String getCounterName(final Invocation invocation) {
+            return getCounterName(invocation.target, invocation.method);
+        }
+
+        @Override
+        protected Role getRole() {
+            return role;
+        }
+
+        protected Class<?>[] classes(final Class<?> returnType, final Object o) {
+            if (Serializable.class.isInstance(o)) {
+                return new Class<?>[] { returnType, Serializable.class };
+            }
+            return new Class<?>[] { returnType };
+        }
+    }
+
+    private static class Invocation {
+        private final Object target;
+        private final Method method;
+        private final Object[] args;
+
+        private Invocation(final Object target, final Method method, final Object[] args) {
+            this.target = target;
+            this.method = method;
+            this.args = args;
+        }
+    }
+}

Added: commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/MonitoringPersistence.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/MonitoringPersistence.java?rev=1534546&view=auto
==============================================================================
--- commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/MonitoringPersistence.java (added)
+++ commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/MonitoringPersistence.java Tue Oct 22 09:07:48 2013
@@ -0,0 +1,165 @@
+/*
+ * 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.commons.monitoring.jpa;
+
+import org.apache.commons.monitoring.Role;
+import org.apache.commons.monitoring.configuration.Configuration;
+import org.apache.commons.monitoring.counters.Unit;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.spi.PersistenceProvider;
+import javax.persistence.spi.PersistenceUnitInfo;
+import javax.persistence.spi.ProviderUtil;
+import java.io.Serializable;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.Map;
+
+import static org.apache.commons.monitoring.jpa.JPAProxyFactory.monitor;
+
+public class MonitoringPersistence implements PersistenceProvider {
+    public static final Role ROLE = new Role("jpa", Unit.Time.NANOSECOND);
+
+    private static final Class<?>[] PROXY_API = new Class<?>[] { EntityManagerFactory.class, Serializable.class};
+    private static final String DELEGATE_PROVIDER_KEY = Configuration.COMMONS_MONITORING_PREFIX + "jpa.provider";
+
+    private static final String[] PROVIDERS = {
+        "org.apache.openjpa.persistence.PersistenceProviderImpl",
+        "org.hibernate.jpa.HibernatePeristenceProvider",
+        "org.hibernate.ejb.HibernatePeristence",
+        "org.eclipse.persistence.jpa.PersistenceProvider",
+        "oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider",
+        "oracle.toplink.essentials.PersistenceProvider",
+        "me.prettyprint.hom.CassandraPersistenceProvider",
+        "org.datanucleus.jpa.PersistenceProviderImpl",
+        "com.orientechnologies.orient.core.db.object.jpa.OJPAPersistenceProvider",
+        "com.orientechnologies.orient.object.jpa.OJPAPersistenceProvider",
+        "com.spaceprogram.simplejpa.PersistenceProviderImpl"
+    };
+
+    private volatile PersistenceProvider delegate;
+
+    @Override
+    public EntityManagerFactory createEntityManagerFactory(final String unit, final Map map) {
+        final PersistenceProvider persistenceProvider = findDelegate(map);
+        final ClassLoader tccl = tccl();
+
+        final ClassLoader hack = new OverridePersistenceXmlClassLoader(tccl, persistenceProvider.getClass().getName());
+        Thread.currentThread().setContextClassLoader(hack);
+        try {
+            final EntityManagerFactory entityManagerFactory = persistenceProvider.createEntityManagerFactory(unit, map);
+            if (entityManagerFactory == null) {
+                return null;
+            }
+            return EntityManagerFactory.class.cast(
+                monitor(PROXY_API, entityManagerFactory, ROLE, true));
+        } finally {
+            Thread.currentThread().setContextClassLoader(tccl);
+        }
+    }
+
+    @Override
+    public EntityManagerFactory createContainerEntityManagerFactory(final PersistenceUnitInfo info, final Map map) {
+        final PersistenceProvider persistenceProvider = findDelegate(map);
+        final EntityManagerFactory containerEntityManagerFactory = persistenceProvider.createContainerEntityManagerFactory(
+            PersistenceUnitInfo.class.cast(Proxy.newProxyInstance(tccl(), new Class<?>[]{PersistenceUnitInfo.class}, new ProviderAwareHandler(persistenceProvider.getClass().getName(), info))),
+            map);
+        if (containerEntityManagerFactory == null) {
+            return null;
+        }
+        return EntityManagerFactory.class.cast(
+            monitor(PROXY_API, containerEntityManagerFactory, ROLE, true));
+    }
+
+    @Override
+    public ProviderUtil getProviderUtil() { // we suppose it is loaded later than createXXXEMF so we'll get the delegate
+        return loadOrGuessDelegate(null).getProviderUtil();
+    }
+
+    private PersistenceProvider findDelegate(final Map map) {
+        if (map == null) {
+            return loadOrGuessDelegate(null);
+        }
+        return loadOrGuessDelegate(String.class.cast(map.get(DELEGATE_PROVIDER_KEY)));
+    }
+
+    private PersistenceProvider loadOrGuessDelegate(final String name) {
+        if (delegate == null) {
+            synchronized (this) {
+                if (delegate == null) {
+                    if (name == null) {
+                        for (final String provider : PROVIDERS) {
+                            try {
+                                delegate = newPersistence(provider);
+                                if (delegate != null) {
+                                    break;
+                                }
+                            } catch (final Throwable th2) {
+                                // no-op
+                            }
+                        }
+
+                        if (delegate == null) {
+                            throw new IllegalStateException(new ClassNotFoundException("Can't find a delegate"));
+                        }
+                    } else {
+                        try {
+                            delegate = newPersistence(name);
+                        } catch (final Exception e) {
+                            throw new IllegalStateException(new ClassNotFoundException("Can't instantiate '" + name + "'"));
+                        }
+                    }
+                }
+            }
+        }
+        if (name != null && !delegate.getClass().getName().equals(name)) {
+            try {
+                return newPersistence(name);
+            } catch (final Exception e) {
+                throw new IllegalStateException(new ClassNotFoundException("Can't instantiate '" + name + "'"));
+            }
+        }
+        return delegate;
+    }
+
+    private static ClassLoader tccl() {
+        return Thread.currentThread().getContextClassLoader();
+    }
+
+    private static PersistenceProvider newPersistence(final String name) throws Exception {
+        return PersistenceProvider.class.cast(tccl().loadClass(name).newInstance());
+    }
+
+    private static class ProviderAwareHandler implements InvocationHandler {
+        private final String provider;
+        private final PersistenceUnitInfo info;
+
+        public ProviderAwareHandler(final String provider, final PersistenceUnitInfo info) {
+            this.provider = provider;
+            this.info = info;
+        }
+
+        @Override
+        public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+            if ("getPersistenceProviderClassName".equals(method.getName())) {
+                return provider;
+            }
+            return method.invoke(info, args);
+        }
+    }
+}

Added: commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/OverridePersistenceXmlClassLoader.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/OverridePersistenceXmlClassLoader.java?rev=1534546&view=auto
==============================================================================
--- commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/OverridePersistenceXmlClassLoader.java (added)
+++ commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/OverridePersistenceXmlClassLoader.java Tue Oct 22 09:07:48 2013
@@ -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.commons.monitoring.jpa;
+
+import org.apache.commons.monitoring.MonitoringException;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLConnection;
+import java.net.URLStreamHandler;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.LinkedList;
+
+public class OverridePersistenceXmlClassLoader extends ClassLoader {
+    private static final String PERSISTENCE_XML = "META-INF/persistence.xml";
+    private static final String PERSISTENCE_PROVIDER = MonitoringPersistence.class.getName();
+    public static final String NO_PROVIDER = "<provider></provider>";
+
+    private final String replacement;
+
+    public OverridePersistenceXmlClassLoader(final ClassLoader parent, final String replacement) {
+        super(parent);
+        this.replacement = replacement;
+    }
+
+    @Override // don't load anything from here
+    protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
+        return super.loadClass(name, resolve);
+    }
+
+    @Override
+    public URL getResource(final String name) {
+        final URL url = super.getResource(name);
+        if (PERSISTENCE_XML.equals(name) && url != null) {
+            return newUrl(url, slurp(url));
+        }
+        return  url;
+    }
+
+    @Override
+    public Enumeration<URL> getResources(final String name) throws IOException {
+        final Enumeration<URL> urls = super.getResources(name);
+        if (PERSISTENCE_XML.equals(name)) {
+            final Collection<URL> overrided = new LinkedList<URL>();
+            while (urls.hasMoreElements()) {
+                final URL url = urls.nextElement();
+                overrided.add(newUrl(url, slurp(url)));
+            }
+            return Collections.enumeration(overrided);
+        }
+        return  urls;
+    }
+
+    private URL newUrl(final URL url, final String slurp) {
+        if (slurp.contains(PERSISTENCE_PROVIDER)) {
+            final String afterReplace = slurp.replace(PERSISTENCE_PROVIDER, replacement).replace(NO_PROVIDER, "");
+            try {
+                return new URL(url.getProtocol(), url.getHost(), url.getPort(), url.getFile(), new ConstantURLStreamHandler(afterReplace));
+            } catch (final MalformedURLException e) {
+                // no-op
+            }
+        }
+        return url;
+    }
+
+    private static String slurp(final URL url) {
+        InputStream is = null;
+        try {
+            is = url.openStream();
+            final ByteArrayOutputStream out = new ByteArrayOutputStream();
+            final byte[] buffer = new byte[1024];
+            int length;
+            while ((length = is.read(buffer)) != -1) {
+                out.write(buffer, 0, length);
+            }
+            return new String(out.toByteArray());
+        } catch (final IOException e) {
+            throw new MonitoringException(e);
+        } finally {
+            // no need to close out
+            try {
+                if (is != null) {
+                    is.close();
+                }
+            } catch (IOException e) {
+                // no-op
+            }
+        }
+    }
+
+    private static class ConstantURLStreamHandler extends URLStreamHandler {
+        private final String value;
+
+        private ConstantURLStreamHandler(final String value) {
+            this.value = value;
+        }
+
+        @Override
+        protected URLConnection openConnection(final URL u) throws IOException {
+            return new ConstantURLConnection(u, value);
+        }
+    }
+
+    private static class ConstantURLConnection extends URLConnection {
+        private final String value;
+
+        private ConstantURLConnection(final URL url, final String value) {
+            super(url);
+            this.value = value;
+        }
+
+        @Override
+        public void connect() throws IOException {
+            // no-op
+        }
+
+        @Override
+        public InputStream getInputStream() throws IOException {
+            return new ByteArrayInputStream(value.getBytes());
+        }
+    }
+}

Added: commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/services/javax.persistence.spi.PersistenceProvider
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/services/javax.persistence.spi.PersistenceProvider?rev=1534546&view=auto
==============================================================================
--- commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/services/javax.persistence.spi.PersistenceProvider (added)
+++ commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/services/javax.persistence.spi.PersistenceProvider Tue Oct 22 09:07:48 2013
@@ -0,0 +1 @@
+org.apache.commons.monitoring.jpa.MonitoringPersistence

Added: commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/EMFTest.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/EMFTest.java?rev=1534546&view=auto
==============================================================================
--- commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/EMFTest.java (added)
+++ commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/EMFTest.java Tue Oct 22 09:07:48 2013
@@ -0,0 +1,78 @@
+/*
+ * 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.commons.monitoring.jpa;
+
+import org.apache.commons.collections.IteratorUtils;
+import org.apache.commons.monitoring.counters.Counter;
+import org.apache.commons.monitoring.repositories.Repository;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.Persistence;
+import javax.persistence.spi.PersistenceUnitInfo;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.util.List;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+public class EMFTest {
+    @Before
+    @After
+    public void reset() {
+        Repository.INSTANCE.clear();
+    }
+
+    @Test
+    public void newEmfJSe() {
+        final EntityManagerFactory emf = Persistence.createEntityManagerFactory("test-jse");
+        assertNotNull(emf);
+        emf.close();
+
+        assertCreateCalled();
+    }
+
+    @Test
+    public void newEmfJavaEE() {
+        final EntityManagerFactory emf = new MonitoringPersistence().createContainerEntityManagerFactory(
+            PersistenceUnitInfo.class.cast(Proxy.newProxyInstance(getClass().getClassLoader(), new Class<?>[]{PersistenceUnitInfo.class}, new InvocationHandler() {
+                @Override
+                public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
+                    if (boolean.class.equals(method.getReturnType())) {
+                        return false;
+                    }
+                    return null;
+                }
+            })), null);
+        assertNotNull(emf);
+        emf.close();
+
+        assertCreateCalled();
+    }
+
+    private static void assertCreateCalled() {
+        final List<Counter> counters = IteratorUtils.toList(Repository.INSTANCE.iterator());
+        assertEquals(1, counters.size());
+
+        final Counter counter = counters.iterator().next();
+        assertEquals(1, counter.getHits());
+    }
+}

Added: commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/QueryTest.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/QueryTest.java?rev=1534546&view=auto
==============================================================================
--- commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/QueryTest.java (added)
+++ commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/QueryTest.java Tue Oct 22 09:07:48 2013
@@ -0,0 +1,119 @@
+/*
+ * 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.commons.monitoring.jpa;
+
+import org.apache.commons.monitoring.counters.Counter;
+import org.apache.commons.monitoring.jpa.entity.Person;
+import org.apache.commons.monitoring.repositories.Repository;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.persistence.Persistence;
+
+import static org.hamcrest.CoreMatchers.containsString;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+public class QueryTest {
+    @Before
+    @After
+    public void reset() {
+        Repository.INSTANCE.clear();
+    }
+
+    @Test
+    public void simpleFind() {
+        final EntityManagerFactory emf = Persistence.createEntityManagerFactory("test-jse");
+        assertNotNull(emf);
+        reset(); // get rid of init counter
+
+        try {
+            final EntityManager em = emf.createEntityManager();
+            assertNotNull(em);
+
+            assertCounter("createEntityManager");
+
+            reset(); // get rid of createEntityManager counter
+            try {
+                em.find(Person.class, 0L);
+                assertCounter("find");
+                reset(); // get rid of em.find() counter
+            } finally {
+                em.close();
+                assertCounter("EntityManagerImpl.close");
+            }
+
+            reset(); // get rid of em.close() counter
+        } finally {
+            emf.close();
+        }
+        assertCounter("EntityManagerFactoryImpl.close");
+    }
+
+    @Test
+    public void createNamedQuery() {
+        final EntityManagerFactory emf = Persistence.createEntityManagerFactory("test-jse");
+
+        try {
+            { // init
+                final EntityManager em = emf.createEntityManager();
+                try {
+                    final EntityTransaction transaction = em.getTransaction();
+                    transaction.begin();
+                    try {
+                        final Person p = new Person();
+                        p.setName("sirona");
+
+                        em.persist(p);
+                        transaction.commit();
+                    } catch (final Exception e) {
+                        transaction.rollback();
+                    }
+                } finally {
+                    em.close();
+                }
+            }
+
+            { // checks
+                final EntityManager em = emf.createEntityManager();
+                try {
+                    reset();
+                    em.createNamedQuery("Person.findByName", Person.class).setParameter("name", "sirona").getSingleResult();
+                    assertCounter("createNamedQuery");
+                } finally {
+                    em.close();
+                }
+            }
+        } finally {
+            emf.close();
+        }
+    }
+
+    private static void assertCounter(final String method) {
+        assertTrue(Repository.INSTANCE.iterator().hasNext());
+
+        final Counter counter = Repository.INSTANCE.iterator().next();
+        assertEquals(1, counter.getHits());
+        assertThat(counter.getKey().getName(), containsString(method));
+    }
+}

Added: commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Address.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Address.java?rev=1534546&view=auto
==============================================================================
--- commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Address.java (added)
+++ commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Address.java Tue Oct 22 09:07:48 2013
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.monitoring.jpa.entity;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.ManyToOne;
+
+@Entity
+public class Address {
+    @Id
+    @GeneratedValue
+    private long id;
+    private String street;
+
+    @ManyToOne
+    private Person person;
+
+    public long getId() {
+        return id;
+    }
+
+    public String getStreet() {
+        return street;
+    }
+
+    public void setStreet(final String street) {
+        this.street = street;
+    }
+
+    public Person getPerson() {
+        return person;
+    }
+
+    public void setPerson(final Person person) {
+        this.person = person;
+    }
+}

Added: commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Person.java
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Person.java?rev=1534546&view=auto
==============================================================================
--- commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Person.java (added)
+++ commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Person.java Tue Oct 22 09:07:48 2013
@@ -0,0 +1,55 @@
+/*
+ * 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.commons.monitoring.jpa.entity;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.Id;
+import javax.persistence.NamedQuery;
+import javax.persistence.OneToMany;
+import java.util.LinkedList;
+import java.util.List;
+
+@Entity
+@NamedQuery(name = "Person.findByName", query = "select p from Person p where p.name = :name")
+public class Person {
+    @Id
+    @GeneratedValue
+    private long id;
+
+    private String name;
+
+    @OneToMany(cascade = { CascadeType.ALL }, mappedBy = "person")
+    private List<Address> addresses = new LinkedList<Address>();
+
+    public long getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public void setName(final String name) {
+        this.name = name;
+    }
+
+    public List<Address> getAddresses() {
+        return addresses;
+    }
+}

Added: commons/sandbox/monitoring/trunk/jpa/src/test/resources/META-INF/persistence.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/test/resources/META-INF/persistence.xml?rev=1534546&view=auto
==============================================================================
--- commons/sandbox/monitoring/trunk/jpa/src/test/resources/META-INF/persistence.xml (added)
+++ commons/sandbox/monitoring/trunk/jpa/src/test/resources/META-INF/persistence.xml Tue Oct 22 09:07:48 2013
@@ -0,0 +1,50 @@
+<?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.
+  -->
+<persistence version="2.0"
+             xmlns="http://java.sun.com/xml/ns/persistence"
+             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
+                       http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
+  <persistence-unit name="test-jse">
+    <provider>org.apache.commons.monitoring.jpa.MonitoringPersistence</provider>
+    <class>org.apache.commons.monitoring.jpa.entity.Person</class>
+    <class>org.apache.commons.monitoring.jpa.entity.Address</class>
+    <properties>
+      <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
+      <property name="openjpa.ConnectionURL" value="jdbc:hsqldb:mem:jpa;create=true"/>
+      <property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver"/>
+      <property name="openjpa.ConnectionUserName" value="sa"/>
+      <property name="openjpa.ConnectionPassword" value=""/>
+      <property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO, SQL=INFO"/>
+    </properties>
+  </persistence-unit>
+  <persistence-unit name="test-jta">
+    <provider>org.apache.commons.monitoring.jpa.MonitoringPersistence</provider>
+    <class>org.apache.commons.monitoring.jpa.entity.Person</class>
+    <class>org.apache.commons.monitoring.jpa.entity.Address</class>
+    <properties>
+      <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
+      <property name="openjpa.ConnectionURL" value="jdbc:hsqldb:mem:jpa;create=true"/>
+      <property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver"/>
+      <property name="openjpa.ConnectionUserName" value="sa"/>
+      <property name="openjpa.ConnectionPassword" value=""/>
+      <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/>
+      <property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO, SQL=INFO"/>
+    </properties>
+  </persistence-unit>
+</persistence>

Modified: commons/sandbox/monitoring/trunk/pom.xml
URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/pom.xml?rev=1534546&r1=1534545&r2=1534546&view=diff
==============================================================================
--- commons/sandbox/monitoring/trunk/pom.xml (original)
+++ commons/sandbox/monitoring/trunk/pom.xml Tue Oct 22 09:07:48 2013
@@ -58,6 +58,7 @@
     <module>graphite</module>
     <module>cube</module>
     <module>collector</module>
+    <module>jpa</module>
   </modules>
 
   <developers>
@@ -163,6 +164,12 @@
         <scope>test</scope>
       </dependency>
       <dependency>
+        <groupId>org.hsqldb</groupId>
+        <artifactId>hsqldb</artifactId>
+        <version>2.2.9</version>
+        <scope>test</scope>
+      </dependency>
+      <dependency>
         <groupId>org.apache.geronimo.specs</groupId>
         <artifactId>geronimo-servlet_3.0_spec</artifactId>
         <version>1.0</version>



Re: svn commit: r1534546 - in /commons/sandbox/monitoring/trunk: ./ aop/src/main/java/org/apache/commons/monitoring/aop/ core/src/main/java/org/apache/commons/monitoring/counters/ jdbc/ jpa/ jpa/src/ jpa/src/main/ jpa/src/main/java/ jpa/src/main/java/org/ ...

Posted by sebb <se...@gmail.com>.
On 22 October 2013 10:07,  <rm...@apache.org> wrote:
> Author: rmannibucau
> Date: Tue Oct 22 09:07:48 2013
> New Revision: 1534546
>
> URL: http://svn.apache.org/r1534546
> Log:
> adding jpa module - doc todo
>
> Added:
>     commons/sandbox/monitoring/trunk/jpa/
>     commons/sandbox/monitoring/trunk/jpa/pom.xml
>     commons/sandbox/monitoring/trunk/jpa/src/
>     commons/sandbox/monitoring/trunk/jpa/src/main/
>     commons/sandbox/monitoring/trunk/jpa/src/main/java/
>     commons/sandbox/monitoring/trunk/jpa/src/main/java/org/
>     commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/
>     commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/
>     commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/
>     commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/
>     commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/JPAProxyFactory.java
>     commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/MonitoringPersistence.java
>     commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/OverridePersistenceXmlClassLoader.java
>     commons/sandbox/monitoring/trunk/jpa/src/main/resources/
>     commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/
>     commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/services/
>     commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/services/javax.persistence.spi.PersistenceProvider
>     commons/sandbox/monitoring/trunk/jpa/src/test/
>     commons/sandbox/monitoring/trunk/jpa/src/test/java/
>     commons/sandbox/monitoring/trunk/jpa/src/test/java/org/
>     commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/
>     commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/
>     commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/
>     commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/
>     commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/EMFTest.java
>     commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/QueryTest.java
>     commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/
>     commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Address.java
>     commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Person.java
>     commons/sandbox/monitoring/trunk/jpa/src/test/resources/
>     commons/sandbox/monitoring/trunk/jpa/src/test/resources/META-INF/
>     commons/sandbox/monitoring/trunk/jpa/src/test/resources/META-INF/persistence.xml

SVN eol-style settings?

> Modified:
>     commons/sandbox/monitoring/trunk/aop/src/main/java/org/apache/commons/monitoring/aop/AbstractPerformanceInterceptor.java
>     commons/sandbox/monitoring/trunk/core/src/main/java/org/apache/commons/monitoring/counters/DefaultCounter.java
>     commons/sandbox/monitoring/trunk/jdbc/pom.xml
>     commons/sandbox/monitoring/trunk/pom.xml
>
> Modified: commons/sandbox/monitoring/trunk/aop/src/main/java/org/apache/commons/monitoring/aop/AbstractPerformanceInterceptor.java
> URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/aop/src/main/java/org/apache/commons/monitoring/aop/AbstractPerformanceInterceptor.java?rev=1534546&r1=1534545&r2=1534546&view=diff
> ==============================================================================
> --- commons/sandbox/monitoring/trunk/aop/src/main/java/org/apache/commons/monitoring/aop/AbstractPerformanceInterceptor.java (original)
> +++ commons/sandbox/monitoring/trunk/aop/src/main/java/org/apache/commons/monitoring/aop/AbstractPerformanceInterceptor.java Tue Oct 22 09:07:48 2013
> @@ -51,7 +51,7 @@ public abstract class AbstractPerformanc
>              return proceed(invocation);
>          }
>
> -        final Counter monitor = Repository.INSTANCE.getCounter(new Counter.Key(Role.PERFORMANCES, name));
> +        final Counter monitor = Repository.INSTANCE.getCounter(new Counter.Key(getRole(), name));
>          final StopWatch stopwatch = Repository.INSTANCE.start(monitor);
>          Throwable error = null;
>          try {
> @@ -69,6 +69,10 @@ public abstract class AbstractPerformanc
>          }
>      }
>
> +    protected Role getRole() {
> +        return Role.PERFORMANCES;
> +    }
> +
>      protected abstract Object proceed(T invocation) throws Throwable;
>
>      protected abstract String getCounterName(T invocation);
>
> Modified: commons/sandbox/monitoring/trunk/core/src/main/java/org/apache/commons/monitoring/counters/DefaultCounter.java
> URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/core/src/main/java/org/apache/commons/monitoring/counters/DefaultCounter.java?rev=1534546&r1=1534545&r2=1534546&view=diff
> ==============================================================================
> --- commons/sandbox/monitoring/trunk/core/src/main/java/org/apache/commons/monitoring/counters/DefaultCounter.java (original)
> +++ commons/sandbox/monitoring/trunk/core/src/main/java/org/apache/commons/monitoring/counters/DefaultCounter.java Tue Oct 22 09:07:48 2013
> @@ -171,4 +171,15 @@ public class DefaultCounter implements C
>      public ReadWriteLock getLock() {
>          return lock;
>      }
> +
> +    @Override
> +    public String toString() {
> +        return "DefaultCounter{" +
> +            "concurrency=" + concurrency +
> +            ", key=" + key +
> +            ", dataStore=" + dataStore +
> +            ", maxConcurrency=" + maxConcurrency +
> +            ", statistics=" + statistics +
> +            '}';
> +    }
>  }
>
> Modified: commons/sandbox/monitoring/trunk/jdbc/pom.xml
> URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jdbc/pom.xml?rev=1534546&r1=1534545&r2=1534546&view=diff
> ==============================================================================
> --- commons/sandbox/monitoring/trunk/jdbc/pom.xml (original)
> +++ commons/sandbox/monitoring/trunk/jdbc/pom.xml Tue Oct 22 09:07:48 2013
> @@ -42,8 +42,6 @@
>      <dependency>
>        <groupId>org.hsqldb</groupId>
>        <artifactId>hsqldb</artifactId>
> -      <version>2.2.9</version>
> -      <scope>test</scope>
>      </dependency>
>      <dependency>
>        <groupId>junit</groupId>
>
> Added: commons/sandbox/monitoring/trunk/jpa/pom.xml
> URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/pom.xml?rev=1534546&view=auto
> ==============================================================================
> --- commons/sandbox/monitoring/trunk/jpa/pom.xml (added)
> +++ commons/sandbox/monitoring/trunk/jpa/pom.xml Tue Oct 22 09:07:48 2013
> @@ -0,0 +1,69 @@
> +<?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/maven-v4_0_0.xsd">
> +  <modelVersion>4.0.0</modelVersion>
> +
> +  <parent>
> +    <artifactId>commons-monitoring-parent</artifactId>
> +    <groupId>org.apache.commons.monitoring</groupId>
> +    <version>1.0-SNAPSHOT</version>
> +  </parent>
> +
> +  <artifactId>commons-monitoring-jpa</artifactId>
> +  <version>1.0-SNAPSHOT</version>
> +  <name>Commons Monitoring (Sandbox) :: JPA</name>
> +
> +  <dependencies>
> +    <dependency>
> +      <groupId>org.apache.geronimo.specs</groupId>
> +      <artifactId>geronimo-jpa_2.0_spec</artifactId>
> +      <version>1.1</version>
> +      <scope>provided</scope>
> +    </dependency>
> +    <dependency>
> +      <groupId>org.apache.commons.monitoring</groupId>
> +      <artifactId>commons-monitoring-core</artifactId>
> +    </dependency>
> +    <dependency>
> +      <groupId>org.apache.commons.monitoring</groupId>
> +      <artifactId>commons-monitoring-aop</artifactId>
> +      <exclusions>
> +        <exclusion>
> +          <groupId>org.apache.commons</groupId>
> +          <artifactId>commons-proxy</artifactId>
> +        </exclusion>
> +      </exclusions>
> +    </dependency>
> +
> +    <dependency>
> +      <groupId>org.hsqldb</groupId>
> +      <artifactId>hsqldb</artifactId>
> +    </dependency>
> +    <dependency>
> +      <groupId>org.apache.openjpa</groupId>
> +      <artifactId>openjpa</artifactId>
> +      <version>2.2.2</version>
> +      <scope>test</scope>
> +    </dependency>
> +    <dependency>
> +      <groupId>junit</groupId>
> +      <artifactId>junit</artifactId>
> +    </dependency>
> +  </dependencies>
> +</project>
> \ No newline at end of file
>
> Added: commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/JPAProxyFactory.java
> URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/JPAProxyFactory.java?rev=1534546&view=auto
> ==============================================================================
> --- commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/JPAProxyFactory.java (added)
> +++ commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/JPAProxyFactory.java Tue Oct 22 09:07:48 2013
> @@ -0,0 +1,103 @@
> +/*
> + * 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.commons.monitoring.jpa;
> +
> +import org.apache.commons.monitoring.Role;
> +import org.apache.commons.monitoring.aop.AbstractPerformanceInterceptor;
> +import org.apache.commons.monitoring.util.ClassLoaders;
> +
> +import java.io.Serializable;
> +import java.lang.reflect.InvocationHandler;
> +import java.lang.reflect.InvocationTargetException;
> +import java.lang.reflect.Method;
> +import java.lang.reflect.Proxy;
> +
> +public final class JPAProxyFactory {
> +    // more designed as internal than user friendly, that's why it is not in aop module
> +    public static Object monitor(final Class<?>[] classes, final Object instance, final Role role, final boolean cascade) {
> +        return classes[0].cast(
> +            Proxy.newProxyInstance(ClassLoaders.current(), classes, new JSEMonitoringHandler(instance, role, cascade)));
> +    }
> +
> +    private JPAProxyFactory() {
> +        // no-op
> +    }
> +
> +    private static class JSEMonitoringHandler extends AbstractPerformanceInterceptor<Invocation> implements InvocationHandler {
> +        private final Object instance;
> +        private final Role role;
> +        private final boolean cascade;
> +
> +        public JSEMonitoringHandler(final Object instance, final Role role, final boolean cascade) {
> +            this.instance = instance;
> +            this.role = role;
> +            this.cascade = cascade;
> +        }
> +
> +        @Override
> +        public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
> +            if ("toString".equals(method.getName())) {
> +                return "MonitoringProxy[" + instance + "]";
> +            }
> +
> +            final Object o = doInvoke(new Invocation(instance, method, args));
> +            final Class<?> returnType = method.getReturnType();
> +            if (cascade && returnType.isInterface()) { // not java.*
> +                return monitor(classes(returnType, o), o, role, cascade);
> +            }
> +            return o;
> +        }
> +
> +        @Override
> +        protected Object proceed(final Invocation invocation) throws Throwable {
> +            try {
> +                return invocation.method.invoke(invocation.target, invocation.args);
> +            } catch (final InvocationTargetException ite) {
> +                throw ite.getCause();
> +            }
> +        }
> +
> +        @Override
> +        protected String getCounterName(final Invocation invocation) {
> +            return getCounterName(invocation.target, invocation.method);
> +        }
> +
> +        @Override
> +        protected Role getRole() {
> +            return role;
> +        }
> +
> +        protected Class<?>[] classes(final Class<?> returnType, final Object o) {
> +            if (Serializable.class.isInstance(o)) {
> +                return new Class<?>[] { returnType, Serializable.class };
> +            }
> +            return new Class<?>[] { returnType };
> +        }
> +    }
> +
> +    private static class Invocation {
> +        private final Object target;
> +        private final Method method;
> +        private final Object[] args;
> +
> +        private Invocation(final Object target, final Method method, final Object[] args) {
> +            this.target = target;
> +            this.method = method;
> +            this.args = args;
> +        }
> +    }
> +}
>
> Added: commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/MonitoringPersistence.java
> URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/MonitoringPersistence.java?rev=1534546&view=auto
> ==============================================================================
> --- commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/MonitoringPersistence.java (added)
> +++ commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/MonitoringPersistence.java Tue Oct 22 09:07:48 2013
> @@ -0,0 +1,165 @@
> +/*
> + * 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.commons.monitoring.jpa;
> +
> +import org.apache.commons.monitoring.Role;
> +import org.apache.commons.monitoring.configuration.Configuration;
> +import org.apache.commons.monitoring.counters.Unit;
> +
> +import javax.persistence.EntityManagerFactory;
> +import javax.persistence.spi.PersistenceProvider;
> +import javax.persistence.spi.PersistenceUnitInfo;
> +import javax.persistence.spi.ProviderUtil;
> +import java.io.Serializable;
> +import java.lang.reflect.InvocationHandler;
> +import java.lang.reflect.Method;
> +import java.lang.reflect.Proxy;
> +import java.util.Map;
> +
> +import static org.apache.commons.monitoring.jpa.JPAProxyFactory.monitor;
> +
> +public class MonitoringPersistence implements PersistenceProvider {
> +    public static final Role ROLE = new Role("jpa", Unit.Time.NANOSECOND);
> +
> +    private static final Class<?>[] PROXY_API = new Class<?>[] { EntityManagerFactory.class, Serializable.class};
> +    private static final String DELEGATE_PROVIDER_KEY = Configuration.COMMONS_MONITORING_PREFIX + "jpa.provider";
> +
> +    private static final String[] PROVIDERS = {
> +        "org.apache.openjpa.persistence.PersistenceProviderImpl",
> +        "org.hibernate.jpa.HibernatePeristenceProvider",
> +        "org.hibernate.ejb.HibernatePeristence",
> +        "org.eclipse.persistence.jpa.PersistenceProvider",
> +        "oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider",
> +        "oracle.toplink.essentials.PersistenceProvider",
> +        "me.prettyprint.hom.CassandraPersistenceProvider",
> +        "org.datanucleus.jpa.PersistenceProviderImpl",
> +        "com.orientechnologies.orient.core.db.object.jpa.OJPAPersistenceProvider",
> +        "com.orientechnologies.orient.object.jpa.OJPAPersistenceProvider",
> +        "com.spaceprogram.simplejpa.PersistenceProviderImpl"
> +    };
> +
> +    private volatile PersistenceProvider delegate;
> +
> +    @Override
> +    public EntityManagerFactory createEntityManagerFactory(final String unit, final Map map) {
> +        final PersistenceProvider persistenceProvider = findDelegate(map);
> +        final ClassLoader tccl = tccl();
> +
> +        final ClassLoader hack = new OverridePersistenceXmlClassLoader(tccl, persistenceProvider.getClass().getName());
> +        Thread.currentThread().setContextClassLoader(hack);
> +        try {
> +            final EntityManagerFactory entityManagerFactory = persistenceProvider.createEntityManagerFactory(unit, map);
> +            if (entityManagerFactory == null) {
> +                return null;
> +            }
> +            return EntityManagerFactory.class.cast(
> +                monitor(PROXY_API, entityManagerFactory, ROLE, true));
> +        } finally {
> +            Thread.currentThread().setContextClassLoader(tccl);
> +        }
> +    }
> +
> +    @Override
> +    public EntityManagerFactory createContainerEntityManagerFactory(final PersistenceUnitInfo info, final Map map) {
> +        final PersistenceProvider persistenceProvider = findDelegate(map);
> +        final EntityManagerFactory containerEntityManagerFactory = persistenceProvider.createContainerEntityManagerFactory(
> +            PersistenceUnitInfo.class.cast(Proxy.newProxyInstance(tccl(), new Class<?>[]{PersistenceUnitInfo.class}, new ProviderAwareHandler(persistenceProvider.getClass().getName(), info))),
> +            map);
> +        if (containerEntityManagerFactory == null) {
> +            return null;
> +        }
> +        return EntityManagerFactory.class.cast(
> +            monitor(PROXY_API, containerEntityManagerFactory, ROLE, true));
> +    }
> +
> +    @Override
> +    public ProviderUtil getProviderUtil() { // we suppose it is loaded later than createXXXEMF so we'll get the delegate
> +        return loadOrGuessDelegate(null).getProviderUtil();
> +    }
> +
> +    private PersistenceProvider findDelegate(final Map map) {
> +        if (map == null) {
> +            return loadOrGuessDelegate(null);
> +        }
> +        return loadOrGuessDelegate(String.class.cast(map.get(DELEGATE_PROVIDER_KEY)));
> +    }
> +
> +    private PersistenceProvider loadOrGuessDelegate(final String name) {
> +        if (delegate == null) {
> +            synchronized (this) {
> +                if (delegate == null) {
> +                    if (name == null) {
> +                        for (final String provider : PROVIDERS) {
> +                            try {
> +                                delegate = newPersistence(provider);
> +                                if (delegate != null) {
> +                                    break;
> +                                }
> +                            } catch (final Throwable th2) {
> +                                // no-op
> +                            }
> +                        }
> +
> +                        if (delegate == null) {
> +                            throw new IllegalStateException(new ClassNotFoundException("Can't find a delegate"));
> +                        }
> +                    } else {
> +                        try {
> +                            delegate = newPersistence(name);
> +                        } catch (final Exception e) {
> +                            throw new IllegalStateException(new ClassNotFoundException("Can't instantiate '" + name + "'"));
> +                        }
> +                    }
> +                }
> +            }
> +        }
> +        if (name != null && !delegate.getClass().getName().equals(name)) {
> +            try {
> +                return newPersistence(name);
> +            } catch (final Exception e) {
> +                throw new IllegalStateException(new ClassNotFoundException("Can't instantiate '" + name + "'"));
> +            }
> +        }
> +        return delegate;
> +    }
> +
> +    private static ClassLoader tccl() {
> +        return Thread.currentThread().getContextClassLoader();
> +    }
> +
> +    private static PersistenceProvider newPersistence(final String name) throws Exception {
> +        return PersistenceProvider.class.cast(tccl().loadClass(name).newInstance());
> +    }
> +
> +    private static class ProviderAwareHandler implements InvocationHandler {
> +        private final String provider;
> +        private final PersistenceUnitInfo info;
> +
> +        public ProviderAwareHandler(final String provider, final PersistenceUnitInfo info) {
> +            this.provider = provider;
> +            this.info = info;
> +        }
> +
> +        @Override
> +        public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
> +            if ("getPersistenceProviderClassName".equals(method.getName())) {
> +                return provider;
> +            }
> +            return method.invoke(info, args);
> +        }
> +    }
> +}
>
> Added: commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/OverridePersistenceXmlClassLoader.java
> URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/OverridePersistenceXmlClassLoader.java?rev=1534546&view=auto
> ==============================================================================
> --- commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/OverridePersistenceXmlClassLoader.java (added)
> +++ commons/sandbox/monitoring/trunk/jpa/src/main/java/org/apache/commons/monitoring/jpa/OverridePersistenceXmlClassLoader.java Tue Oct 22 09:07:48 2013
> @@ -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.commons.monitoring.jpa;
> +
> +import org.apache.commons.monitoring.MonitoringException;
> +
> +import java.io.ByteArrayInputStream;
> +import java.io.ByteArrayOutputStream;
> +import java.io.IOException;
> +import java.io.InputStream;
> +import java.net.MalformedURLException;
> +import java.net.URL;
> +import java.net.URLConnection;
> +import java.net.URLStreamHandler;
> +import java.util.Collection;
> +import java.util.Collections;
> +import java.util.Enumeration;
> +import java.util.LinkedList;
> +
> +public class OverridePersistenceXmlClassLoader extends ClassLoader {
> +    private static final String PERSISTENCE_XML = "META-INF/persistence.xml";
> +    private static final String PERSISTENCE_PROVIDER = MonitoringPersistence.class.getName();
> +    public static final String NO_PROVIDER = "<provider></provider>";
> +
> +    private final String replacement;
> +
> +    public OverridePersistenceXmlClassLoader(final ClassLoader parent, final String replacement) {
> +        super(parent);
> +        this.replacement = replacement;
> +    }
> +
> +    @Override // don't load anything from here
> +    protected Class<?> loadClass(final String name, final boolean resolve) throws ClassNotFoundException {
> +        return super.loadClass(name, resolve);
> +    }
> +
> +    @Override
> +    public URL getResource(final String name) {
> +        final URL url = super.getResource(name);
> +        if (PERSISTENCE_XML.equals(name) && url != null) {
> +            return newUrl(url, slurp(url));
> +        }
> +        return  url;
> +    }
> +
> +    @Override
> +    public Enumeration<URL> getResources(final String name) throws IOException {
> +        final Enumeration<URL> urls = super.getResources(name);
> +        if (PERSISTENCE_XML.equals(name)) {
> +            final Collection<URL> overrided = new LinkedList<URL>();
> +            while (urls.hasMoreElements()) {
> +                final URL url = urls.nextElement();
> +                overrided.add(newUrl(url, slurp(url)));
> +            }
> +            return Collections.enumeration(overrided);
> +        }
> +        return  urls;
> +    }
> +
> +    private URL newUrl(final URL url, final String slurp) {
> +        if (slurp.contains(PERSISTENCE_PROVIDER)) {
> +            final String afterReplace = slurp.replace(PERSISTENCE_PROVIDER, replacement).replace(NO_PROVIDER, "");
> +            try {
> +                return new URL(url.getProtocol(), url.getHost(), url.getPort(), url.getFile(), new ConstantURLStreamHandler(afterReplace));
> +            } catch (final MalformedURLException e) {
> +                // no-op
> +            }
> +        }
> +        return url;
> +    }
> +
> +    private static String slurp(final URL url) {
> +        InputStream is = null;
> +        try {
> +            is = url.openStream();
> +            final ByteArrayOutputStream out = new ByteArrayOutputStream();
> +            final byte[] buffer = new byte[1024];
> +            int length;
> +            while ((length = is.read(buffer)) != -1) {
> +                out.write(buffer, 0, length);
> +            }
> +            return new String(out.toByteArray());
> +        } catch (final IOException e) {
> +            throw new MonitoringException(e);
> +        } finally {
> +            // no need to close out
> +            try {
> +                if (is != null) {
> +                    is.close();
> +                }
> +            } catch (IOException e) {
> +                // no-op
> +            }
> +        }
> +    }
> +
> +    private static class ConstantURLStreamHandler extends URLStreamHandler {
> +        private final String value;
> +
> +        private ConstantURLStreamHandler(final String value) {
> +            this.value = value;
> +        }
> +
> +        @Override
> +        protected URLConnection openConnection(final URL u) throws IOException {
> +            return new ConstantURLConnection(u, value);
> +        }
> +    }
> +
> +    private static class ConstantURLConnection extends URLConnection {
> +        private final String value;
> +
> +        private ConstantURLConnection(final URL url, final String value) {
> +            super(url);
> +            this.value = value;
> +        }
> +
> +        @Override
> +        public void connect() throws IOException {
> +            // no-op
> +        }
> +
> +        @Override
> +        public InputStream getInputStream() throws IOException {
> +            return new ByteArrayInputStream(value.getBytes());
> +        }
> +    }
> +}
>
> Added: commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/services/javax.persistence.spi.PersistenceProvider
> URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/services/javax.persistence.spi.PersistenceProvider?rev=1534546&view=auto
> ==============================================================================
> --- commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/services/javax.persistence.spi.PersistenceProvider (added)
> +++ commons/sandbox/monitoring/trunk/jpa/src/main/resources/META-INF/services/javax.persistence.spi.PersistenceProvider Tue Oct 22 09:07:48 2013
> @@ -0,0 +1 @@
> +org.apache.commons.monitoring.jpa.MonitoringPersistence
>
> Added: commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/EMFTest.java
> URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/EMFTest.java?rev=1534546&view=auto
> ==============================================================================
> --- commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/EMFTest.java (added)
> +++ commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/EMFTest.java Tue Oct 22 09:07:48 2013
> @@ -0,0 +1,78 @@
> +/*
> + * 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.commons.monitoring.jpa;
> +
> +import org.apache.commons.collections.IteratorUtils;
> +import org.apache.commons.monitoring.counters.Counter;
> +import org.apache.commons.monitoring.repositories.Repository;
> +import org.junit.After;
> +import org.junit.Before;
> +import org.junit.Test;
> +
> +import javax.persistence.EntityManagerFactory;
> +import javax.persistence.Persistence;
> +import javax.persistence.spi.PersistenceUnitInfo;
> +import java.lang.reflect.InvocationHandler;
> +import java.lang.reflect.Method;
> +import java.lang.reflect.Proxy;
> +import java.util.List;
> +
> +import static org.junit.Assert.assertEquals;
> +import static org.junit.Assert.assertNotNull;
> +
> +public class EMFTest {
> +    @Before
> +    @After
> +    public void reset() {
> +        Repository.INSTANCE.clear();
> +    }
> +
> +    @Test
> +    public void newEmfJSe() {
> +        final EntityManagerFactory emf = Persistence.createEntityManagerFactory("test-jse");
> +        assertNotNull(emf);
> +        emf.close();
> +
> +        assertCreateCalled();
> +    }
> +
> +    @Test
> +    public void newEmfJavaEE() {
> +        final EntityManagerFactory emf = new MonitoringPersistence().createContainerEntityManagerFactory(
> +            PersistenceUnitInfo.class.cast(Proxy.newProxyInstance(getClass().getClassLoader(), new Class<?>[]{PersistenceUnitInfo.class}, new InvocationHandler() {
> +                @Override
> +                public Object invoke(final Object proxy, final Method method, final Object[] args) throws Throwable {
> +                    if (boolean.class.equals(method.getReturnType())) {
> +                        return false;
> +                    }
> +                    return null;
> +                }
> +            })), null);
> +        assertNotNull(emf);
> +        emf.close();
> +
> +        assertCreateCalled();
> +    }
> +
> +    private static void assertCreateCalled() {
> +        final List<Counter> counters = IteratorUtils.toList(Repository.INSTANCE.iterator());
> +        assertEquals(1, counters.size());
> +
> +        final Counter counter = counters.iterator().next();
> +        assertEquals(1, counter.getHits());
> +    }
> +}
>
> Added: commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/QueryTest.java
> URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/QueryTest.java?rev=1534546&view=auto
> ==============================================================================
> --- commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/QueryTest.java (added)
> +++ commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/QueryTest.java Tue Oct 22 09:07:48 2013
> @@ -0,0 +1,119 @@
> +/*
> + * 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.commons.monitoring.jpa;
> +
> +import org.apache.commons.monitoring.counters.Counter;
> +import org.apache.commons.monitoring.jpa.entity.Person;
> +import org.apache.commons.monitoring.repositories.Repository;
> +import org.junit.After;
> +import org.junit.Before;
> +import org.junit.Test;
> +
> +import javax.persistence.EntityManager;
> +import javax.persistence.EntityManagerFactory;
> +import javax.persistence.EntityTransaction;
> +import javax.persistence.Persistence;
> +
> +import static org.hamcrest.CoreMatchers.containsString;
> +import static org.junit.Assert.assertEquals;
> +import static org.junit.Assert.assertNotNull;
> +import static org.junit.Assert.assertThat;
> +import static org.junit.Assert.assertTrue;
> +
> +public class QueryTest {
> +    @Before
> +    @After
> +    public void reset() {
> +        Repository.INSTANCE.clear();
> +    }
> +
> +    @Test
> +    public void simpleFind() {
> +        final EntityManagerFactory emf = Persistence.createEntityManagerFactory("test-jse");
> +        assertNotNull(emf);
> +        reset(); // get rid of init counter
> +
> +        try {
> +            final EntityManager em = emf.createEntityManager();
> +            assertNotNull(em);
> +
> +            assertCounter("createEntityManager");
> +
> +            reset(); // get rid of createEntityManager counter
> +            try {
> +                em.find(Person.class, 0L);
> +                assertCounter("find");
> +                reset(); // get rid of em.find() counter
> +            } finally {
> +                em.close();
> +                assertCounter("EntityManagerImpl.close");
> +            }
> +
> +            reset(); // get rid of em.close() counter
> +        } finally {
> +            emf.close();
> +        }
> +        assertCounter("EntityManagerFactoryImpl.close");
> +    }
> +
> +    @Test
> +    public void createNamedQuery() {
> +        final EntityManagerFactory emf = Persistence.createEntityManagerFactory("test-jse");
> +
> +        try {
> +            { // init
> +                final EntityManager em = emf.createEntityManager();
> +                try {
> +                    final EntityTransaction transaction = em.getTransaction();
> +                    transaction.begin();
> +                    try {
> +                        final Person p = new Person();
> +                        p.setName("sirona");
> +
> +                        em.persist(p);
> +                        transaction.commit();
> +                    } catch (final Exception e) {
> +                        transaction.rollback();
> +                    }
> +                } finally {
> +                    em.close();
> +                }
> +            }
> +
> +            { // checks
> +                final EntityManager em = emf.createEntityManager();
> +                try {
> +                    reset();
> +                    em.createNamedQuery("Person.findByName", Person.class).setParameter("name", "sirona").getSingleResult();
> +                    assertCounter("createNamedQuery");
> +                } finally {
> +                    em.close();
> +                }
> +            }
> +        } finally {
> +            emf.close();
> +        }
> +    }
> +
> +    private static void assertCounter(final String method) {
> +        assertTrue(Repository.INSTANCE.iterator().hasNext());
> +
> +        final Counter counter = Repository.INSTANCE.iterator().next();
> +        assertEquals(1, counter.getHits());
> +        assertThat(counter.getKey().getName(), containsString(method));
> +    }
> +}
>
> Added: commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Address.java
> URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Address.java?rev=1534546&view=auto
> ==============================================================================
> --- commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Address.java (added)
> +++ commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Address.java Tue Oct 22 09:07:48 2013
> @@ -0,0 +1,53 @@
> +/*
> + * Licensed to the Apache Software Foundation (ASF) under one or more
> + * contributor license agreements.  See the NOTICE file distributed with
> + * this work for additional information regarding copyright ownership.
> + * The ASF licenses this file to You under the Apache License, Version 2.0
> + * (the "License"); you may not use this file except in compliance with
> + * the License.  You may obtain a copy of the License at
> + *
> + *      http://www.apache.org/licenses/LICENSE-2.0
> + *
> + * Unless required by applicable law or agreed to in writing, software
> + * distributed under the License is distributed on an "AS IS" BASIS,
> + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
> + * See the License for the specific language governing permissions and
> + * limitations under the License.
> + */
> +package org.apache.commons.monitoring.jpa.entity;
> +
> +import javax.persistence.Entity;
> +import javax.persistence.GeneratedValue;
> +import javax.persistence.Id;
> +import javax.persistence.ManyToOne;
> +
> +@Entity
> +public class Address {
> +    @Id
> +    @GeneratedValue
> +    private long id;
> +    private String street;
> +
> +    @ManyToOne
> +    private Person person;
> +
> +    public long getId() {
> +        return id;
> +    }
> +
> +    public String getStreet() {
> +        return street;
> +    }
> +
> +    public void setStreet(final String street) {
> +        this.street = street;
> +    }
> +
> +    public Person getPerson() {
> +        return person;
> +    }
> +
> +    public void setPerson(final Person person) {
> +        this.person = person;
> +    }
> +}
>
> Added: commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Person.java
> URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Person.java?rev=1534546&view=auto
> ==============================================================================
> --- commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Person.java (added)
> +++ commons/sandbox/monitoring/trunk/jpa/src/test/java/org/apache/commons/monitoring/jpa/entity/Person.java Tue Oct 22 09:07:48 2013
> @@ -0,0 +1,55 @@
> +/*
> + * 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.commons.monitoring.jpa.entity;
> +
> +import javax.persistence.CascadeType;
> +import javax.persistence.Entity;
> +import javax.persistence.GeneratedValue;
> +import javax.persistence.Id;
> +import javax.persistence.NamedQuery;
> +import javax.persistence.OneToMany;
> +import java.util.LinkedList;
> +import java.util.List;
> +
> +@Entity
> +@NamedQuery(name = "Person.findByName", query = "select p from Person p where p.name = :name")
> +public class Person {
> +    @Id
> +    @GeneratedValue
> +    private long id;
> +
> +    private String name;
> +
> +    @OneToMany(cascade = { CascadeType.ALL }, mappedBy = "person")
> +    private List<Address> addresses = new LinkedList<Address>();
> +
> +    public long getId() {
> +        return id;
> +    }
> +
> +    public String getName() {
> +        return name;
> +    }
> +
> +    public void setName(final String name) {
> +        this.name = name;
> +    }
> +
> +    public List<Address> getAddresses() {
> +        return addresses;
> +    }
> +}
>
> Added: commons/sandbox/monitoring/trunk/jpa/src/test/resources/META-INF/persistence.xml
> URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/jpa/src/test/resources/META-INF/persistence.xml?rev=1534546&view=auto
> ==============================================================================
> --- commons/sandbox/monitoring/trunk/jpa/src/test/resources/META-INF/persistence.xml (added)
> +++ commons/sandbox/monitoring/trunk/jpa/src/test/resources/META-INF/persistence.xml Tue Oct 22 09:07:48 2013
> @@ -0,0 +1,50 @@
> +<?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.
> +  -->
> +<persistence version="2.0"
> +             xmlns="http://java.sun.com/xml/ns/persistence"
> +             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
> +             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
> +                       http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
> +  <persistence-unit name="test-jse">
> +    <provider>org.apache.commons.monitoring.jpa.MonitoringPersistence</provider>
> +    <class>org.apache.commons.monitoring.jpa.entity.Person</class>
> +    <class>org.apache.commons.monitoring.jpa.entity.Address</class>
> +    <properties>
> +      <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
> +      <property name="openjpa.ConnectionURL" value="jdbc:hsqldb:mem:jpa;create=true"/>
> +      <property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver"/>
> +      <property name="openjpa.ConnectionUserName" value="sa"/>
> +      <property name="openjpa.ConnectionPassword" value=""/>
> +      <property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO, SQL=INFO"/>
> +    </properties>
> +  </persistence-unit>
> +  <persistence-unit name="test-jta">
> +    <provider>org.apache.commons.monitoring.jpa.MonitoringPersistence</provider>
> +    <class>org.apache.commons.monitoring.jpa.entity.Person</class>
> +    <class>org.apache.commons.monitoring.jpa.entity.Address</class>
> +    <properties>
> +      <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
> +      <property name="openjpa.ConnectionURL" value="jdbc:hsqldb:mem:jpa;create=true"/>
> +      <property name="openjpa.ConnectionDriverName" value="org.hsqldb.jdbcDriver"/>
> +      <property name="openjpa.ConnectionUserName" value="sa"/>
> +      <property name="openjpa.ConnectionPassword" value=""/>
> +      <property name="openjpa.RuntimeUnenhancedClasses" value="supported"/>
> +      <property name="openjpa.Log" value="DefaultLevel=WARN, Tool=INFO, SQL=INFO"/>
> +    </properties>
> +  </persistence-unit>
> +</persistence>
>
> Modified: commons/sandbox/monitoring/trunk/pom.xml
> URL: http://svn.apache.org/viewvc/commons/sandbox/monitoring/trunk/pom.xml?rev=1534546&r1=1534545&r2=1534546&view=diff
> ==============================================================================
> --- commons/sandbox/monitoring/trunk/pom.xml (original)
> +++ commons/sandbox/monitoring/trunk/pom.xml Tue Oct 22 09:07:48 2013
> @@ -58,6 +58,7 @@
>      <module>graphite</module>
>      <module>cube</module>
>      <module>collector</module>
> +    <module>jpa</module>
>    </modules>
>
>    <developers>
> @@ -163,6 +164,12 @@
>          <scope>test</scope>
>        </dependency>
>        <dependency>
> +        <groupId>org.hsqldb</groupId>
> +        <artifactId>hsqldb</artifactId>
> +        <version>2.2.9</version>
> +        <scope>test</scope>
> +      </dependency>
> +      <dependency>
>          <groupId>org.apache.geronimo.specs</groupId>
>          <artifactId>geronimo-servlet_3.0_spec</artifactId>
>          <version>1.0</version>
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org