Not logged in.  Login/Logout/Register | List snippets | | Create snippet | Upload image | Upload data

214
LINES

< > BotCompany Repo | #1030885 // RealmCopy - successor of quickExport

JavaX fragment (include) [tags: use-pretranspiled]

Libraryless. Click here for Pure Java version (16206L/105K).

1  
sclass RealmCopy {
2  
  O dest = mc(); // destination realm
3  
  new IdentityHashMap seen;
4  
  new HashMap<Class> classMap;
5  
  new HashMap<Class, L<Field>> fieldsForClass;
6  
  //IF1<S, Class> classFinder = toIF1(_defaultClassFinder());
7  
  bool fullCopy; // descend into objects even when they have the same type
8  
  bool nonTransientOnly; // skip transient fields?
9  
  bool handleEnclosingInstancesProperly; // if false, set enclosing instance to null initially
10  
  
11  
  VStack.Computable copyComputation(O o) {
12  
    ret new CopyObject(o);
13  
  }
14  
  
15  
  O copy(O o) {
16  
    ret evalInVStack(copyComputation(o));
17  
  }
18  
  
19  
  noeq record CopyObject(O o) extends VStackComputableWithStep {
20  
    void step(VStack stack) {
21  
      // null and simple types
22  
      
23  
      if (o == null || o instanceof String || o instanceof Number) {
24  
        ifdef RealmCopy_debug
25  
          print("Simple object: " + o);
26  
        endifdef
27  
        ret with stack.ret(o);
28  
      }
29  
      
30  
      // seen object
31  
32  
      O oo = seen.get(o);
33  
      if (oo != null) stack.ret(oo);
34  
      
35  
      dispatchByType(stack, o);
36  
    }
37  
  }
38  
39  
  void dispatchByType(VStack stack, O o) {  
40  
    if (o cast O[])
41  
      ret with stack.replace(new CopyObjectArray(o));
42  
      
43  
    if (o cast Cl)
44  
      if (!overrideCollectionOrMapCopy(o))
45  
        ret with stack.replace(new CopyCollection(o));
46  
      
47  
    if (o cast Map)
48  
      if (!overrideCollectionOrMapCopy(o))
49  
        ret with stack.replace(new CopyMap(o));
50  
      
51  
    ret with stack.replace(new CopyObjectFieldByField(o));
52  
  }
53  
  
54  
  noeq record CopyObjectArray(O[] o) extends VStackComputableWithStep {
55  
    O[] out;
56  
    int i;
57  
    
58  
    void step(VStack stack) {
59  
      if (step == 0) {
60  
        out = newObjectArrayOfSameType(o);
61  
        seen.put(o, out);
62  
        ++step;
63  
      }
64  
      
65  
      if (stack.hasSubResult())
66  
        out[i++] = stack.subResult();
67  
68  
      if (i >= o.length)
69  
        ret with stack.ret(out);
70  
        
71  
      stack.call(new CopyObject(o[i]));
72  
    }
73  
  }
74  
75  
  noeq record CopyCollection(Cl o) extends VStackComputableWithStep {
76  
    Cl out;
77  
    Iterator it;
78  
    
79  
    void step(VStack stack) {
80  
      if (step == 0) {
81  
        out = similarEmptyCollection(o);
82  
        seen.put(o, out);
83  
        it = iterator(o);
84  
        ++step;
85  
      }
86  
      
87  
      if (stack.hasSubResult())
88  
        out.add(stack.subResult());
89  
90  
      if (!it.hasNext())
91  
        ret with stack.ret(out);
92  
        
93  
      stack.call(new CopyObject(it.next()));
94  
    }
95  
  }
96  
97  
  noeq record CopyMap(Map o) extends VStackComputableWithStep {
98  
    Map out;
99  
    Iterator<Map.Entry> it;
100  
    Map.Entry entry;
101  
    O copiedKey;
102  
    
103  
    void step(VStack stack) {
104  
      if (step == 0) {
105  
        out = similarEmptyMap(o);
106  
        seen.put(o, out);
107  
        it = iterator(o.entrySet());
108  
        ++step;
109  
      }
110  
      
111  
      if (stack.hasSubResult()) {
112  
        if (step == 1) {
113  
          // got the copied key
114  
          copiedKey = stack.subResult();
115  
          // now copy the value
116  
          stack.call(new CopyObject(entry.getValue()));
117  
          ret with ++step;
118  
        } else {
119  
          // got the copied value - can put into map
120  
          out.put(copiedKey, stack.subResult());
121  
          step = 1;
122  
        }
123  
      }
124  
125  
      if (!it.hasNext())
126  
        ret with stack.ret(out);
127  
        
128  
      entry = it.next();
129  
      stack.call(new CopyObject(entry.getKey()));
130  
    }
131  
  }
132  
133  
  noeq record CopyObjectFieldByField(O o) extends VStackComputableWithStep {
134  
    S className;
135  
    Class c, destClass;
136  
    O out;
137  
    O enclosing;
138  
    L<Field> fields;
139  
    Iterator<Field> itField;
140  
    Field field;
141  
    Field[] enclosingFields;
142  
    
143  
    void step(VStack stack) {
144  
      if (step == 0) {
145  
        c = o.getClass();
146  
        
147  
        destClass = classMap.get(c);
148  
        if (destClass == null) {
149  
          destClass = findDestClass(c);
150  
          classMap.put(c, destClass);
151  
        }
152  
153  
        if (destClass == c && !fullCopy)
154  
          ret with stack.ret(o); // short cut unless deep copying
155  
        
156  
        // take care of enclosing instance
157  
        
158  
        enclosingFields = thisDollarOneFields(c);
159  
        if (handleEnclosingInstancesProperly
160  
          && nempty(enclosingFields))
161  
          stack.push(new CopyObject(fieldGet(first(enclosingFields), o)));
162  
163  
        ret with step = 1;
164  
      } else if (step == 1) {
165  
        // create new object
166  
        
167  
        try {
168  
          if (stack.hasSubResult())
169  
            out = unlisted_gen(destClass, stack.subResult());
170  
          else if (nempty(enclosingFields))
171  
            out = unlisted_gen(destClass, (O) null);
172  
          else
173  
            out = unlisted_gen(destClass);
174  
        } on fail {
175  
          printVars_str(+c, +destClass, +enclosingFields);
176  
        }
177  
        seen.put(o, out);
178  
          
179  
        fields = getOrCreate(fieldsForClass, c, () -> 
180  
          nonTransientOnly
181  
            ? nonStaticNonTransientFieldObjects(o)
182  
            : nonStaticFieldObjects(o));
183  
        itField = iterator(fields);
184  
        
185  
        ret with ++step;
186  
      }
187  
      
188  
      if (stack.hasSubResult()) {
189  
        ifdef RealmCopy_debug
190  
          printFunctionCall setOpt(out, field.getName(), stack.subResult());
191  
        endifdef
192  
        setOpt(out, field.getName(), stack.subResult());
193  
      }
194  
        
195  
      if (!itField.hasNext())
196  
        ret with stack.ret(out);
197  
        
198  
      field = itField.next();
199  
      stack.push(new CopyObject(fieldGet(field, o));
200  
    }
201  
  }
202  
  
203  
  Class findDestClass(Class c) {
204  
    Class destClass = null;
205  
    S className = c.getName();
206  
    className = loadableUtilsClassNameToMain(className);
207  
    if (!isAnonymousClassName(className))
208  
      destClass = getClass_vmName_withLoadableUtils(dest, className);
209  
    ret or(destClass, c);
210  
  }
211  
212  
  // set to true if you want to copy a map or collection field-by-field
213  
  swappable bool overrideCollectionOrMapCopy(O o) { false; }
214  
}

Author comment

Began life as a copy of #1002777

download  show line numbers  debug dex  old transpilations   

Travelled to 4 computer(s): bhatertpkbcr, mqqgnosmbjvj, pyentgdyhuwx, vouqrxazstgt

No comments. add comment

Snippet ID: #1030885
Snippet name: RealmCopy - successor of quickExport
Eternal ID of this version: #1030885/32
Text MD5: 91fe90d3e2dfef86fbddfbfeb04ea547
Transpilation MD5: 61099b57bd3d8361b89b6913ca601a8c
Author: stefan
Category: eleu / nl
Type: JavaX fragment (include)
Public (visible to everyone): Yes
Archived (hidden from active list): No
Created/modified: 2021-06-23 23:58:50
Source code size: 5955 bytes / 214 lines
Pitched / IR pitched: No / No
Views / Downloads: 259 / 563
Version history: 31 change(s)
Referenced in: [show references]