r6983 - in dumbhippo/trunk/server: src/com/dumbhippo/dm src/com/dumbhippo/dm/schema src/com/dumbhippo/server/dm tests/com/dumbhippo/dm
- From: commits mugshot org
- To: online-desktop-list gnome org
- Subject: r6983 - in dumbhippo/trunk/server: src/com/dumbhippo/dm src/com/dumbhippo/dm/schema src/com/dumbhippo/server/dm tests/com/dumbhippo/dm
- Date: Thu, 6 Dec 2007 17:29:43 -0600 (CST)
Author: otaylor
Date: 2007-12-06 17:29:41 -0600 (Thu, 06 Dec 2007)
New Revision: 6983
Added:
dumbhippo/trunk/server/src/com/dumbhippo/dm/DMInjectionLookup.java
Modified:
dumbhippo/trunk/server/src/com/dumbhippo/dm/DataModel.java
dumbhippo/trunk/server/src/com/dumbhippo/dm/schema/DMClassHolder.java
dumbhippo/trunk/server/src/com/dumbhippo/dm/schema/DMPropertyHolder.java
dumbhippo/trunk/server/src/com/dumbhippo/server/dm/DataService.java
dumbhippo/trunk/server/tests/com/dumbhippo/dm/FilterCompilerTests.java
dumbhippo/trunk/server/tests/com/dumbhippo/dm/TestSupport.java
Log:
DMClassHolder DMPropertyHolder: Don't add inherited properties in
base classes multiple times
DMInjectionLookup DataModel DMClassHolder: Allow users of the data
model to custom injection.
DataService DMClassHolder: Move @EJB handling to DataService, add
handling of @WebServiceCache.
TestSupport FilterCompilerTests: Adapt to new signature of DataModel
constructor
Added: dumbhippo/trunk/server/src/com/dumbhippo/dm/DMInjectionLookup.java
===================================================================
--- dumbhippo/trunk/server/src/com/dumbhippo/dm/DMInjectionLookup.java 2007-12-06 22:27:23 UTC (rev 6982)
+++ dumbhippo/trunk/server/src/com/dumbhippo/dm/DMInjectionLookup.java 2007-12-06 23:29:41 UTC (rev 6983)
@@ -0,0 +1,41 @@
+package com.dumbhippo.dm;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * This interface allows system creating a DataModel to customize how property
+ * injection for DMObject instances works. To process a field for injection,
+ * the following steps are taken:
+ *
+ * A) injectionLookup.getInjectionByAnnotations() is called; if it returns
+ * not-null, that value is used
+ * B) if the @Inject annotation is present:
+ * B1) injectionLookup.getInjectionByType is called; if it returns
+ * not-null, that value is used
+ * B2) default injection types such as DMSession and EntityManager are checked for,
+ * if one is found, the cooresponding value is used
+ * B3) otherwise, an exception is raised
+ * C) any other built-in annotations are checked for
+ */
+public interface DMInjectionLookup {
+ /**
+ * Determine the value to inject into a property based on the annotations of the
+ * property.
+ *
+ * @param valueType the type of the property's value
+ * @param annotations annotations on the property (the field or method)
+ * @return the value to inject into the property, or null if no injection is known
+ * based on the annotations.
+ */
+ Object getInjectionByAnnotations(Class<?> valueType, Annotation[] annotations, DMSession session);
+
+
+ /**
+ * Determine the value to inject into a property annotated with @Inject
+ *
+ * @param valueType the type of the property's value
+ * @return the value to inject into the property, or null if no injection is known for
+ * the type.
+ */
+ Object getInjectionByType(Class<?> valueType, DMSession session);
+}
Modified: dumbhippo/trunk/server/src/com/dumbhippo/dm/DataModel.java
===================================================================
--- dumbhippo/trunk/server/src/com/dumbhippo/dm/DataModel.java 2007-12-06 22:27:23 UTC (rev 6982)
+++ dumbhippo/trunk/server/src/com/dumbhippo/dm/DataModel.java 2007-12-06 23:29:41 UTC (rev 6983)
@@ -36,6 +36,7 @@
private String baseUrl;
private DMSessionMap sessionMap = new DMSessionMapJTA();
private EntityManagerFactory emf = null;
+ private DMInjectionLookup injectionLookup;
private ChangeNotifier notifier;
private Map<Class<?>, DMClassHolder<?,?>> classes = new HashMap<Class<?>, DMClassHolder<?,?>>();
private Map<String, DMClassHolder<?,?>> classesByBase = new HashMap<String, DMClassHolder<?,?>>();
@@ -64,6 +65,7 @@
public DataModel(String baseUrl,
DMSessionMap sessionMap,
EntityManagerFactory emf,
+ DMInjectionLookup injectionLookup,
ChangeNotifier notifier,
Class<? extends DMViewpoint> viewpointClass,
DMViewpoint systemViewpoint) {
@@ -81,6 +83,7 @@
this.sessionMap = sessionMap;
this.emf = emf;
+ this.injectionLookup = injectionLookup;
this.notifier = notifier;
this.viewpointClass = viewpointClass;
this.systemViewpoint = systemViewpoint;
@@ -135,6 +138,10 @@
return emf.createEntityManager();
}
+ public DMInjectionLookup getInjectionLookup() {
+ return injectionLookup;
+ }
+
public DMClassHolder<?, ? extends DMObject<?>> getClassHolder(Class<?> tClass) {
DMClassHolder<?,?> classHolder = classes.get(tClass);
@@ -231,7 +238,7 @@
public DMStore getStore() {
return store;
}
-
+
public long getTimestamp() {
// FIXME: This doesn't fully work in a clustered configuration; we should use
// timestamps/serials from the invalidation protocol instead.
Modified: dumbhippo/trunk/server/src/com/dumbhippo/dm/schema/DMClassHolder.java
===================================================================
--- dumbhippo/trunk/server/src/com/dumbhippo/dm/schema/DMClassHolder.java 2007-12-06 22:27:23 UTC (rev 6982)
+++ dumbhippo/trunk/server/src/com/dumbhippo/dm/schema/DMClassHolder.java 2007-12-06 23:29:41 UTC (rev 6983)
@@ -29,6 +29,7 @@
import com.dumbhippo.GlobalSetup;
import com.dumbhippo.dm.BadIdException;
+import com.dumbhippo.dm.DMInjectionLookup;
import com.dumbhippo.dm.DMObject;
import com.dumbhippo.dm.DMSession;
import com.dumbhippo.dm.DMViewpoint;
@@ -204,22 +205,6 @@
}
}
- public void processInjections(DMSession session, T t) {
- Class<?> clazz = baseClass;
- while (clazz != null) {
- for (Field field : clazz.getDeclaredFields()) {
- if (field.isAnnotationPresent(Inject.class)) {
- injectField(session, t, field);
- } else if (field.isAnnotationPresent(EJB.class)) {
- Object bean = EJBUtil.defaultLookup(field.getType());
- setField(t, field, bean);
- }
- }
-
- clazz = clazz.getSuperclass();
- }
- }
-
public Filter getUncompiledFilter() {
return filter;
}
@@ -302,19 +287,50 @@
}
}
- private void injectField(DMSession session, T t, Field field) {
- if (field.getType() == EntityManager.class) {
- setField(t, field, session.getInjectableEntityManager());
- } else if (field.getType() == DMSession.class) {
- setField(t, field, session);
- } else if (DMViewpoint.class.isAssignableFrom(field.getType())) {
+ public void processInjections(DMSession session, T t) {
+ DMInjectionLookup injectionLookup = model.getInjectionLookup();
+
+ Class<?> clazz = baseClass;
+ while (clazz != null) {
+ for (Field field : clazz.getDeclaredFields()) {
+ Object injection = null;
+
+ if (injectionLookup != null)
+ injection = injectionLookup.getInjectionByAnnotations(field.getType(), field.getAnnotations(), session);
+
+ if (injection == null && field.isAnnotationPresent(Inject.class)) {
+ if (injectionLookup != null)
+ injection = injectionLookup.getInjectionByType(field.getType(), session);
+ if (injection == null)
+ injection = getInjectionByType(field.getType(), session);
+ }
+
+ if (injection != null)
+ setField(t, field, injection);
+
+ if (field.isAnnotationPresent(EJB.class)) {
+ Object bean = EJBUtil.defaultLookup(field.getType());
+ setField(t, field, bean);
+ }
+ }
+
+ clazz = clazz.getSuperclass();
+ }
+ }
+
+ private Object getInjectionByType(Class<?> type, DMSession session) {
+ if (type == EntityManager.class) {
+ return session.getInjectableEntityManager();
+ } else if (type == DMSession.class) {
+ return session;
+ } else if (DMViewpoint.class.isAssignableFrom(type)) {
// We use a isAssignableFrom check here to allow people to @Inject fields
// that are subclasses of DMViewpoint. If the type of the @Inject field
// is a subtype of DMViewpoint not compatible with the the viewpoint of
// the DMSession, then this we'll get a ClassCastException here
- setField(t, field, session.getViewpoint());
+ return session.getViewpoint();
} else {
- throw new RuntimeException("@Inject annotation found field of unknown type " + field.getType().getName());
+ throw new RuntimeException("@Inject annotation found field of unknown type " + type.getName());
}
}
@@ -396,11 +412,15 @@
@SuppressWarnings("unchecked")
DMPropertyHolder<K,T,?> property = (DMPropertyHolder<K,T,?>)parentClassHolder.getProperty(i);
- foundProperties.add(property);
- if (!nameCount.containsKey(property.getName()))
- nameCount.put(property.getName(), 1);
- else
- nameCount.put(property.getName(), 1 + nameCount.get(property.getName()));
+ // Only get properties declared in the parent class, we'll pick up inherited
+ // properties as we walk further up the inheritance chain
+ if (property.getPropertyInfo().getDeclaringType() == parentClass) {
+ foundProperties.add(property);
+ if (!nameCount.containsKey(property.getName()))
+ nameCount.put(property.getName(), 1);
+ else
+ nameCount.put(property.getName(), 1 + nameCount.get(property.getName()));
+ }
}
}
Modified: dumbhippo/trunk/server/src/com/dumbhippo/dm/schema/DMPropertyHolder.java
===================================================================
--- dumbhippo/trunk/server/src/com/dumbhippo/dm/schema/DMPropertyHolder.java 2007-12-06 22:27:23 UTC (rev 6982)
+++ dumbhippo/trunk/server/src/com/dumbhippo/dm/schema/DMPropertyHolder.java 2007-12-06 23:29:41 UTC (rev 6983)
@@ -234,6 +234,10 @@
return annotation.defaultMaxFetch();
}
+ protected PropertyInfo getPropertyInfo() {
+ return propertyInfo;
+ }
+
abstract public Object dehydrate(Object value);
abstract public Object rehydrate(DMViewpoint viewpoint, K key, Object value, DMSession session, boolean filter);
abstract public Object filter(DMViewpoint viewpoint, K key, Object value);
Modified: dumbhippo/trunk/server/src/com/dumbhippo/server/dm/DataService.java
===================================================================
--- dumbhippo/trunk/server/src/com/dumbhippo/server/dm/DataService.java 2007-12-06 22:27:23 UTC (rev 6982)
+++ dumbhippo/trunk/server/src/com/dumbhippo/server/dm/DataService.java 2007-12-06 23:29:41 UTC (rev 6983)
@@ -1,5 +1,8 @@
package com.dumbhippo.server.dm;
+import java.lang.annotation.Annotation;
+
+import javax.ejb.EJB;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.ObjectMessage;
@@ -13,6 +16,8 @@
import com.dumbhippo.Site;
import com.dumbhippo.dm.ChangeNotificationSet;
import com.dumbhippo.dm.ChangeNotifier;
+import com.dumbhippo.dm.DMInjectionLookup;
+import com.dumbhippo.dm.DMSession;
import com.dumbhippo.dm.DMSessionMapJTA;
import com.dumbhippo.dm.DataModel;
import com.dumbhippo.dm.JBossInjectableEntityManagerFactory;
@@ -26,6 +31,8 @@
import com.dumbhippo.server.util.EJBUtil;
import com.dumbhippo.server.views.SystemViewpoint;
import com.dumbhippo.server.views.Viewpoint;
+import com.dumbhippo.services.caches.CacheFactory;
+import com.dumbhippo.services.caches.WebServiceCache;
public class DataService extends ServiceMBeanSupport implements DataServiceMBean, ChangeNotifier {
static public final String TOPIC_NAME = "topic/DataModelTopic";
@@ -38,6 +45,25 @@
private Thread topicConsumerThread;
private static DataService instance;
+
+ private class InjectionLookup implements DMInjectionLookup {
+ public Object getInjectionByAnnotations(Class<?> valueType, Annotation[] annotations, DMSession session) {
+ for (Annotation annotation : annotations) {
+ if (annotation instanceof EJB)
+ return EJBUtil.defaultLookup(valueType);
+ else if (annotation instanceof WebServiceCache) {
+ CacheFactory cacheFactory = EJBUtil.defaultLookup(CacheFactory.class);
+ return cacheFactory.lookup(valueType);
+ }
+ }
+
+ return null;
+ }
+
+ public Object getInjectionByType(Class<?> valueType, DMSession session) {
+ return null;
+ }
+ }
// This service is started before HippoService, which sets up the tree cache and updates db schemas.
// Thus, don't try to use the database in here.
Modified: dumbhippo/trunk/server/tests/com/dumbhippo/dm/FilterCompilerTests.java
===================================================================
--- dumbhippo/trunk/server/tests/com/dumbhippo/dm/FilterCompilerTests.java 2007-12-06 22:27:23 UTC (rev 6982)
+++ dumbhippo/trunk/server/tests/com/dumbhippo/dm/FilterCompilerTests.java 2007-12-06 23:29:41 UTC (rev 6983)
@@ -31,7 +31,7 @@
protected void setUp() {
// The model is only used for the viewpoint class and the class pool; we don't
// want to set up a real model, because we want to avoid compiling filters.
- model = new DataModel("http://mugshot.org", null, null, null,
+ model = new DataModel("http://mugshot.org", null, null, null, null,
TestViewpoint.class, new TestViewpoint(null));
}
Modified: dumbhippo/trunk/server/tests/com/dumbhippo/dm/TestSupport.java
===================================================================
--- dumbhippo/trunk/server/tests/com/dumbhippo/dm/TestSupport.java 2007-12-06 22:27:23 UTC (rev 6982)
+++ dumbhippo/trunk/server/tests/com/dumbhippo/dm/TestSupport.java 2007-12-06 23:29:41 UTC (rev 6983)
@@ -36,7 +36,7 @@
model = new DataModel("http://mugshot.org",
new TestSessionMap(delegateEmf),
testEmf,
- null,
+ null, null,
TestViewpoint.class,
new TestViewpoint(null));
model.addDMClass(TestUserDMO.class);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]