Author: simoneg
Date: Wed May 18 23:32:18 2011
New Revision: 1124464

URL: http://svn.apache.org/viewvc?rev=1124464&view=rev
Log:
Keep track of removed entities, to implement orphan removal and to persist 
entities modified before being detached from the main graph

Modified:
    
labs/magma/trunk/database-mongodb/src/main/java/org/apache/magma/database/mongo/MongoEntityLazyRelations.aj
    
labs/magma/trunk/database-mongodb/src/main/java/org/apache/magma/database/mongo/MongoEntityTransactionMethods.aj
    
labs/magma/trunk/database-mongodb/src/main/java/org/apache/magma/database/mongo/PropertyInfoAdditions.aj
    
labs/magma/trunk/database-mongodb/src/main/java/org/apache/magma/database/mongo/Transaction.java

Modified: 
labs/magma/trunk/database-mongodb/src/main/java/org/apache/magma/database/mongo/MongoEntityLazyRelations.aj
URL: 
http://svn.apache.org/viewvc/labs/magma/trunk/database-mongodb/src/main/java/org/apache/magma/database/mongo/MongoEntityLazyRelations.aj?rev=1124464&r1=1124463&r2=1124464&view=diff
==============================================================================
--- 
labs/magma/trunk/database-mongodb/src/main/java/org/apache/magma/database/mongo/MongoEntityLazyRelations.aj
 (original)
+++ 
labs/magma/trunk/database-mongodb/src/main/java/org/apache/magma/database/mongo/MongoEntityLazyRelations.aj
 Wed May 18 23:32:18 2011
@@ -3,6 +3,7 @@ package org.apache.magma.database.mongo;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
@@ -95,7 +96,11 @@ public aspect MongoEntityLazyRelations {
                bh.setValue(pi.getName(), ret);
                bh.commit();                    
 
-               bean.loaded(pi.getName());
+               if (dynamic) {
+                       bean.loaded(pi.getName(), collection);
+               } else {
+                       bean.loaded(pi.getName(), (Collection)null);
+               }
                return ret;
        }
 
@@ -130,7 +135,13 @@ public aspect MongoEntityLazyRelations {
                bh.setValue(pi.getName(), ret);
                bh.commit();                    
                
-               bean.loaded(pi.getName());
+               Class valclazz = pi.getMapValueClass();
+               if (MongoEntity.class.isAssignableFrom(valclazz)) {
+                       bean.loaded(pi.getName(), collection.values());         
        
+               } else {
+                       bean.loaded(pi.getName(), (Collection)null);            
        
+               }
+               
                return ret;
        }
        
@@ -167,24 +178,55 @@ public aspect MongoEntityLazyRelations {
                        BeanHandler bh = bean.handler();
                        bh.setValue(pi.getName(), ret);
                        bh.commit();                    
+                       bean.loaded(pi.getName(), ret);                 
+               } else if (ret != null) {
+                       bean.loaded(pi.getName(), ret);                 
+                       bean.dirtyHandleProperty(pi, ret);
                }
                
-               bean.loaded(pi.getName());                      
                return ret;
        }       
        
        
        // Loadeds properties
-       private Set<String> MongoEntity.loadeds;
+       private Map<String, Set<MongoEntity>> MongoEntity.loadeds;
        
        boolean MongoEntity.isLoaded(String name) {
                if (loadeds == null) return false;
-               return loadeds.contains(name);
+               return loadeds.containsKey(name);
+       }
+       
+       Collection<MongoEntity> MongoEntity.getLoaded(String name) {
+               if (loadeds == null) return Collections.emptyList();
+               Collection<MongoEntity> ret =loadeds.get(name);
+               if (ret == null) return Collections.emptyList();
+               return ret;
        }
        
-       void MongoEntity.loaded(String name) {
-               if (loadeds == null) loadeds = new HashSet<String>();
-               loadeds.add(name);
+       Set<Map.Entry<String, Set<MongoEntity>>> MongoEntity.getLoadedsEntry() {
+               if (loadeds == null) return Collections.EMPTY_SET;
+               return loadeds.entrySet();
+       }
+       
+       void MongoEntity.loaded(String name, MongoEntity previous) {
+               if (previous != null) {
+                       this.loaded(name, Arrays.asList(previous));
+               } else {
+                       this.loaded(name, (Collection)null);
+               }
+       }
+       void MongoEntity.loaded(String name, Collection<MongoEntity> previous) {
+               if (loadeds == null) loadeds = new 
HashMap<String,Set<MongoEntity>>();
+               Set<MongoEntity> entities = loadeds.get(name);
+               if (previous != null) {
+                       if (entities == null) {
+                               entities = new HashSet<MongoEntity>();
+                               loadeds.put(name, entities);
+                       }
+                       entities.addAll(previous);
+               } else {
+                       loadeds.put(name, null);
+               }
        }
        
        

Modified: 
labs/magma/trunk/database-mongodb/src/main/java/org/apache/magma/database/mongo/MongoEntityTransactionMethods.aj
URL: 
http://svn.apache.org/viewvc/labs/magma/trunk/database-mongodb/src/main/java/org/apache/magma/database/mongo/MongoEntityTransactionMethods.aj?rev=1124464&r1=1124463&r2=1124464&view=diff
==============================================================================
--- 
labs/magma/trunk/database-mongodb/src/main/java/org/apache/magma/database/mongo/MongoEntityTransactionMethods.aj
 (original)
+++ 
labs/magma/trunk/database-mongodb/src/main/java/org/apache/magma/database/mongo/MongoEntityTransactionMethods.aj
 Wed May 18 23:32:18 2011
@@ -3,7 +3,10 @@ package org.apache.magma.database.mongo;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Collection;
 
+import org.apache.commons.beanutils.PropertyUtils;
+import org.apache.magma.beans.BeanHandler;
 import org.apache.magma.beans.PropertyInfo;
 import org.aspectj.lang.reflect.MethodSignature;
 
@@ -70,11 +73,14 @@ public aspect MongoEntityTransactionMeth
                                bean.dirtied();
                        } else if (pi.isSubEntity()) {
                                // TODO persist of an embedded doc
-                       } else if (pi.isBasicType() || pi.isMongoPersisted() || 
(pi.getType() != null && Enum.class.isAssignableFrom(pi.getType()))) {
+                       } else if (pi.isBasicType() || (pi.getType() != null && 
Enum.class.isAssignableFrom(pi.getType()))) {
                                // Basic types goes straight
                                bean.checkGetBson().put(pi.getJpaColName(), 
MongoUtils.convertToMongo(val));
                                bean.dirtyModified(pi, 
MongoUtils.convertToMongo(val));
-                               bean.loaded(pi.getName());
+                       } else if (pi.isMongoPersisted()) {
+                               if (!bean.isLoaded(pi.getName())) 
bean.loaded(pi.getName(), (Collection)null);
+                               bean.checkGetBson().put(pi.getJpaColName(), 
MongoUtils.convertToMongo(val));
+                               bean.dirtyModified(pi, 
MongoUtils.convertToMongo(val));                         
                        } else if (pi.isCollection()) {
                                // TODO change in collection!
                                throw new UnsupportedOperationException();
@@ -82,14 +88,24 @@ public aspect MongoEntityTransactionMeth
                }               
        }
        
-       after(MongoEntity bean, Object val) :
-               execution(* *.set*(..)) 
+       
+       void around(MongoEntity bean, Object val) :
+               execution(void *.set*(..)) 
                && !MongoEntityOps.mongoOps()
                && this(bean)
                && args(val)
        {
                Method method = 
((MethodSignature)thisJoinPointStaticPart.getSignature()).getMethod();
                PropertyInfo pi = bean.beanData().findProperty(method);
+               if (pi.isMongoPersisted() && !pi.isMap() && !pi.isCollection() 
&& !bean.isLoaded(pi.getName()) && pi.isReadable()) {
+                       // Force a load to store previous bean if any
+                       try {
+                               PropertyUtils.getProperty(bean, pi.getName());
+                       } catch (Exception e) {
+                               // Should never happen
+                       }
+               }
+               proceed(bean, val);
                bean.dirtyHandleProperty(pi, val);
        }
        

Modified: 
labs/magma/trunk/database-mongodb/src/main/java/org/apache/magma/database/mongo/PropertyInfoAdditions.aj
URL: 
http://svn.apache.org/viewvc/labs/magma/trunk/database-mongodb/src/main/java/org/apache/magma/database/mongo/PropertyInfoAdditions.aj?rev=1124464&r1=1124463&r2=1124464&view=diff
==============================================================================
--- 
labs/magma/trunk/database-mongodb/src/main/java/org/apache/magma/database/mongo/PropertyInfoAdditions.aj
 (original)
+++ 
labs/magma/trunk/database-mongodb/src/main/java/org/apache/magma/database/mongo/PropertyInfoAdditions.aj
 Wed May 18 23:32:18 2011
@@ -1,6 +1,8 @@
 package org.apache.magma.database.mongo;
 
 import java.beans.PropertyDescriptor;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 
 import javax.persistence.CascadeType;
@@ -48,6 +50,7 @@ public aspect PropertyInfoAdditions {
        
        private JpaRelations PropertyInfo.jpaRelation = null;
        private CascadeType[] PropertyInfo.jpaCascade = null;
+       private boolean PropertyInfo.jpaDeleteOrphans = false;
        private String PropertyInfo.jpaMappedBy = null;
        
        
@@ -83,6 +86,10 @@ public aspect PropertyInfoAdditions {
                return this.jpaRelation;
        }
        
+       public boolean PropertyInfo.isJpaDeleteOrphans() {
+               return this.jpaDeleteOrphans;
+       }
+       
        
        after(PropertyInfo info, PropertyDescriptor desc, Class beanClass) : 
                execution(* PropertyInfo.init(PropertyDescriptor, Class)) 
@@ -120,6 +127,7 @@ public aspect PropertyInfoAdditions {
                                info.jpaCascade = assoc.cascade();
                                info.jpaRelation = JpaRelations.OneToOne;
                                info.jpaMappedBy = assoc.mappedBy();
+                               info.jpaDeleteOrphans |= 
checkOrphanRemoval(assoc);
                        }
                }
 
@@ -129,6 +137,7 @@ public aspect PropertyInfoAdditions {
                                info.jpaCascade = assoc.cascade();
                                info.jpaRelation = JpaRelations.OneToMany;
                                info.jpaMappedBy = assoc.mappedBy();
+                               info.jpaDeleteOrphans |= 
checkOrphanRemoval(assoc);
                        }
                }
        
@@ -137,6 +146,7 @@ public aspect PropertyInfoAdditions {
                        if (assoc != null) {
                                info.jpaCascade = assoc.cascade();
                                info.jpaRelation = JpaRelations.ManyToMany;     
                        
+                               info.jpaDeleteOrphans |= 
checkOrphanRemoval(assoc);
                        }
                }
 
@@ -146,9 +156,39 @@ public aspect PropertyInfoAdditions {
                                info.jpaCascade = assoc.cascade();
                                info.jpaRelation = JpaRelations.ManyToOne;      
                        
                                info.jpaMappedBy = assoc.mappedBy();
+                               info.jpaDeleteOrphans |= 
checkOrphanRemoval(assoc);
                        }
                }
                
-       }       
+               if (!info.jpaDeleteOrphans) {
+                       Annotation[] anns = rm.getAnnotations();
+                       for (Annotation ann : anns) {
+                               info.jpaDeleteOrphans |= 
ann.annotationType().getName().equals("org.apache.openjpa.persistence.ElementDependent");
+                               // TODO eventually parse also other old ORM 
specific options
+                       }
+               }
+       }
+       
+       private boolean checkOrphanRemoval(Annotation a) {
+               Method meth = null;
+               try {
+                       meth = a.getClass().getMethod("orphanRemoval");
+               } catch (SecurityException e) {
+                       // TODO maybe we should warn for this one?
+                       return false;
+               } catch (NoSuchMethodException e) {
+                       return false;
+               }
+               if (meth == null) return false;
+               if (!meth.getReturnType().equals(Boolean.TYPE)) return false;
+               try {
+                       return (Boolean)meth.invoke(a);
+               } catch (IllegalAccessException e) {
+                       // TODO maybe we should warn for this one?
+                       return false;
+               } catch (Exception e) {
+                       return false;
+               }
+       }
        
 }

Modified: 
labs/magma/trunk/database-mongodb/src/main/java/org/apache/magma/database/mongo/Transaction.java
URL: 
http://svn.apache.org/viewvc/labs/magma/trunk/database-mongodb/src/main/java/org/apache/magma/database/mongo/Transaction.java?rev=1124464&r1=1124463&r2=1124464&view=diff
==============================================================================
--- 
labs/magma/trunk/database-mongodb/src/main/java/org/apache/magma/database/mongo/Transaction.java
 (original)
+++ 
labs/magma/trunk/database-mongodb/src/main/java/org/apache/magma/database/mongo/Transaction.java
 Wed May 18 23:32:18 2011
@@ -345,16 +345,46 @@ public class Transaction {
        public void commit() {
                MongoDB mdb = this.db.getDb();
                Set<MongoEntity> reallySaving = new HashSet<MongoEntity>();
-               BasicDBObject entlist = new BasicDBObject();
+               Set<MongoEntity> orphans = new HashSet<MongoEntity>();
+               
                for (MongoEntity ent : this.confirmedSave) {
                        if (!ent.isDirty()) continue;
                        TransactionPart part = ent.getPart();
                        if (part == null) continue;
+                       reallySaving.add(ent);
+               }
+               
+               // TODO this should be acycle, what if a dirty loaded is inside 
another dirty loaded and so on?
+               // Add dirty loadeds of really saving entities and orphans to 
delete
+               Set<MongoEntity> discovereds = new HashSet<MongoEntity>();
+               for (MongoEntity ent : reallySaving) {
+                       Set<Map.Entry<String, Set<MongoEntity>>> loadeds = 
ent.getLoadedsEntry();
+                       for (Map.Entry<String, Set<MongoEntity>> loaded : 
loadeds) {
+                               Set<MongoEntity> oldents = loaded.getValue();
+                               if (oldents == null || oldents.size() == 0) 
continue;
+                               PropertyInfo loadedpi = 
ent.beanData().getProperty(loaded.getKey());
+                               if (loadedpi.isMongoPersisted()) {
+                                       if (loadedpi.isJpaDeleteOrphans()) {
+                                               // FIXME list all orphans
+                                       } else {
+                                               for (MongoEntity oldent : 
oldents) {
+                                                       if (oldent.isFromDb())
+                                                               
discovereds.add(oldent);
+                                               }
+                                       }
+                               }
+                       }
+               }       
+               reallySaving.addAll(discovereds);
+               
+               if (reallySaving.size() == 0) return;
+               
+               
+               BasicDBObject entlist = new BasicDBObject();
+               for (MongoEntity ent : reallySaving) {
                        MongoCollection coll = getCollection(ent.getClass());
                        String id = MongoUtils.getMongoId(ent);
                        
-                       reallySaving.add(ent);
-                       
                        BasicDBList colllist = (BasicDBList) 
entlist.get(coll.getName());
                        if (colllist == null) {
                                colllist = new BasicDBList();
@@ -362,7 +392,7 @@ public class Transaction {
                        }
                        colllist.add(id);
                }
-               if (reallySaving.size() == 0) return;
+               // FIXME also add orphans to entlist
                
                MongoCollection trcoll = getCollection("transactions");
                BasicDBObject mydbo = new BasicDBObject();



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to