Author: rmannibucau
Date: Sun Jul 31 18:09:54 2011
New Revision: 1152606
URL: http://svn.apache.org/viewvc?rev=1152606&view=rev
Log:
adding @Repository - first version - todo: enhance it
Added:
openejb/trunk/openejb3/container/openejb-api/src/main/java/org/apache/openejb/api/Repository.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/QueryProxy.java
Modified:
openejb/trunk/openejb3/container/openejb-api/pom.xml
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EjbJarInfo.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/EjbModule.java
Modified: openejb/trunk/openejb3/container/openejb-api/pom.xml
URL:
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-api/pom.xml?rev=1152606&r1=1152605&r2=1152606&view=diff
==============================================================================
--- openejb/trunk/openejb3/container/openejb-api/pom.xml (original)
+++ openejb/trunk/openejb3/container/openejb-api/pom.xml Sun Jul 31 18:09:54
2011
@@ -25,10 +25,18 @@
<groupId>org.apache.openejb</groupId>
<version>4.0.0-SNAPSHOT</version>
</parent>
+
<modelVersion>4.0.0</modelVersion>
<artifactId>openejb-api</artifactId>
- <packaging>jar</packaging>
<name>OpenEJB :: Container :: API</name>
+ <dependencies>
+ <dependency>
+ <groupId>org.apache.geronimo.specs</groupId>
+ <artifactId>geronimo-jpa_2.0_spec</artifactId>
+ <version>1.1</version>
+ <scope>provided</scope>
+ </dependency>
+ </dependencies>
</project>
Added:
openejb/trunk/openejb3/container/openejb-api/src/main/java/org/apache/openejb/api/Repository.java
URL:
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-api/src/main/java/org/apache/openejb/api/Repository.java?rev=1152606&view=auto
==============================================================================
---
openejb/trunk/openejb3/container/openejb-api/src/main/java/org/apache/openejb/api/Repository.java
(added)
+++
openejb/trunk/openejb3/container/openejb-api/src/main/java/org/apache/openejb/api/Repository.java
Sun Jul 31 18:09:54 2011
@@ -0,0 +1,18 @@
+package org.apache.openejb.api;
+
+import javax.persistence.PersistenceContext;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ * @author rmannibucau
+ */
+@Target({ ElementType.TYPE })
+@Retention(RetentionPolicy.RUNTIME)
+public @interface Repository {
+ PersistenceContext context() default @PersistenceContext;
+ String jndiName() default "";
+}
+
Modified:
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
URL:
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java?rev=1152606&r1=1152605&r2=1152606&view=diff
==============================================================================
---
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
(original)
+++
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/Assembler.java
Sun Jul 31 18:09:54 2011
@@ -32,6 +32,7 @@ import org.apache.openejb.NoSuchApplicat
import org.apache.openejb.OpenEJB;
import org.apache.openejb.OpenEJBException;
import org.apache.openejb.UndeployException;
+import org.apache.openejb.api.Repository;
import org.apache.openejb.cdi.CdiBuilder;
import org.apache.openejb.core.ConnectorReference;
import org.apache.openejb.core.CoreContainerSystem;
@@ -54,20 +55,14 @@ import org.apache.openejb.core.transacti
import org.apache.openejb.javaagent.Agent;
import org.apache.openejb.loader.Options;
import org.apache.openejb.loader.SystemInstance;
+import org.apache.openejb.persistence.JtaEntityManager;
import org.apache.openejb.persistence.JtaEntityManagerRegistry;
import org.apache.openejb.persistence.PersistenceClassLoaderHandler;
import org.apache.openejb.resource.GeronimoConnectionManagerFactory;
-import org.apache.openejb.rest.ThreadLocalContextManager;
import org.apache.openejb.spi.ApplicationServer;
import org.apache.openejb.spi.ContainerSystem;
import org.apache.openejb.spi.SecurityService;
-import org.apache.openejb.util.AsmParameterNameLoader;
-import org.apache.openejb.util.LogCategory;
-import org.apache.openejb.util.Logger;
-import org.apache.openejb.util.Messages;
-import org.apache.openejb.util.OpenEJBErrorHandler;
-import org.apache.openejb.util.References;
-import org.apache.openejb.util.SafeToolkit;
+import org.apache.openejb.util.*;
import org.apache.openejb.util.proxy.ProxyFactory;
import org.apache.openejb.util.proxy.ProxyManager;
import org.apache.webbeans.config.WebBeansContext;
@@ -88,6 +83,10 @@ import javax.naming.NameAlreadyBoundExce
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.persistence.EntityManagerFactory;
+import javax.persistence.PersistenceContext;
+import javax.persistence.PersistenceContextType;
+import javax.persistence.PersistenceProperty;
+import javax.persistence.metamodel.Type;
import javax.resource.spi.BootstrapContext;
import javax.resource.spi.ConnectionManager;
import javax.resource.spi.ManagedConnectionFactory;
@@ -105,21 +104,11 @@ import java.lang.instrument.ClassFileTra
import java.lang.instrument.Instrumentation;
import java.lang.management.ManagementFactory;
import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
import java.net.MalformedURLException;
import java.net.URL;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
+import java.util.*;
import java.util.Map.Entry;
-import java.util.Properties;
-import java.util.Set;
-import java.util.TreeMap;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadFactory;
@@ -152,6 +141,7 @@ public class Assembler extends Assembler
private final Map<String, AppInfo> deployedApplications = new
HashMap<String, AppInfo>();
private final List<DeploymentListener> deploymentListeners = new
ArrayList<DeploymentListener>();
private final Set<String> moduleIds = new HashSet<String>();
+ private final Set<String> repositoryNames = new HashSet<String>();
private static final String GLOBAL_UNIQUE_ID = "global";
@@ -569,11 +559,13 @@ public class Assembler extends Assembler
// JPA - Persistence Units MUST be processed first since they will
add ClassFileTransformers
// to the class loader which must be added before any classes are
loaded
+ Map<String, String> units = new HashMap<String, String>();
PersistenceBuilder persistenceBuilder = new
PersistenceBuilder(persistenceClassLoaderHandler);
for (PersistenceUnitInfo info : appInfo.persistenceUnits) {
try {
EntityManagerFactory factory =
persistenceBuilder.createEntityManagerFactory(info, classLoader);
containerSystem.getJNDIContext().bind(PERSISTENCE_UNIT_NAMING_CONTEXT +
info.id, factory);
+ units.put(info.name, PERSISTENCE_UNIT_NAMING_CONTEXT +
info.id);
} catch (NameAlreadyBoundException e) {
throw new OpenEJBException("PersistenceUnit already
deployed: " + info.persistenceUnitRootUrl);
} catch (Exception e) {
@@ -696,6 +688,48 @@ public class Assembler extends Assembler
}
}
+ // @Repository
+ JtaEntityManagerRegistry jtaEntityManagerRegistry =
SystemInstance.get().getComponent(JtaEntityManagerRegistry.class);
+ for (String repository : ejbJar.repositories) {
+ try {
+ Class<?> proxied = classLoader.loadClass(repository);
+ // TODO: move it in config
+ Repository annotation =
proxied.getAnnotation(Repository.class);
+ PersistenceContext pc = annotation.context();
+
+ // create the em
+ Context context =
SystemInstance.get().getComponent(ContainerSystem.class).getJNDIContext();
+ EntityManagerFactory factory;
+ try {
+ factory = (EntityManagerFactory)
context.lookup(units.get(pc.unitName()));
+ } catch (NamingException e) {
+ throw new OpenEJBException("PersistenceUnit '" +
pc.unitName() + "' not found");
+ }
+ Map<String, String> properties = new
LinkedHashMap<String, String>();
+ for (PersistenceProperty property : pc.properties()) {
+ properties.put(property.name(), property.value());
+ }
+
+ JtaEntityManager jtaEntityManager = new
JtaEntityManager(pc.unitName(), jtaEntityManagerRegistry, factory, properties,
pc.type() == PersistenceContextType.EXTENDED);
+
+ Object proxy = Proxy.newProxyInstance(classLoader,
+ new Class<?>[] { proxied },
+ new QueryProxy(jtaEntityManager));
+
+ String jndi = annotation.jndiName();
+ if (jndi == null || jndi.isEmpty()) {
+ jndi = "openejb/Repository/" + repository;
+ }
+ containerSystemContext.bind(jndi, proxy); // TODO in a
better way
+ repositoryNames.add(jndi);
+ logger.info("Bound @Repository " + repository + " to "
+ jndi);
+ appContext.getGlobalJndiContext().bind("global/" +
jndi, proxy);
+ logger.info("Bound @Repository " + repository + " to
global/" + jndi);
+ } catch (ClassNotFoundException cnfe) {
+ logger.error("cant' instantiate repository interface "
+ repository, cnfe);
+ }
+ }
+
allDeployments.addAll(deployments.values());
}
@@ -1096,6 +1130,16 @@ public class Assembler extends Assembler
}
moduleIds.clear();
+ for (String repoName : repositoryNames) {
+ try {
+ globalContext.unbind(repoName);
+ appContext.getGlobalJndiContext().unbind("global/" + repoName);
+ } catch (NamingException e) {
+ undeployException.getCauses().add(new Exception("repository: "
+ repoName + ": " + e.getMessage(), e));
+ }
+ }
+ repositoryNames.clear();
+
try {
if (globalContext instanceof IvmContext) {
Modified:
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EjbJarInfo.java
URL:
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EjbJarInfo.java?rev=1152606&r1=1152605&r2=1152606&view=diff
==============================================================================
---
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EjbJarInfo.java
(original)
+++
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/assembler/classic/EjbJarInfo.java
Sun Jul 31 18:09:54 2011
@@ -43,5 +43,6 @@ public class EjbJarInfo extends Validati
public final Set<String> watchedResources = new TreeSet<String>();
public final JndiEncInfo moduleJndiEnc = new JndiEncInfo();
- public BeansInfo beans;
+ public BeansInfo beans;
+ public Set<String> repositories = new TreeSet<String>();
}
Modified:
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
URL:
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java?rev=1152606&r1=1152605&r2=1152606&view=diff
==============================================================================
---
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
(original)
+++
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AnnotationDeployer.java
Sun Jul 31 18:09:54 2011
@@ -129,6 +129,7 @@ import org.apache.openejb.BeanContext;
import org.apache.openejb.OpenEJBException;
import org.apache.openejb.api.LocalClient;
import org.apache.openejb.api.RemoteClient;
+import org.apache.openejb.api.Repository;
import org.apache.openejb.cdi.CdiBeanInfo;
import org.apache.openejb.core.webservices.JaxWsUtils;
import org.apache.openejb.jee.ActivationConfig;
@@ -1260,6 +1261,14 @@ public class AnnotationDeployer implemen
}
}
+ //
+ // @Repository
+ //
+ List<Annotated<Class<?>>> repositories =
finder.findMetaAnnotatedClasses(Repository.class);
+ for (Annotated<Class<?>> clazz : repositories) {
+ ejbModule.getRepositories().add(clazz.get().getName());
+ }
+
return ejbModule;
}
Modified:
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java
URL:
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java?rev=1152606&r1=1152605&r2=1152606&view=diff
==============================================================================
---
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java
(original)
+++
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/AppInfoBuilder.java
Sun Jul 31 18:09:54 2011
@@ -169,6 +169,7 @@ class AppInfoBuilder {
ejbJarInfo.validationInfo =
ValidatorBuilder.getInfo(ejbModule.getValidationConfig());
ejbJarInfo.portInfos.addAll(configureWebservices(ejbModule.getWebservices()));
ejbJarInfo.uniqueId = ejbModule.getUniqueId();
+ ejbJarInfo.repositories = ejbModule.getRepositories();
configureWebserviceSecurity(ejbJarInfo, ejbModule);
ejbJarInfos.put(ejbModule, ejbJarInfo);
Modified:
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/EjbModule.java
URL:
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/EjbModule.java?rev=1152606&r1=1152605&r2=1152606&view=diff
==============================================================================
---
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/EjbModule.java
(original)
+++
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/config/EjbModule.java
Sun Jul 31 18:09:54 2011
@@ -55,6 +55,8 @@ public class EjbModule extends Module im
private ClientModule clientModule;
private ID id;
+ private final Set<String> repositories = new TreeSet<String>();
+
public EjbModule(EjbJar ejbJar) {
this(Thread.currentThread().getContextClassLoader(), null, ejbJar,
null);
}
@@ -182,6 +184,10 @@ public class EjbModule extends Module im
return watchedResources;
}
+ public Set<String> getRepositories() {
+ return repositories;
+ }
+
@Override
public String toString() {
return "EjbModule{" +
Added:
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/QueryProxy.java
URL:
http://svn.apache.org/viewvc/openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/QueryProxy.java?rev=1152606&view=auto
==============================================================================
---
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/QueryProxy.java
(added)
+++
openejb/trunk/openejb3/container/openejb-core/src/main/java/org/apache/openejb/util/QueryProxy.java
Sun Jul 31 18:09:54 2011
@@ -0,0 +1,109 @@
+package org.apache.openejb.util;
+
+import org.apache.commons.lang.StringUtils;
+
+import javax.persistence.EntityManager;
+import javax.persistence.Query;
+import javax.persistence.criteria.*;
+import javax.persistence.metamodel.EntityType;
+import javax.persistence.metamodel.SingularAttribute;
+import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.Method;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+ * @author rmannibucau
+ */
+public class QueryProxy implements InvocationHandler {
+ public static final String FIND_PREFIX = "find";
+
+ private final Map<String, Class<?>> RETURN_TYPES = new
ConcurrentHashMap<String, Class<?>>();
+ private final Map<String, List<String>> CONDITIONS = new
ConcurrentHashMap<String, List<String>>();
+
+ private EntityManager em;
+
+ public QueryProxy(EntityManager entityManager) {
+ em = entityManager;
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args) throws
Throwable {
+ if (!method.getName().startsWith(FIND_PREFIX)) {
+ throw new IllegalArgumentException("finder should start with
find");
+ }
+
+ final String methodName = method.getName();
+ Class<?> type;
+ if (RETURN_TYPES.containsKey(methodName)) {
+ type = RETURN_TYPES.get(methodName);
+ } else {
+ type = getGenericType(method.getGenericReturnType());
+ }
+ Query query = getQuery(em, methodName, type, args);
+ if (Collection.class.isAssignableFrom(method.getReturnType())) {
+ return query.getResultList();
+ }
+ return query.getSingleResult();
+ }
+
+ private Class<?> getGenericType(Type type) {
+ if (type instanceof ParameterizedType) {
+ ParameterizedType pt = (ParameterizedType) type;
+ if ( pt.getActualTypeArguments().length == 1) {
+ return (Class<?>) pt.getActualTypeArguments()[0];
+ }
+ }
+ return (Class<?>) type;
+ }
+
+ private <T> Query getQuery(EntityManager entityManager, String methodName,
Class<T> entityType, Object[] args) {
+ final List<String> conditions = parseMethodName(methodName);
+ final EntityType<T> et =
entityManager.getMetamodel().entity(entityType);
+ final CriteriaBuilder cb = entityManager.getCriteriaBuilder();
+
+ CriteriaQuery<Object> query = cb.createQuery();
+ Root<T> from = query.from(entityType);
+ query = query.select(from);
+
+ int i = 0;
+ for (String condition : conditions) {
+ SingularAttribute<? super T, ?> attribute =
et.getSingularAttribute(condition);
+ Path<?> path = from.get(attribute);
+ Class<?> javaType = attribute.getType().getJavaType();
+ if (javaType.equals(String.class)) {
+ query = query.where(cb.like((Expression<String>) path,
(String) args[i++]));
+ } else if (Number.class.isAssignableFrom(javaType) ||
javaType.isPrimitive()) {
+ query = query.where(cb.equal(path, args[i++]));
+ }
+ }
+
+ return entityManager.createQuery(query);
+ }
+
+ private List<String> parseMethodName(final String methodName) {
+ List<String> parsed;
+ if (CONDITIONS.containsKey(methodName)) {
+ parsed = CONDITIONS.get(methodName);
+ } else {
+ parsed = new ArrayList<String>();
+ String toParse = methodName.substring(FIND_PREFIX.length());
+ // TODO: parsing
+ if (toParse.startsWith("By")) {
+ toParse = StringUtils.uncapitalize(toParse.substring(2));
+ parsed.add(toParse);
+ }
+ CONDITIONS.put(methodName, parsed);
+ }
+ return parsed;
+ }
+
+ @Override
+ public String toString() {
+ return "OpenEJB :: QueryProxy";
+ }
+}