package oasis.jongo;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import oasis.model.annotations.Id;

public class OasisIdHelper {
  private static final Map<Class<?>, Field> oasisFieldCache = new HashMap<>();

  public static void updateOasisIdField(Object target) {
    Field idField = OasisIdHelper.findOasisIdField(target.getClass());
    if (idField != null) {
      if (!idField.getType().equals(String.class)) {
        throw new IllegalArgumentException("Unable to set Oasis Id on class: " + target.getClass() + " (id field is not a String)");
      }

      idField.setAccessible(true);
      try {
        if (idField.get(target) == null) {
          idField.set(target, UUID.randomUUID().toString());
        }
      } catch (IllegalAccessException e) {
        throw new IllegalArgumentException("Unable to set Oasis Id on class: " + target.getClass() + " (id field is not accessible)");
      }
    }
  }

  static Field findOasisIdField(Class<?> clazz) {
    if (oasisFieldCache.containsKey(clazz)) {
      return oasisFieldCache.get(clazz);
    }

    while (!Object.class.equals(clazz)) {
      for (Field f : clazz.getDeclaredFields()) {
        if (f.isAnnotationPresent(Id.class)) {
          oasisFieldCache.put(clazz, f);
          return f;
        }
      }
      clazz = clazz.getSuperclass();
    }
    return null;
  }
}

@@ -1018,24 +1018,137 @@
 ?%3E clazz) %7B%0A
+    if (Object.class == clazz) %7B%0A      return null;%0A    %7D%0A    // XXX: restrict to classes in an oasis.* package?%0A
     if (oasi
@@ -1233,52 +1233,8 @@
  %7D%0A%0A
-    while (!Object.class.equals(clazz)) %7B%0A  
     
@@ -1279,26 +1279,24 @@
 ()) %7B%0A      
-  
 if (f.isAnno
@@ -1318,26 +1318,24 @@
 d.class)) %7B%0A
-  
         oasi
@@ -1365,26 +1365,24 @@
 f);%0A        
-  
 return f;%0A  
@@ -1389,34 +1389,47 @@
     
-  
 %7D%0A    
- 
- 
 %7D%0A    
- 
- clazz = 
+Field f = findOasisIdField(
 claz
@@ -1445,23 +1445,53 @@
 rclass()
+)
 ;%0A    
-%7D
+oasisFieldCache.put(clazz, f);
 %0A    ret
@@ -1490,24 +1490,21 @@
 %0A    return 
-null
+f
 ;%0A  %7D%0A%7D%0A

Optimize OasisIdHelper a bit.