001/**
002 * Copyright 2014 The Sculptor Project Team, including the original
003 * author or authors.
004 * 
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 * 
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 * 
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.sculptor.generator.cartridge.mongodb;
018
019import com.google.common.base.Objects;
020import java.util.Arrays;
021import java.util.Collection;
022import java.util.List;
023import javax.inject.Inject;
024import org.eclipse.xtend2.lib.StringConcatenation;
025import org.eclipse.xtext.xbase.lib.Extension;
026import org.eclipse.xtext.xbase.lib.Functions.Function1;
027import org.eclipse.xtext.xbase.lib.IterableExtensions;
028import org.eclipse.xtext.xbase.lib.ListExtensions;
029import org.sculptor.generator.cartridge.mongodb.MongoDbHelper;
030import org.sculptor.generator.ext.DbHelper;
031import org.sculptor.generator.ext.Helper;
032import org.sculptor.generator.ext.Properties;
033import org.sculptor.generator.util.HelperBase;
034import org.sculptor.generator.util.OutputSlot;
035import sculptormetamodel.Attribute;
036import sculptormetamodel.BasicType;
037import sculptormetamodel.DomainObject;
038import sculptormetamodel.Inheritance;
039import sculptormetamodel.Module;
040import sculptormetamodel.NamedElement;
041import sculptormetamodel.Reference;
042
043@SuppressWarnings("all")
044public class MongoDbMapperTmpl {
045  @Inject
046  @Extension
047  private MongoDbHelper mongoDbHelper;
048  
049  @Inject
050  @Extension
051  private DbHelper dbHelper;
052  
053  @Inject
054  @Extension
055  private HelperBase helperBase;
056  
057  @Inject
058  @Extension
059  private Helper helper;
060  
061  @Inject
062  @Extension
063  private Properties properties;
064  
065  public String mongoDbMapper(final DomainObject it) {
066    StringConcatenation _builder = new StringConcatenation();
067    {
068      boolean _hasHint = this.helper.hasHint(it, "gapMapper");
069      if (_hasHint) {
070        String _mongoDbMapperSubclass = this.mongoDbMapperSubclass(it);
071        _builder.append(_mongoDbMapperSubclass, "");
072        _builder.newLineIfNotEmpty();
073      }
074    }
075    String _mongoDbMapperBase = this.mongoDbMapperBase(it);
076    _builder.append(_mongoDbMapperBase, "");
077    _builder.newLineIfNotEmpty();
078    return _builder.toString();
079  }
080  
081  public String mongoDbMapperSubclass(final DomainObject it) {
082    Module _module = it.getModule();
083    String _mapperPackage = this.mongoDbHelper.getMapperPackage(_module);
084    String _plus = (_mapperPackage + ".");
085    String _name = it.getName();
086    String _plus_1 = (_plus + _name);
087    String _plus_2 = (_plus_1 + "Mapper");
088    String _javaFileName = this.helper.javaFileName(_plus_2);
089    StringConcatenation _builder = new StringConcatenation();
090    String _javaHeader = this.properties.javaHeader();
091    _builder.append(_javaHeader, "");
092    _builder.newLineIfNotEmpty();
093    _builder.append("package ");
094    Module _module_1 = it.getModule();
095    String _mapperPackage_1 = this.mongoDbHelper.getMapperPackage(_module_1);
096    _builder.append(_mapperPackage_1, "");
097    _builder.append(";");
098    _builder.newLineIfNotEmpty();
099    _builder.newLine();
100    _builder.append("/// Sculptor code formatter imports ///");
101    _builder.newLine();
102    _builder.newLine();
103    _builder.append("public class ");
104    String _name_1 = it.getName();
105    _builder.append(_name_1, "");
106    _builder.append("Mapper extends ");
107    String _name_2 = it.getName();
108    _builder.append(_name_2, "");
109    _builder.append("MapperBase {");
110    _builder.newLineIfNotEmpty();
111    String _instance = this.getInstance(it);
112    _builder.append(_instance, "");
113    _builder.newLineIfNotEmpty();
114    String _constructor = this.constructor(it);
115    _builder.append(_constructor, "");
116    _builder.newLineIfNotEmpty();
117    String _gapToDomain = this.gapToDomain(it);
118    _builder.append(_gapToDomain, "");
119    _builder.newLineIfNotEmpty();
120    String _gapToData = this.gapToData(it);
121    _builder.append(_gapToData, "");
122    _builder.newLineIfNotEmpty();
123    _builder.append("}");
124    _builder.newLine();
125    return this.helper.fileOutput(_javaFileName, OutputSlot.TO_SRC, _builder.toString());
126  }
127  
128  public String mongoDbMapperBase(final DomainObject it) {
129    Module _module = it.getModule();
130    String _mapperPackage = this.mongoDbHelper.getMapperPackage(_module);
131    String _plus = (_mapperPackage + ".");
132    String _name = it.getName();
133    String _plus_1 = (_plus + _name);
134    String _plus_2 = (_plus_1 + "Mapper");
135    String _xifexpression = null;
136    boolean _hasHint = this.helper.hasHint(it, "gapMapper");
137    if (_hasHint) {
138      _xifexpression = "Base";
139    } else {
140      _xifexpression = "";
141    }
142    String _plus_3 = (_plus_2 + _xifexpression);
143    String _javaFileName = this.helper.javaFileName(_plus_3);
144    StringConcatenation _builder = new StringConcatenation();
145    String _javaHeader = this.properties.javaHeader();
146    _builder.append(_javaHeader, "");
147    _builder.newLineIfNotEmpty();
148    _builder.append("package ");
149    Module _module_1 = it.getModule();
150    String _mapperPackage_1 = this.mongoDbHelper.getMapperPackage(_module_1);
151    _builder.append(_mapperPackage_1, "");
152    _builder.append(";");
153    _builder.newLineIfNotEmpty();
154    _builder.newLine();
155    _builder.append("/// Sculptor code formatter imports ///");
156    _builder.newLine();
157    _builder.newLine();
158    _builder.append("public ");
159    {
160      boolean _hasHint_1 = this.helper.hasHint(it, "gapMapper");
161      if (_hasHint_1) {
162        _builder.append("abstract ");
163      }
164    }
165    _builder.append("class ");
166    String _name_1 = it.getName();
167    _builder.append(_name_1, "");
168    _builder.append("Mapper");
169    {
170      boolean _hasHint_2 = this.helper.hasHint(it, "gapMapper");
171      if (_hasHint_2) {
172        _builder.append("Base");
173      }
174    }
175    _builder.append(" implements ");
176    String _fw = this.properties.fw("accessimpl.mongodb.DataMapper");
177    _builder.append(_fw, "");
178    _builder.append("<");
179    DomainObject _rootExtends = this.helper.getRootExtends(it);
180    String _domainPackage = this.helperBase.getDomainPackage(_rootExtends);
181    _builder.append(_domainPackage, "");
182    _builder.append(".");
183    DomainObject _rootExtends_1 = this.helper.getRootExtends(it);
184    String _name_2 = _rootExtends_1.getName();
185    _builder.append(_name_2, "");
186    _builder.append(", com.mongodb.DBObject> {");
187    _builder.newLineIfNotEmpty();
188    _builder.newLine();
189    {
190      DomainObject _extends = it.getExtends();
191      boolean _notEquals = (!Objects.equal(_extends, null));
192      if (_notEquals) {
193        String _discriminator = this.discriminator(it);
194        _builder.append(_discriminator, "");
195        _builder.newLineIfNotEmpty();
196      }
197    }
198    _builder.append("\t");
199    _builder.newLine();
200    {
201      boolean _hasHint_3 = this.helper.hasHint(it, "gapMapper");
202      boolean _not = (!_hasHint_3);
203      if (_not) {
204        _builder.append("\t");
205        String _instance = this.getInstance(it);
206        _builder.append(_instance, "\t");
207        _builder.newLineIfNotEmpty();
208      }
209    }
210    _builder.append("\t");
211    _builder.newLine();
212    _builder.append("\t");
213    String _constructorBase = this.constructorBase(it);
214    _builder.append(_constructorBase, "\t");
215    _builder.newLineIfNotEmpty();
216    _builder.append("\t");
217    _builder.newLine();
218    _builder.append("\t");
219    String _canMapToData = this.canMapToData(it);
220    _builder.append(_canMapToData, "\t");
221    _builder.newLineIfNotEmpty();
222    _builder.append("\t");
223    String _dBCollectionName = this.getDBCollectionName(it);
224    _builder.append(_dBCollectionName, "\t");
225    _builder.newLineIfNotEmpty();
226    _builder.append("\t");
227    _builder.newLine();
228    {
229      boolean _or = false;
230      boolean _isAbstract = it.isAbstract();
231      if (_isAbstract) {
232        _or = true;
233      } else {
234        boolean _hasSubClass = this.helper.hasSubClass(it);
235        _or = _hasSubClass;
236      }
237      if (_or) {
238        _builder.append("\t");
239        String _registerSubclassMappers = this.registerSubclassMappers(it);
240        _builder.append(_registerSubclassMappers, "\t");
241        _builder.newLineIfNotEmpty();
242        _builder.append("\t");
243        String _abstractToDomain = this.abstractToDomain(it);
244        _builder.append(_abstractToDomain, "\t");
245        _builder.newLineIfNotEmpty();
246        _builder.append("\t");
247        String _abstractToData = this.abstractToData(it);
248        _builder.append(_abstractToData, "\t");
249        _builder.newLineIfNotEmpty();
250      } else {
251        _builder.append("\t");
252        String _domain = this.toDomain(it);
253        _builder.append(_domain, "\t");
254        _builder.newLineIfNotEmpty();
255        _builder.append("\t");
256        String _data = this.toData(it);
257        _builder.append(_data, "\t");
258        _builder.newLineIfNotEmpty();
259      }
260    }
261    _builder.append("\t");
262    _builder.newLine();
263    _builder.append("\t");
264    String _indexes = this.indexes(it);
265    _builder.append(_indexes, "\t");
266    _builder.newLineIfNotEmpty();
267    _builder.append("\t");
268    _builder.newLine();
269    _builder.append("}");
270    _builder.newLine();
271    return this.helper.fileOutput(_javaFileName, OutputSlot.TO_GEN_SRC, _builder.toString());
272  }
273  
274  public String constructor(final DomainObject it) {
275    StringConcatenation _builder = new StringConcatenation();
276    _builder.append("protected ");
277    String _name = it.getName();
278    _builder.append(_name, "");
279    _builder.append("Mapper() {");
280    _builder.newLineIfNotEmpty();
281    _builder.append("\t");
282    _builder.append("}");
283    _builder.newLine();
284    return _builder.toString();
285  }
286  
287  public String constructorBase(final DomainObject it) {
288    StringConcatenation _builder = new StringConcatenation();
289    _builder.append("protected ");
290    String _name = it.getName();
291    _builder.append(_name, "");
292    _builder.append("Mapper");
293    {
294      boolean _hasHint = this.helper.hasHint(it, "gapMapper");
295      if (_hasHint) {
296        _builder.append("Base");
297      }
298    }
299    _builder.append("() {");
300    _builder.newLineIfNotEmpty();
301    {
302      boolean _or = false;
303      boolean _isAbstract = it.isAbstract();
304      if (_isAbstract) {
305        _or = true;
306      } else {
307        boolean _hasSubClass = this.helper.hasSubClass(it);
308        _or = _hasSubClass;
309      }
310      if (_or) {
311        _builder.append("\t");
312        _builder.append("registerSubclassMappers();");
313        _builder.newLine();
314      }
315    }
316    _builder.append("\t");
317    _builder.append("}");
318    _builder.newLine();
319    return _builder.toString();
320  }
321  
322  public String getInstance(final DomainObject it) {
323    StringConcatenation _builder = new StringConcatenation();
324    _builder.append("private static final ");
325    String _name = it.getName();
326    _builder.append(_name, "");
327    _builder.append("Mapper instance = new ");
328    String _name_1 = it.getName();
329    _builder.append(_name_1, "");
330    _builder.append("Mapper();");
331    _builder.newLineIfNotEmpty();
332    _builder.newLine();
333    _builder.append("public static ");
334    String _name_2 = it.getName();
335    _builder.append(_name_2, "");
336    _builder.append("Mapper getInstance() {");
337    _builder.newLineIfNotEmpty();
338    _builder.append("\t");
339    _builder.append("return instance;");
340    _builder.newLine();
341    _builder.append("}");
342    _builder.newLine();
343    _builder.newLine();
344    return _builder.toString();
345  }
346  
347  public String discriminator(final DomainObject it) {
348    StringConcatenation _builder = new StringConcatenation();
349    _builder.append("public static final String ");
350    DomainObject _rootExtends = this.helper.getRootExtends(it);
351    Inheritance _inheritance = _rootExtends.getInheritance();
352    String _discriminatorColumnName = this.dbHelper.discriminatorColumnName(_inheritance);
353    _builder.append(_discriminatorColumnName, "");
354    _builder.append(" = ");
355    {
356      String _discriminatorColumnValue = it.getDiscriminatorColumnValue();
357      boolean _equals = Objects.equal(_discriminatorColumnValue, null);
358      if (_equals) {
359        String _domainPackage = this.helperBase.getDomainPackage(it);
360        _builder.append(_domainPackage, "");
361        _builder.append(".");
362        String _name = it.getName();
363        _builder.append(_name, "");
364        _builder.append(".class.getSimpleName()");
365      } else {
366        _builder.append("\"");
367        String _discriminatorColumnValue_1 = it.getDiscriminatorColumnValue();
368        _builder.append(_discriminatorColumnValue_1, "");
369        _builder.append("\"");
370      }
371    }
372    _builder.append(";");
373    _builder.newLineIfNotEmpty();
374    return _builder.toString();
375  }
376  
377  public String registerSubclassMappers(final DomainObject it) {
378    StringConcatenation _builder = new StringConcatenation();
379    _builder.append("private final java.util.Map<Class<?>, ");
380    String _fw = this.properties.fw("accessimpl.mongodb.DataMapper");
381    _builder.append(_fw, "");
382    _builder.append("<");
383    String _domainPackage = this.helperBase.getDomainPackage(it);
384    _builder.append(_domainPackage, "");
385    _builder.append(".");
386    String _name = it.getName();
387    _builder.append(_name, "");
388    _builder.append(", com.mongodb.DBObject>> subclassMapperByClass = new java.util.concurrent.ConcurrentHashMap<Class<?>, ");
389    String _fw_1 = this.properties.fw("accessimpl.mongodb.DataMapper");
390    _builder.append(_fw_1, "");
391    _builder.append("<");
392    String _domainPackage_1 = this.helperBase.getDomainPackage(it);
393    _builder.append(_domainPackage_1, "");
394    _builder.append(".");
395    String _name_1 = it.getName();
396    _builder.append(_name_1, "");
397    _builder.append(", com.mongodb.DBObject>>();");
398    _builder.newLineIfNotEmpty();
399    _builder.append("private final java.util.Map<String, ");
400    String _fw_2 = this.properties.fw("accessimpl.mongodb.DataMapper");
401    _builder.append(_fw_2, "");
402    _builder.append("<");
403    String _domainPackage_2 = this.helperBase.getDomainPackage(it);
404    _builder.append(_domainPackage_2, "");
405    _builder.append(".");
406    String _name_2 = it.getName();
407    _builder.append(_name_2, "");
408    _builder.append(", com.mongodb.DBObject>> subclassMapperByDtype = new java.util.concurrent.ConcurrentHashMap<String, ");
409    String _fw_3 = this.properties.fw("accessimpl.mongodb.DataMapper");
410    _builder.append(_fw_3, "");
411    _builder.append("<");
412    String _domainPackage_3 = this.helperBase.getDomainPackage(it);
413    _builder.append(_domainPackage_3, "");
414    _builder.append(".");
415    String _name_3 = it.getName();
416    _builder.append(_name_3, "");
417    _builder.append(", com.mongodb.DBObject>>();");
418    _builder.newLineIfNotEmpty();
419    _builder.newLine();
420    _builder.append("protected void registerSubclassMappers() {");
421    _builder.newLine();
422    {
423      Collection<DomainObject> _allSubclasses = this.helper.getAllSubclasses(it);
424      for(final DomainObject sub : _allSubclasses) {
425        _builder.append("\t");
426        _builder.append("registerSubclassMapper(");
427        _builder.newLine();
428        _builder.append("\t");
429        _builder.append("\t");
430        String _domainPackage_4 = this.helperBase.getDomainPackage(sub);
431        _builder.append(_domainPackage_4, "\t\t");
432        _builder.append(".");
433        String _name_4 = sub.getName();
434        _builder.append(_name_4, "\t\t");
435        _builder.append(".class,");
436        _builder.newLineIfNotEmpty();
437        _builder.append("\t");
438        _builder.append("\t");
439        Module _module = sub.getModule();
440        String _mapperPackage = this.mongoDbHelper.getMapperPackage(_module);
441        _builder.append(_mapperPackage, "\t\t");
442        _builder.append(".");
443        String _name_5 = sub.getName();
444        _builder.append(_name_5, "\t\t");
445        _builder.append("Mapper.");
446        DomainObject _rootExtends = this.helper.getRootExtends(it);
447        Inheritance _inheritance = _rootExtends.getInheritance();
448        String _discriminatorColumnName = this.dbHelper.discriminatorColumnName(_inheritance);
449        _builder.append(_discriminatorColumnName, "\t\t");
450        _builder.append(",");
451        _builder.newLineIfNotEmpty();
452        _builder.append("\t");
453        _builder.append("\t");
454        Module _module_1 = sub.getModule();
455        String _mapperPackage_1 = this.mongoDbHelper.getMapperPackage(_module_1);
456        _builder.append(_mapperPackage_1, "\t\t");
457        _builder.append(".");
458        String _name_6 = sub.getName();
459        _builder.append(_name_6, "\t\t");
460        _builder.append("Mapper.getInstance());");
461        _builder.newLineIfNotEmpty();
462      }
463    }
464    _builder.append("}");
465    _builder.newLine();
466    _builder.newLine();
467    _builder.append("protected void registerSubclassMapper(Class<?> domainType, String dtype, ");
468    String _fw_4 = this.properties.fw("accessimpl.mongodb.DataMapper");
469    _builder.append(_fw_4, "");
470    _builder.append("<");
471    String _domainPackage_5 = this.helperBase.getDomainPackage(it);
472    _builder.append(_domainPackage_5, "");
473    _builder.append(".");
474    String _name_7 = it.getName();
475    _builder.append(_name_7, "");
476    _builder.append(", com.mongodb.DBObject> mapper) {");
477    _builder.newLineIfNotEmpty();
478    _builder.append("\t");
479    _builder.append("subclassMapperByClass.put(domainType, mapper);");
480    _builder.newLine();
481    _builder.append("\t");
482    _builder.append("subclassMapperByDtype.put(dtype, mapper);");
483    _builder.newLine();
484    _builder.append("}");
485    _builder.newLine();
486    return _builder.toString();
487  }
488  
489  public String delegateToDomainToSubclassMapper(final DomainObject it) {
490    StringConcatenation _builder = new StringConcatenation();
491    _builder.append("String dtype;");
492    _builder.newLine();
493    _builder.append("if (from.containsField(\"");
494    DomainObject _rootExtends = this.helper.getRootExtends(it);
495    Inheritance _inheritance = _rootExtends.getInheritance();
496    String _discriminatorColumnName = this.dbHelper.discriminatorColumnName(_inheritance);
497    _builder.append(_discriminatorColumnName, "");
498    _builder.append("\")) {");
499    _builder.newLineIfNotEmpty();
500    _builder.append("\t\t");
501    _builder.append("dtype = (String) from.get(\"");
502    DomainObject _rootExtends_1 = this.helper.getRootExtends(it);
503    Inheritance _inheritance_1 = _rootExtends_1.getInheritance();
504    String _discriminatorColumnName_1 = this.dbHelper.discriminatorColumnName(_inheritance_1);
505    _builder.append(_discriminatorColumnName_1, "\t\t");
506    _builder.append("\");");
507    _builder.newLineIfNotEmpty();
508    _builder.append("\t");
509    _builder.append("} else {");
510    _builder.newLine();
511    _builder.append("\t\t");
512    _builder.append("dtype = \"unknown\";");
513    _builder.newLine();
514    _builder.append("\t");
515    _builder.append("}");
516    _builder.newLine();
517    _builder.append("\t");
518    _builder.newLine();
519    _builder.append("\t");
520    String _fw = this.properties.fw("accessimpl.mongodb.DataMapper");
521    _builder.append(_fw, "\t");
522    _builder.append("<? extends ");
523    String _domainPackage = this.helperBase.getDomainPackage(it);
524    _builder.append(_domainPackage, "\t");
525    _builder.append(".");
526    String _name = it.getName();
527    _builder.append(_name, "\t");
528    _builder.append(", DBObject> subclassMapper = subclassMapperByDtype.get(dtype);");
529    _builder.newLineIfNotEmpty();
530    _builder.append("\t");
531    _builder.append("if (subclassMapper == null) {");
532    _builder.newLine();
533    _builder.append("\t\t");
534    _builder.append("throw new IllegalArgumentException(\"Unsupported domain object (");
535    DomainObject _rootExtends_2 = this.helper.getRootExtends(it);
536    Inheritance _inheritance_2 = _rootExtends_2.getInheritance();
537    String _discriminatorColumnName_2 = this.dbHelper.discriminatorColumnName(_inheritance_2);
538    _builder.append(_discriminatorColumnName_2, "\t\t");
539    _builder.append("): \" + dtype);");
540    _builder.newLineIfNotEmpty();
541    _builder.append("\t");
542    _builder.append("}");
543    _builder.newLine();
544    _builder.append("\t");
545    _builder.append("return subclassMapper.toDomain(from);");
546    _builder.newLine();
547    return _builder.toString();
548  }
549  
550  public String delegateToDataToSubclassMapper(final DomainObject it) {
551    StringConcatenation _builder = new StringConcatenation();
552    String _fw = this.properties.fw("accessimpl.mongodb.DataMapper");
553    _builder.append(_fw, "");
554    _builder.append("<");
555    String _domainPackage = this.helperBase.getDomainPackage(it);
556    _builder.append(_domainPackage, "");
557    _builder.append(".");
558    String _name = it.getName();
559    _builder.append(_name, "");
560    _builder.append(", com.mongodb.DBObject> subclassMapper = subclassMapperByClass.get(from.getClass());");
561    _builder.newLineIfNotEmpty();
562    _builder.append("if (subclassMapper == null) {");
563    _builder.newLine();
564    _builder.append("\t");
565    _builder.append("throw new IllegalArgumentException(\"Unsupported domain object: \" + from.getClass().getName());");
566    _builder.newLine();
567    _builder.append("}");
568    _builder.newLine();
569    _builder.newLine();
570    _builder.append("return subclassMapper.toData(from);");
571    _builder.newLine();
572    return _builder.toString();
573  }
574  
575  public String fromNullCheck(final DomainObject it) {
576    StringConcatenation _builder = new StringConcatenation();
577    _builder.append("if (from == null) {");
578    _builder.newLine();
579    _builder.append("\t");
580    _builder.append("return null;");
581    _builder.newLine();
582    _builder.append("}");
583    _builder.newLine();
584    return _builder.toString();
585  }
586  
587  public String abstractToDomain(final DomainObject it) {
588    StringConcatenation _builder = new StringConcatenation();
589    _builder.append("@Override");
590    _builder.newLine();
591    _builder.append("public ");
592    DomainObject _rootExtends = this.helper.getRootExtends(it);
593    String _domainPackage = this.helperBase.getDomainPackage(_rootExtends);
594    _builder.append(_domainPackage, "");
595    _builder.append(".");
596    DomainObject _rootExtends_1 = this.helper.getRootExtends(it);
597    String _name = _rootExtends_1.getName();
598    _builder.append(_name, "");
599    _builder.append(" toDomain(com.mongodb.DBObject from) {");
600    _builder.newLineIfNotEmpty();
601    _builder.append("\t");
602    String _fromNullCheck = this.fromNullCheck(it);
603    _builder.append(_fromNullCheck, "\t");
604    _builder.newLineIfNotEmpty();
605    _builder.append("\t");
606    String _delegateToDomainToSubclassMapper = this.delegateToDomainToSubclassMapper(it);
607    _builder.append(_delegateToDomainToSubclassMapper, "\t");
608    _builder.newLineIfNotEmpty();
609    _builder.append("}");
610    _builder.newLine();
611    return _builder.toString();
612  }
613  
614  public String gapToDomain(final DomainObject it) {
615    StringConcatenation _builder = new StringConcatenation();
616    _builder.append("@Override");
617    _builder.newLine();
618    _builder.append("public ");
619    DomainObject _rootExtends = this.helper.getRootExtends(it);
620    String _domainPackage = this.helperBase.getDomainPackage(_rootExtends);
621    _builder.append(_domainPackage, "");
622    _builder.append(".");
623    DomainObject _rootExtends_1 = this.helper.getRootExtends(it);
624    String _name = _rootExtends_1.getName();
625    _builder.append(_name, "");
626    _builder.append(" toDomain(com.mongodb.DBObject from) {");
627    _builder.newLineIfNotEmpty();
628    _builder.append("\t");
629    _builder.append("return super.toDomain(from);");
630    _builder.newLine();
631    _builder.append("}");
632    _builder.newLine();
633    return _builder.toString();
634  }
635  
636  public String toDomain(final DomainObject it) {
637    String _xblockexpression = null;
638    {
639      final List<NamedElement> constructorParameters = this.helper.getConstructorParameters(it);
640      List<NamedElement> _constructorParameters = this.helper.getConstructorParameters(it);
641      final Function1<NamedElement, Boolean> _function = new Function1<NamedElement, Boolean>() {
642        @Override
643        public Boolean apply(final NamedElement e) {
644          boolean _and = false;
645          if (!(e instanceof Reference)) {
646            _and = false;
647          } else {
648            boolean _isEnumReference = MongoDbMapperTmpl.this.helper.isEnumReference(e);
649            boolean _not = (!_isEnumReference);
650            _and = _not;
651          }
652          return Boolean.valueOf(_and);
653        }
654      };
655      Iterable<NamedElement> _filter = IterableExtensions.<NamedElement>filter(_constructorParameters, _function);
656      final Function1<NamedElement, Reference> _function_1 = new Function1<NamedElement, Reference>() {
657        @Override
658        public Reference apply(final NamedElement e) {
659          return ((Reference) e);
660        }
661      };
662      final Iterable<Reference> nonEnumReferenceConstructorParameters = IterableExtensions.<NamedElement, Reference>map(_filter, _function_1);
663      Collection<Reference> _allReferences = this.helper.getAllReferences(it);
664      final Function1<Reference, Boolean> _function_2 = new Function1<Reference, Boolean>() {
665        @Override
666        public Boolean apply(final Reference e) {
667          boolean _or = false;
668          boolean _isEnumReference = MongoDbMapperTmpl.this.helper.isEnumReference(e);
669          if (_isEnumReference) {
670            _or = true;
671          } else {
672            boolean _contains = constructorParameters.contains(e);
673            _or = _contains;
674          }
675          return Boolean.valueOf((!_or));
676        }
677      };
678      final Iterable<Reference> allNonEnumNonConstructorReferences = IterableExtensions.<Reference>filter(_allReferences, _function_2);
679      StringConcatenation _builder = new StringConcatenation();
680      _builder.append("@Override");
681      _builder.newLine();
682      _builder.append("public ");
683      DomainObject _rootExtends = this.helper.getRootExtends(it);
684      String _domainPackage = this.helperBase.getDomainPackage(_rootExtends);
685      _builder.append(_domainPackage, "");
686      _builder.append(".");
687      DomainObject _rootExtends_1 = this.helper.getRootExtends(it);
688      String _name = _rootExtends_1.getName();
689      _builder.append(_name, "");
690      _builder.append(" toDomain(com.mongodb.DBObject from) {");
691      _builder.newLineIfNotEmpty();
692      _builder.append("\t");
693      String _fromNullCheck = this.fromNullCheck(it);
694      _builder.append(_fromNullCheck, "\t");
695      _builder.newLineIfNotEmpty();
696      _builder.newLine();
697      {
698        List<NamedElement> _constructorParameters_1 = this.helper.getConstructorParameters(it);
699        final Function1<NamedElement, Boolean> _function_3 = new Function1<NamedElement, Boolean>() {
700          @Override
701          public Boolean apply(final NamedElement e) {
702            return Boolean.valueOf((e instanceof Attribute));
703          }
704        };
705        Iterable<NamedElement> _filter_1 = IterableExtensions.<NamedElement>filter(_constructorParameters_1, _function_3);
706        final Function1<NamedElement, Attribute> _function_4 = new Function1<NamedElement, Attribute>() {
707          @Override
708          public Attribute apply(final NamedElement e) {
709            return ((Attribute) e);
710          }
711        };
712        Iterable<Attribute> _map = IterableExtensions.<NamedElement, Attribute>map(_filter_1, _function_4);
713        for(final Attribute p : _map) {
714          {
715            boolean _isJodaTemporal = this.dbHelper.isJodaTemporal(p);
716            if (_isJodaTemporal) {
717              _builder.append("\t");
718              String _typeName = this.helperBase.getTypeName(p);
719              _builder.append(_typeName, "\t");
720              _builder.append(" ");
721              String _name_1 = p.getName();
722              _builder.append(_name_1, "\t");
723              _builder.append(" = ");
724              String _xifexpression = null;
725              String _type = p.getType();
726              boolean _equals = Objects.equal(_type, "Date");
727              if (_equals) {
728                _xifexpression = "JodaLocalDate";
729              } else {
730                _xifexpression = "JodaDateTime";
731              }
732              String _plus = ("accessimpl.mongodb." + _xifexpression);
733              String _plus_1 = (_plus + "Mapper");
734              String _fw = this.properties.fw(_plus_1);
735              _builder.append(_fw, "\t");
736              _builder.append(".getInstance().toDomain((java.util.Date)from.get(\"");
737              String _databaseName = this.dbHelper.getDatabaseName(p);
738              _builder.append(_databaseName, "\t");
739              _builder.append("\"));");
740              _builder.newLineIfNotEmpty();
741            } else {
742              _builder.append("\t");
743              String _typeName_1 = this.helperBase.getTypeName(p);
744              _builder.append(_typeName_1, "\t");
745              _builder.append(" ");
746              String _name_2 = p.getName();
747              _builder.append(_name_2, "\t");
748              _builder.append(" = (");
749              String _typeName_2 = this.helperBase.getTypeName(p);
750              String _objectTypeName = this.helperBase.getObjectTypeName(_typeName_2);
751              _builder.append(_objectTypeName, "\t");
752              _builder.append(") from.get(\"");
753              String _databaseName_1 = this.dbHelper.getDatabaseName(p);
754              _builder.append(_databaseName_1, "\t");
755              _builder.append("\");");
756              _builder.newLineIfNotEmpty();
757            }
758          }
759        }
760      }
761      {
762        final Function1<NamedElement, Boolean> _function_5 = new Function1<NamedElement, Boolean>() {
763          @Override
764          public Boolean apply(final NamedElement e) {
765            return Boolean.valueOf(MongoDbMapperTmpl.this.helper.isEnumReference(e));
766          }
767        };
768        Iterable<NamedElement> _filter_2 = IterableExtensions.<NamedElement>filter(constructorParameters, _function_5);
769        final Function1<NamedElement, Reference> _function_6 = new Function1<NamedElement, Reference>() {
770          @Override
771          public Reference apply(final NamedElement e) {
772            return ((Reference) e);
773          }
774        };
775        Iterable<Reference> _map_1 = IterableExtensions.<NamedElement, Reference>map(_filter_2, _function_6);
776        for(final Reference p_1 : _map_1) {
777          _builder.append("\t");
778          String _typeName_3 = this.helperBase.getTypeName(p_1);
779          _builder.append(_typeName_3, "\t");
780          _builder.append(" ");
781          String _name_3 = p_1.getName();
782          _builder.append(_name_3, "\t");
783          _builder.append(" = (from.get(\"");
784          String _databaseName_2 = this.dbHelper.getDatabaseName(p_1);
785          _builder.append(_databaseName_2, "\t");
786          _builder.append("\") == null ? null : ");
787          String _typeName_4 = this.helperBase.getTypeName(p_1);
788          _builder.append(_typeName_4, "\t");
789          _builder.append(".valueOf((String) from.get(\"");
790          String _databaseName_3 = this.dbHelper.getDatabaseName(p_1);
791          _builder.append(_databaseName_3, "\t");
792          _builder.append("\")));");
793          _builder.newLineIfNotEmpty();
794        }
795      }
796      _builder.newLine();
797      _builder.append("\t");
798      _builder.append("// Single reference in constructor param, persistent, and should be included in aggregate");
799      _builder.newLine();
800      {
801        final Function1<Reference, Boolean> _function_7 = new Function1<Reference, Boolean>() {
802          @Override
803          public Boolean apply(final Reference e) {
804            boolean _and = false;
805            boolean _and_1 = false;
806            boolean _and_2 = false;
807            boolean _isMany = e.isMany();
808            boolean _not = (!_isMany);
809            if (!_not) {
810              _and_2 = false;
811            } else {
812              DomainObject _to = e.getTo();
813              boolean _isPersistent = MongoDbMapperTmpl.this.helper.isPersistent(_to);
814              _and_2 = _isPersistent;
815            }
816            if (!_and_2) {
817              _and_1 = false;
818            } else {
819              Reference _opposite = e.getOpposite();
820              boolean _equals = Objects.equal(_opposite, null);
821              _and_1 = _equals;
822            }
823            if (!_and_1) {
824              _and = false;
825            } else {
826              boolean _or = false;
827              boolean _isBasicTypeReference = MongoDbMapperTmpl.this.helper.isBasicTypeReference(e);
828              if (_isBasicTypeReference) {
829                _or = true;
830              } else {
831                boolean _isUnownedReference = MongoDbMapperTmpl.this.helper.isUnownedReference(e);
832                boolean _not_1 = (!_isUnownedReference);
833                _or = _not_1;
834              }
835              _and = _or;
836            }
837            return Boolean.valueOf(_and);
838          }
839        };
840        Iterable<Reference> _filter_3 = IterableExtensions.<Reference>filter(nonEnumReferenceConstructorParameters, _function_7);
841        for(final Reference p_2 : _filter_3) {
842          _builder.append("\t");
843          String _typeName_5 = this.helperBase.getTypeName(p_2);
844          _builder.append(_typeName_5, "\t");
845          _builder.append(" ");
846          String _name_4 = p_2.getName();
847          _builder.append(_name_4, "\t");
848          _builder.append(" = null;");
849          _builder.newLineIfNotEmpty();
850          _builder.append("\t");
851          _builder.append("if (from.containsField(\"");
852          String _databaseName_4 = this.dbHelper.getDatabaseName(p_2);
853          _builder.append(_databaseName_4, "\t");
854          _builder.append("\")) {");
855          _builder.newLineIfNotEmpty();
856          _builder.append("\t");
857          _builder.append("\t");
858          String _name_5 = p_2.getName();
859          _builder.append(_name_5, "\t\t");
860          _builder.append(" = ");
861          _builder.newLineIfNotEmpty();
862          _builder.append("\t");
863          _builder.append("\t");
864          DomainObject _to = p_2.getTo();
865          Module _module = _to.getModule();
866          String _mapperPackage = this.mongoDbHelper.getMapperPackage(_module);
867          _builder.append(_mapperPackage, "\t\t");
868          _builder.append(".");
869          DomainObject _to_1 = p_2.getTo();
870          String _name_6 = _to_1.getName();
871          _builder.append(_name_6, "\t\t");
872          _builder.append("Mapper.getInstance().toDomain(");
873          _builder.newLineIfNotEmpty();
874          _builder.append("\t");
875          _builder.append("\t\t");
876          _builder.append("(com.mongodb.DBObject) from.get(\"");
877          String _databaseName_5 = this.dbHelper.getDatabaseName(p_2);
878          _builder.append(_databaseName_5, "\t\t\t");
879          _builder.append("\"));");
880          _builder.newLineIfNotEmpty();
881          _builder.append("\t");
882          _builder.append("}");
883          _builder.newLine();
884        }
885      }
886      _builder.append("\t");
887      _builder.newLine();
888      _builder.append("\t");
889      _builder.append("// Single reference in constructor param, not in same aggregate root (unowned reference)");
890      _builder.newLine();
891      {
892        final Function1<Reference, Boolean> _function_8 = new Function1<Reference, Boolean>() {
893          @Override
894          public Boolean apply(final Reference e) {
895            boolean _and = false;
896            boolean _isMany = e.isMany();
897            boolean _not = (!_isMany);
898            if (!_not) {
899              _and = false;
900            } else {
901              boolean _isUnownedReference = MongoDbMapperTmpl.this.helper.isUnownedReference(e);
902              _and = _isUnownedReference;
903            }
904            return Boolean.valueOf(_and);
905          }
906        };
907        Iterable<Reference> _filter_4 = IterableExtensions.<Reference>filter(nonEnumReferenceConstructorParameters, _function_8);
908        for(final Reference p_3 : _filter_4) {
909          _builder.append("\t");
910          String _javaType = this.helperBase.getJavaType("IDTYPE");
911          _builder.append(_javaType, "\t");
912          _builder.append(" ");
913          String _name_7 = p_3.getName();
914          _builder.append(_name_7, "\t");
915          _builder.append(" = null;");
916          _builder.newLineIfNotEmpty();
917          _builder.append("\t");
918          _builder.append("if (from.containsField(\"");
919          String _databaseName_6 = this.dbHelper.getDatabaseName(p_3);
920          _builder.append(_databaseName_6, "\t");
921          _builder.append("\")) {");
922          _builder.newLineIfNotEmpty();
923          _builder.append("\t");
924          _builder.append("\t");
925          String _name_8 = p_3.getName();
926          _builder.append(_name_8, "\t\t");
927          _builder.append(" = (");
928          String _javaType_1 = this.helperBase.getJavaType("IDTYPE");
929          _builder.append(_javaType_1, "\t\t");
930          _builder.append(") from.get(\"");
931          String _databaseName_7 = this.dbHelper.getDatabaseName(p_3);
932          _builder.append(_databaseName_7, "\t\t");
933          _builder.append("\");");
934          _builder.newLineIfNotEmpty();
935          _builder.append("\t");
936          _builder.append("}");
937          _builder.newLine();
938        }
939      }
940      _builder.append("\t");
941      _builder.append("// TODO many references in constructor");
942      _builder.newLine();
943      _builder.append("\t");
944      _builder.newLine();
945      _builder.append("\t");
946      String _domainPackage_1 = this.helperBase.getDomainPackage(it);
947      _builder.append(_domainPackage_1, "\t");
948      _builder.append(".");
949      String _name_9 = it.getName();
950      _builder.append(_name_9, "\t");
951      _builder.append(" result = new ");
952      String _domainPackage_2 = this.helperBase.getDomainPackage(it);
953      _builder.append(_domainPackage_2, "\t");
954      _builder.append(".");
955      String _name_10 = it.getName();
956      _builder.append(_name_10, "\t");
957      _builder.append("(");
958      _builder.newLineIfNotEmpty();
959      _builder.append("\t\t");
960      {
961        boolean _hasElements = false;
962        for(final NamedElement p_4 : constructorParameters) {
963          if (!_hasElements) {
964            _hasElements = true;
965          } else {
966            _builder.appendImmediate(", ", "\t\t");
967          }
968          String _name_11 = p_4.getName();
969          _builder.append(_name_11, "\t\t");
970        }
971      }
972      _builder.append(");");
973      _builder.newLineIfNotEmpty();
974      {
975        if ((!(it instanceof BasicType))) {
976          _builder.append("\t");
977          _builder.append("if (from.containsField(\"_id\")) {");
978          _builder.newLine();
979          _builder.append("\t");
980          _builder.append("\t");
981          _builder.append("org.bson.types.ObjectId objectId = (org.bson.types.ObjectId) from.get(\"_id\");");
982          _builder.newLine();
983          _builder.append("\t");
984          _builder.append("\t");
985          _builder.append("String idString = objectId.toStringMongod();");
986          _builder.newLine();
987          _builder.append("\t");
988          _builder.append("\t");
989          String _fw_1 = this.properties.fw("accessimpl.mongodb.IdReflectionUtil");
990          _builder.append(_fw_1, "\t\t");
991          _builder.append(".internalSetId(result, idString);");
992          _builder.newLineIfNotEmpty();
993          _builder.append("\t");
994          _builder.append("}");
995          _builder.newLine();
996        }
997      }
998      _builder.append("\t");
999      Collection<Attribute> _allAttributes = this.helper.getAllAttributes(it);
1000      final Function1<Attribute, Boolean> _function_9 = new Function1<Attribute, Boolean>() {
1001        @Override
1002        public Boolean apply(final Attribute e) {
1003          return Boolean.valueOf(MongoDbMapperTmpl.this.helper.isUuid(e));
1004        }
1005      };
1006      final Attribute uuid = IterableExtensions.<Attribute>findFirst(_allAttributes, _function_9);
1007      _builder.newLineIfNotEmpty();
1008      {
1009        boolean _notEquals = (!Objects.equal(uuid, null));
1010        if (_notEquals) {
1011          _builder.append("\t");
1012          _builder.append("if (from.containsField(\"");
1013          String _databaseName_8 = this.dbHelper.getDatabaseName(uuid);
1014          _builder.append(_databaseName_8, "\t");
1015          _builder.append("\")) {");
1016          _builder.newLineIfNotEmpty();
1017          _builder.append("\t");
1018          _builder.append("\t");
1019          String _fw_2 = this.properties.fw("accessimpl.mongodb.IdReflectionUtil");
1020          _builder.append(_fw_2, "\t\t");
1021          _builder.append(".internalSetUuid(result, (String) from.get(\"");
1022          String _databaseName_9 = this.dbHelper.getDatabaseName(uuid);
1023          _builder.append(_databaseName_9, "\t\t");
1024          _builder.append("\"));");
1025          _builder.newLineIfNotEmpty();
1026          _builder.append("\t");
1027          _builder.append("}");
1028          _builder.newLine();
1029        }
1030      }
1031      {
1032        Collection<Attribute> _allAttributes_1 = this.helper.getAllAttributes(it);
1033        final Function1<Attribute, Boolean> _function_10 = new Function1<Attribute, Boolean>() {
1034          @Override
1035          public Boolean apply(final Attribute e) {
1036            boolean _or = false;
1037            boolean _or_1 = false;
1038            boolean _isUuid = MongoDbMapperTmpl.this.helper.isUuid(e);
1039            if (_isUuid) {
1040              _or_1 = true;
1041            } else {
1042              String _name = e.getName();
1043              boolean _equals = Objects.equal(_name, "id");
1044              _or_1 = _equals;
1045            }
1046            if (_or_1) {
1047              _or = true;
1048            } else {
1049              boolean _contains = constructorParameters.contains(e);
1050              _or = _contains;
1051            }
1052            return Boolean.valueOf((!_or));
1053          }
1054        };
1055        Iterable<Attribute> _filter_5 = IterableExtensions.<Attribute>filter(_allAttributes_1, _function_10);
1056        for(final Attribute att : _filter_5) {
1057          _builder.append("\t");
1058          _builder.append("if (from.containsField(\"");
1059          String _databaseName_10 = this.dbHelper.getDatabaseName(att);
1060          _builder.append(_databaseName_10, "\t");
1061          _builder.append("\")) {");
1062          _builder.newLineIfNotEmpty();
1063          {
1064            String _collectionType = att.getCollectionType();
1065            boolean _notEquals_1 = (!Objects.equal(_collectionType, null));
1066            if (_notEquals_1) {
1067              _builder.append("\t");
1068              _builder.append("\t");
1069              _builder.append("result.set");
1070              String _name_12 = att.getName();
1071              String _firstUpper = this.helperBase.toFirstUpper(_name_12);
1072              _builder.append(_firstUpper, "\t\t");
1073              _builder.append("(new ");
1074              String _implTypeName = this.helperBase.getImplTypeName(att);
1075              _builder.append(_implTypeName, "\t\t");
1076              _builder.append("((java.util.Collection) from.get(\"");
1077              String _databaseName_11 = this.dbHelper.getDatabaseName(att);
1078              _builder.append(_databaseName_11, "\t\t");
1079              _builder.append("\")));");
1080              _builder.newLineIfNotEmpty();
1081            } else {
1082              boolean _isJodaTemporal_1 = this.dbHelper.isJodaTemporal(att);
1083              if (_isJodaTemporal_1) {
1084                _builder.append("\t");
1085                _builder.append("\t");
1086                _builder.append("result.set");
1087                String _name_13 = att.getName();
1088                String _firstUpper_1 = this.helperBase.toFirstUpper(_name_13);
1089                _builder.append(_firstUpper_1, "\t\t");
1090                _builder.append("(");
1091                String _xifexpression_1 = null;
1092                String _type_1 = att.getType();
1093                boolean _equals_1 = Objects.equal(_type_1, "Date");
1094                if (_equals_1) {
1095                  _xifexpression_1 = "JodaLocalDate";
1096                } else {
1097                  _xifexpression_1 = "JodaDateTime";
1098                }
1099                String _plus_2 = ("accessimpl.mongodb." + _xifexpression_1);
1100                String _plus_3 = (_plus_2 + "Mapper");
1101                String _fw_3 = this.properties.fw(_plus_3);
1102                _builder.append(_fw_3, "\t\t");
1103                _builder.append(".getInstance().toDomain((java.util.Date)from.get(\"");
1104                String _databaseName_12 = this.dbHelper.getDatabaseName(att);
1105                _builder.append(_databaseName_12, "\t\t");
1106                _builder.append("\")));");
1107                _builder.newLineIfNotEmpty();
1108              } else {
1109                _builder.append("\t");
1110                _builder.append("\t");
1111                _builder.append("result.set");
1112                String _name_14 = att.getName();
1113                String _firstUpper_2 = this.helperBase.toFirstUpper(_name_14);
1114                _builder.append(_firstUpper_2, "\t\t");
1115                _builder.append("((");
1116                String _typeName_6 = this.helperBase.getTypeName(att);
1117                String _objectTypeName_1 = this.helperBase.getObjectTypeName(_typeName_6);
1118                _builder.append(_objectTypeName_1, "\t\t");
1119                _builder.append(") from.get(\"");
1120                String _databaseName_13 = this.dbHelper.getDatabaseName(att);
1121                _builder.append(_databaseName_13, "\t\t");
1122                _builder.append("\"));");
1123                _builder.newLineIfNotEmpty();
1124              }
1125            }
1126          }
1127          _builder.append("\t");
1128          _builder.append("}");
1129          _builder.newLine();
1130        }
1131      }
1132      _builder.newLine();
1133      {
1134        Collection<Reference> _allEnumReferences = this.helper.getAllEnumReferences(it);
1135        final Function1<Reference, Boolean> _function_11 = new Function1<Reference, Boolean>() {
1136          @Override
1137          public Boolean apply(final Reference e) {
1138            boolean _contains = constructorParameters.contains(e);
1139            return Boolean.valueOf((!_contains));
1140          }
1141        };
1142        Iterable<Reference> _filter_6 = IterableExtensions.<Reference>filter(_allEnumReferences, _function_11);
1143        for(final Reference enumRef : _filter_6) {
1144          _builder.append("\t");
1145          _builder.append("if (from.containsField(\"");
1146          String _databaseName_14 = this.dbHelper.getDatabaseName(enumRef);
1147          _builder.append(_databaseName_14, "\t");
1148          _builder.append("\")) {");
1149          _builder.newLineIfNotEmpty();
1150          _builder.append("\t");
1151          _builder.append("\t");
1152          _builder.append("result.set");
1153          String _name_15 = enumRef.getName();
1154          String _firstUpper_3 = this.helperBase.toFirstUpper(_name_15);
1155          _builder.append(_firstUpper_3, "\t\t");
1156          _builder.append("((from.get(\"");
1157          String _databaseName_15 = this.dbHelper.getDatabaseName(enumRef);
1158          _builder.append(_databaseName_15, "\t\t");
1159          _builder.append("\") == null ? null : ");
1160          String _typeName_7 = this.helperBase.getTypeName(enumRef);
1161          _builder.append(_typeName_7, "\t\t");
1162          _builder.append(".valueOf((String) from.get(\"");
1163          String _databaseName_16 = this.dbHelper.getDatabaseName(enumRef);
1164          _builder.append(_databaseName_16, "\t\t");
1165          _builder.append("\"))));");
1166          _builder.newLineIfNotEmpty();
1167          _builder.append("\t");
1168          _builder.append("}");
1169          _builder.newLine();
1170        }
1171      }
1172      _builder.newLine();
1173      _builder.append("\t");
1174      _builder.append("// Single reference not in constructor param, persistent, and should be included in aggregate");
1175      _builder.newLine();
1176      {
1177        final Function1<Reference, Boolean> _function_12 = new Function1<Reference, Boolean>() {
1178          @Override
1179          public Boolean apply(final Reference e) {
1180            boolean _and = false;
1181            boolean _and_1 = false;
1182            boolean _and_2 = false;
1183            boolean _isMany = e.isMany();
1184            boolean _not = (!_isMany);
1185            if (!_not) {
1186              _and_2 = false;
1187            } else {
1188              DomainObject _to = e.getTo();
1189              boolean _isPersistent = MongoDbMapperTmpl.this.helper.isPersistent(_to);
1190              _and_2 = _isPersistent;
1191            }
1192            if (!_and_2) {
1193              _and_1 = false;
1194            } else {
1195              Reference _opposite = e.getOpposite();
1196              boolean _equals = Objects.equal(_opposite, null);
1197              _and_1 = _equals;
1198            }
1199            if (!_and_1) {
1200              _and = false;
1201            } else {
1202              boolean _or = false;
1203              boolean _isBasicTypeReference = MongoDbMapperTmpl.this.helper.isBasicTypeReference(e);
1204              if (_isBasicTypeReference) {
1205                _or = true;
1206              } else {
1207                boolean _isUnownedReference = MongoDbMapperTmpl.this.helper.isUnownedReference(e);
1208                boolean _not_1 = (!_isUnownedReference);
1209                _or = _not_1;
1210              }
1211              _and = _or;
1212            }
1213            return Boolean.valueOf(_and);
1214          }
1215        };
1216        Iterable<Reference> _filter_7 = IterableExtensions.<Reference>filter(allNonEnumNonConstructorReferences, _function_12);
1217        for(final Reference ref : _filter_7) {
1218          _builder.append("\t");
1219          _builder.append("if (from.containsField(\"");
1220          String _databaseName_17 = this.dbHelper.getDatabaseName(ref);
1221          _builder.append(_databaseName_17, "\t");
1222          _builder.append("\")) {");
1223          _builder.newLineIfNotEmpty();
1224          _builder.append("\t");
1225          _builder.append("\t");
1226          _builder.append("result.set");
1227          String _name_16 = ref.getName();
1228          String _firstUpper_4 = this.helperBase.toFirstUpper(_name_16);
1229          _builder.append(_firstUpper_4, "\t\t");
1230          _builder.append("(");
1231          _builder.newLineIfNotEmpty();
1232          _builder.append("\t");
1233          _builder.append("\t");
1234          DomainObject _to_2 = ref.getTo();
1235          Module _module_1 = _to_2.getModule();
1236          String _mapperPackage_1 = this.mongoDbHelper.getMapperPackage(_module_1);
1237          _builder.append(_mapperPackage_1, "\t\t");
1238          _builder.append(".");
1239          DomainObject _to_3 = ref.getTo();
1240          String _name_17 = _to_3.getName();
1241          _builder.append(_name_17, "\t\t");
1242          _builder.append("Mapper.getInstance().toDomain(");
1243          _builder.newLineIfNotEmpty();
1244          _builder.append("\t");
1245          _builder.append("\t\t");
1246          _builder.append("(com.mongodb.DBObject) from.get(\"");
1247          String _databaseName_18 = this.dbHelper.getDatabaseName(ref);
1248          _builder.append(_databaseName_18, "\t\t\t");
1249          _builder.append("\")));");
1250          _builder.newLineIfNotEmpty();
1251          _builder.append("\t");
1252          _builder.append("}");
1253          _builder.newLine();
1254        }
1255      }
1256      _builder.newLine();
1257      _builder.append("\t");
1258      _builder.append("// Multiple reference not in constructor param, persistent, and should be included in aggregate");
1259      _builder.newLine();
1260      {
1261        final Function1<Reference, Boolean> _function_13 = new Function1<Reference, Boolean>() {
1262          @Override
1263          public Boolean apply(final Reference e) {
1264            boolean _and = false;
1265            boolean _and_1 = false;
1266            boolean _isMany = e.isMany();
1267            if (!_isMany) {
1268              _and_1 = false;
1269            } else {
1270              DomainObject _to = e.getTo();
1271              boolean _isPersistent = MongoDbMapperTmpl.this.helper.isPersistent(_to);
1272              _and_1 = _isPersistent;
1273            }
1274            if (!_and_1) {
1275              _and = false;
1276            } else {
1277              boolean _or = false;
1278              boolean _isBasicTypeReference = MongoDbMapperTmpl.this.helper.isBasicTypeReference(e);
1279              if (_isBasicTypeReference) {
1280                _or = true;
1281              } else {
1282                boolean _isUnownedReference = MongoDbMapperTmpl.this.helper.isUnownedReference(e);
1283                boolean _not = (!_isUnownedReference);
1284                _or = _not;
1285              }
1286              _and = _or;
1287            }
1288            return Boolean.valueOf(_and);
1289          }
1290        };
1291        Iterable<Reference> _filter_8 = IterableExtensions.<Reference>filter(allNonEnumNonConstructorReferences, _function_13);
1292        for(final Reference ref_1 : _filter_8) {
1293          _builder.append("\t");
1294          _builder.append("if (from.containsField(\"");
1295          String _databaseName_19 = this.dbHelper.getDatabaseName(ref_1);
1296          _builder.append(_databaseName_19, "\t");
1297          _builder.append("\")) {");
1298          _builder.newLineIfNotEmpty();
1299          _builder.append("\t");
1300          _builder.append("\t");
1301          _builder.append("@SuppressWarnings(\"unchecked\")");
1302          _builder.newLine();
1303          _builder.append("\t");
1304          _builder.append("\t");
1305          _builder.append("java.util.Collection<com.mongodb.DBObject> ");
1306          String _name_18 = ref_1.getName();
1307          _builder.append(_name_18, "\t\t");
1308          _builder.append("Data = (java.util.Collection<com.mongodb.DBObject>) from.get(\"");
1309          String _databaseName_20 = this.dbHelper.getDatabaseName(ref_1);
1310          _builder.append(_databaseName_20, "\t\t");
1311          _builder.append("\");");
1312          _builder.newLineIfNotEmpty();
1313          _builder.append("\t");
1314          _builder.append("\t");
1315          _builder.append("for (com.mongodb.DBObject each : ");
1316          String _name_19 = ref_1.getName();
1317          _builder.append(_name_19, "\t\t");
1318          _builder.append("Data) {");
1319          _builder.newLineIfNotEmpty();
1320          _builder.append("\t");
1321          _builder.append("\t\t");
1322          _builder.append("result.add");
1323          String _name_20 = ref_1.getName();
1324          String _firstUpper_5 = this.helperBase.toFirstUpper(_name_20);
1325          String _singular = this.helper.singular(_firstUpper_5);
1326          _builder.append(_singular, "\t\t\t");
1327          _builder.append("(");
1328          DomainObject _to_4 = ref_1.getTo();
1329          Module _module_2 = _to_4.getModule();
1330          String _mapperPackage_2 = this.mongoDbHelper.getMapperPackage(_module_2);
1331          _builder.append(_mapperPackage_2, "\t\t\t");
1332          _builder.append(".");
1333          DomainObject _to_5 = ref_1.getTo();
1334          String _name_21 = _to_5.getName();
1335          _builder.append(_name_21, "\t\t\t");
1336          _builder.append("Mapper.getInstance().toDomain(each));");
1337          _builder.newLineIfNotEmpty();
1338          _builder.append("\t");
1339          _builder.append("\t");
1340          _builder.append("}");
1341          _builder.newLine();
1342          _builder.append("\t");
1343          _builder.append("}");
1344          _builder.newLine();
1345        }
1346      }
1347      _builder.newLine();
1348      _builder.append("\t");
1349      _builder.append("// Single reference not in constructor param, not in same aggregate root (unowned reference)");
1350      _builder.newLine();
1351      {
1352        final Function1<Reference, Boolean> _function_14 = new Function1<Reference, Boolean>() {
1353          @Override
1354          public Boolean apply(final Reference e) {
1355            boolean _and = false;
1356            boolean _isMany = e.isMany();
1357            boolean _not = (!_isMany);
1358            if (!_not) {
1359              _and = false;
1360            } else {
1361              boolean _isUnownedReference = MongoDbMapperTmpl.this.helper.isUnownedReference(e);
1362              _and = _isUnownedReference;
1363            }
1364            return Boolean.valueOf(_and);
1365          }
1366        };
1367        Iterable<Reference> _filter_9 = IterableExtensions.<Reference>filter(allNonEnumNonConstructorReferences, _function_14);
1368        for(final Reference ref_2 : _filter_9) {
1369          _builder.append("\t");
1370          _builder.append("if (from.containsField(\"");
1371          String _databaseName_21 = this.dbHelper.getDatabaseName(ref_2);
1372          _builder.append(_databaseName_21, "\t");
1373          _builder.append("\")) {");
1374          _builder.newLineIfNotEmpty();
1375          _builder.append("\t");
1376          _builder.append("\t");
1377          _builder.append("result.set");
1378          String _name_22 = ref_2.getName();
1379          String _firstUpper_6 = this.helperBase.toFirstUpper(_name_22);
1380          _builder.append(_firstUpper_6, "\t\t");
1381          _builder.append("Id((");
1382          String _javaType_2 = this.helperBase.getJavaType("IDTYPE");
1383          _builder.append(_javaType_2, "\t\t");
1384          _builder.append(") from.get(\"");
1385          String _databaseName_22 = this.dbHelper.getDatabaseName(ref_2);
1386          _builder.append(_databaseName_22, "\t\t");
1387          _builder.append("\"));");
1388          _builder.newLineIfNotEmpty();
1389          _builder.append("\t");
1390          _builder.append("}");
1391          _builder.newLine();
1392        }
1393      }
1394      _builder.newLine();
1395      _builder.append("\t");
1396      _builder.append("// Multiple reference not in constructor param, not in same aggregate root (unowned reference)");
1397      _builder.newLine();
1398      {
1399        final Function1<Reference, Boolean> _function_15 = new Function1<Reference, Boolean>() {
1400          @Override
1401          public Boolean apply(final Reference e) {
1402            boolean _and = false;
1403            boolean _isMany = e.isMany();
1404            if (!_isMany) {
1405              _and = false;
1406            } else {
1407              boolean _isUnownedReference = MongoDbMapperTmpl.this.helper.isUnownedReference(e);
1408              _and = _isUnownedReference;
1409            }
1410            return Boolean.valueOf(_and);
1411          }
1412        };
1413        Iterable<Reference> _filter_10 = IterableExtensions.<Reference>filter(allNonEnumNonConstructorReferences, _function_15);
1414        for(final Reference ref_3 : _filter_10) {
1415          _builder.append("\t");
1416          _builder.append("if (from.containsField(\"");
1417          String _databaseName_23 = this.dbHelper.getDatabaseName(ref_3);
1418          _builder.append(_databaseName_23, "\t");
1419          _builder.append("\")) {");
1420          _builder.newLineIfNotEmpty();
1421          _builder.append("\t");
1422          _builder.append("\t");
1423          _builder.append("@SuppressWarnings(\"unchecked\")");
1424          _builder.newLine();
1425          _builder.append("\t");
1426          _builder.append("\t");
1427          _builder.append("java.util.Collection<");
1428          String _javaType_3 = this.helperBase.getJavaType("IDTYPE");
1429          _builder.append(_javaType_3, "\t\t");
1430          _builder.append("> ");
1431          String _name_23 = ref_3.getName();
1432          _builder.append(_name_23, "\t\t");
1433          _builder.append("Data = (java.util.Collection<");
1434          String _javaType_4 = this.helperBase.getJavaType("IDTYPE");
1435          _builder.append(_javaType_4, "\t\t");
1436          _builder.append(">) from.get(\"");
1437          String _databaseName_24 = this.dbHelper.getDatabaseName(ref_3);
1438          _builder.append(_databaseName_24, "\t\t");
1439          _builder.append("\");");
1440          _builder.newLineIfNotEmpty();
1441          _builder.append("\t");
1442          _builder.append("\t");
1443          _builder.append("for (");
1444          String _javaType_5 = this.helperBase.getJavaType("IDTYPE");
1445          _builder.append(_javaType_5, "\t\t");
1446          _builder.append(" each : ");
1447          String _name_24 = ref_3.getName();
1448          _builder.append(_name_24, "\t\t");
1449          _builder.append("Data) {");
1450          _builder.newLineIfNotEmpty();
1451          _builder.append("\t");
1452          _builder.append("\t\t");
1453          _builder.append("result.get");
1454          String _name_25 = ref_3.getName();
1455          String _firstUpper_7 = this.helperBase.toFirstUpper(_name_25);
1456          _builder.append(_firstUpper_7, "\t\t\t");
1457          _builder.append("Ids().add(each);");
1458          _builder.newLineIfNotEmpty();
1459          _builder.append("\t");
1460          _builder.append("\t");
1461          _builder.append("}");
1462          _builder.newLine();
1463          _builder.append("\t");
1464          _builder.append("}");
1465          _builder.newLine();
1466        }
1467      }
1468      _builder.newLine();
1469      _builder.append("\t");
1470      _builder.append("return result;");
1471      _builder.newLine();
1472      _builder.append("}");
1473      _builder.newLine();
1474      _xblockexpression = _builder.toString();
1475    }
1476    return _xblockexpression;
1477  }
1478  
1479  protected String _getDBCollectionName(final DomainObject it) {
1480    StringConcatenation _builder = new StringConcatenation();
1481    _builder.append("@Override");
1482    _builder.newLine();
1483    _builder.append("public String getDBCollectionName() {");
1484    _builder.newLine();
1485    _builder.append("\t");
1486    _builder.append("return \"");
1487    DomainObject _rootExtends = this.helper.getRootExtends(it);
1488    String _databaseName = this.dbHelper.getDatabaseName(_rootExtends);
1489    _builder.append(_databaseName, "\t");
1490    _builder.append("\";");
1491    _builder.newLineIfNotEmpty();
1492    _builder.append("}");
1493    _builder.newLine();
1494    return _builder.toString();
1495  }
1496  
1497  protected String _getDBCollectionName(final BasicType it) {
1498    StringConcatenation _builder = new StringConcatenation();
1499    _builder.append("@Override");
1500    _builder.newLine();
1501    _builder.append("public String getDBCollectionName() {");
1502    _builder.newLine();
1503    _builder.append("\t");
1504    _builder.append("throw new IllegalStateException(\"BasicType ");
1505    String _name = it.getName();
1506    _builder.append(_name, "\t");
1507    _builder.append(" is not stored in own DBCollection\");");
1508    _builder.newLineIfNotEmpty();
1509    _builder.append("}");
1510    _builder.newLine();
1511    return _builder.toString();
1512  }
1513  
1514  public String canMapToData(final DomainObject it) {
1515    StringConcatenation _builder = new StringConcatenation();
1516    _builder.append("@Override");
1517    _builder.newLine();
1518    _builder.append("public boolean canMapToData(Class<?> domainObjectClass) {");
1519    _builder.newLine();
1520    _builder.append("    ");
1521    _builder.append("if (domainObjectClass == null) {");
1522    _builder.newLine();
1523    _builder.append("    \t");
1524    _builder.append("return true;");
1525    _builder.newLine();
1526    _builder.append("    ");
1527    _builder.append("}");
1528    _builder.newLine();
1529    _builder.append("\t");
1530    _builder.append("return ");
1531    String _domainPackage = this.helperBase.getDomainPackage(it);
1532    _builder.append(_domainPackage, "\t");
1533    _builder.append(".");
1534    String _name = it.getName();
1535    _builder.append(_name, "\t");
1536    _builder.append(".class.isAssignableFrom(domainObjectClass);");
1537    _builder.newLineIfNotEmpty();
1538    _builder.append("}");
1539    _builder.newLine();
1540    return _builder.toString();
1541  }
1542  
1543  public String abstractToData(final DomainObject it) {
1544    StringConcatenation _builder = new StringConcatenation();
1545    _builder.append("@Override");
1546    _builder.newLine();
1547    _builder.append("public com.mongodb.DBObject toData(");
1548    DomainObject _rootExtends = this.helper.getRootExtends(it);
1549    String _domainPackage = this.helperBase.getDomainPackage(_rootExtends);
1550    _builder.append(_domainPackage, "");
1551    _builder.append(".");
1552    DomainObject _rootExtends_1 = this.helper.getRootExtends(it);
1553    String _name = _rootExtends_1.getName();
1554    _builder.append(_name, "");
1555    _builder.append(" from) {");
1556    _builder.newLineIfNotEmpty();
1557    _builder.append("\t");
1558    String _fromNullCheck = this.fromNullCheck(it);
1559    _builder.append(_fromNullCheck, "\t");
1560    _builder.newLineIfNotEmpty();
1561    _builder.append("\t");
1562    String _delegateToDataToSubclassMapper = this.delegateToDataToSubclassMapper(it);
1563    _builder.append(_delegateToDataToSubclassMapper, "\t");
1564    _builder.newLineIfNotEmpty();
1565    _builder.append("}");
1566    _builder.newLine();
1567    return _builder.toString();
1568  }
1569  
1570  public String gapToData(final DomainObject it) {
1571    StringConcatenation _builder = new StringConcatenation();
1572    _builder.append("@Override");
1573    _builder.newLine();
1574    _builder.append("public com.mongodb.DBObject toData(");
1575    DomainObject _rootExtends = this.helper.getRootExtends(it);
1576    String _domainPackage = this.helperBase.getDomainPackage(_rootExtends);
1577    _builder.append(_domainPackage, "");
1578    _builder.append(".");
1579    DomainObject _rootExtends_1 = this.helper.getRootExtends(it);
1580    String _name = _rootExtends_1.getName();
1581    _builder.append(_name, "");
1582    _builder.append(" from) {");
1583    _builder.newLineIfNotEmpty();
1584    _builder.append("\t");
1585    _builder.append("return super.toData(from);");
1586    _builder.newLine();
1587    _builder.append("}");
1588    _builder.newLine();
1589    return _builder.toString();
1590  }
1591  
1592  public String toData(final DomainObject it) {
1593    String _xblockexpression = null;
1594    {
1595      Collection<Reference> _allReferences = this.helper.getAllReferences(it);
1596      final Function1<Reference, Boolean> _function = new Function1<Reference, Boolean>() {
1597        @Override
1598        public Boolean apply(final Reference e) {
1599          boolean _or = false;
1600          boolean _isEnumReference = MongoDbMapperTmpl.this.helper.isEnumReference(e);
1601          if (_isEnumReference) {
1602            _or = true;
1603          } else {
1604            boolean _isTransient = e.isTransient();
1605            _or = _isTransient;
1606          }
1607          return Boolean.valueOf((!_or));
1608        }
1609      };
1610      final Iterable<Reference> allNonEnumNonTransientReferences = IterableExtensions.<Reference>filter(_allReferences, _function);
1611      StringConcatenation _builder = new StringConcatenation();
1612      _builder.append("@Override");
1613      _builder.newLine();
1614      _builder.append("public com.mongodb.DBObject toData(");
1615      DomainObject _rootExtends = this.helper.getRootExtends(it);
1616      String _domainPackage = this.helperBase.getDomainPackage(_rootExtends);
1617      _builder.append(_domainPackage, "");
1618      _builder.append(".");
1619      DomainObject _rootExtends_1 = this.helper.getRootExtends(it);
1620      String _name = _rootExtends_1.getName();
1621      _builder.append(_name, "");
1622      _builder.append(" ");
1623      {
1624        DomainObject _extends = it.getExtends();
1625        boolean _equals = Objects.equal(_extends, null);
1626        if (_equals) {
1627          _builder.append("from");
1628        } else {
1629          _builder.append("inFrom");
1630        }
1631      }
1632      _builder.append(") {");
1633      _builder.newLineIfNotEmpty();
1634      {
1635        DomainObject _extends_1 = it.getExtends();
1636        boolean _notEquals = (!Objects.equal(_extends_1, null));
1637        if (_notEquals) {
1638          _builder.append("\t");
1639          String _domainPackage_1 = this.helperBase.getDomainPackage(it);
1640          _builder.append(_domainPackage_1, "\t");
1641          _builder.append(".");
1642          String _name_1 = it.getName();
1643          _builder.append(_name_1, "\t");
1644          _builder.append(" from = (");
1645          String _domainPackage_2 = this.helperBase.getDomainPackage(it);
1646          _builder.append(_domainPackage_2, "\t");
1647          _builder.append(".");
1648          String _name_2 = it.getName();
1649          _builder.append(_name_2, "\t");
1650          _builder.append(") inFrom;");
1651          _builder.newLineIfNotEmpty();
1652        }
1653      }
1654      _builder.append("\t");
1655      String _fromNullCheck = this.fromNullCheck(it);
1656      _builder.append(_fromNullCheck, "\t");
1657      _builder.newLineIfNotEmpty();
1658      _builder.newLine();
1659      _builder.append("\t");
1660      _builder.append("com.mongodb.DBObject result = new com.mongodb.BasicDBObject();");
1661      _builder.newLine();
1662      {
1663        if ((!(it instanceof BasicType))) {
1664          _builder.append("\t");
1665          _builder.append("if (from.getId() != null) {");
1666          _builder.newLine();
1667          _builder.append("\t");
1668          _builder.append("\t");
1669          _builder.append("org.bson.types.ObjectId objectId = org.bson.types.ObjectId.massageToObjectId(from.getId());");
1670          _builder.newLine();
1671          _builder.append("\t");
1672          _builder.append("\t");
1673          _builder.append("result.put(\"_id\", objectId);");
1674          _builder.newLine();
1675          _builder.append("\t");
1676          _builder.append("}");
1677          _builder.newLine();
1678        }
1679      }
1680      _builder.newLine();
1681      {
1682        DomainObject _extends_2 = it.getExtends();
1683        boolean _notEquals_1 = (!Objects.equal(_extends_2, null));
1684        if (_notEquals_1) {
1685          _builder.append("\t");
1686          _builder.append("result.put(\"");
1687          DomainObject _rootExtends_2 = this.helper.getRootExtends(it);
1688          Inheritance _inheritance = _rootExtends_2.getInheritance();
1689          String _discriminatorColumnName = this.dbHelper.discriminatorColumnName(_inheritance);
1690          _builder.append(_discriminatorColumnName, "\t");
1691          _builder.append("\", ");
1692          DomainObject _rootExtends_3 = this.helper.getRootExtends(it);
1693          Inheritance _inheritance_1 = _rootExtends_3.getInheritance();
1694          String _discriminatorColumnName_1 = this.dbHelper.discriminatorColumnName(_inheritance_1);
1695          _builder.append(_discriminatorColumnName_1, "\t");
1696          _builder.append(");");
1697          _builder.newLineIfNotEmpty();
1698        }
1699      }
1700      _builder.newLine();
1701      {
1702        Collection<Attribute> _allAttributes = this.helper.getAllAttributes(it);
1703        final Function1<Attribute, Boolean> _function_1 = new Function1<Attribute, Boolean>() {
1704          @Override
1705          public Boolean apply(final Attribute e) {
1706            boolean _or = false;
1707            String _name = e.getName();
1708            boolean _equals = Objects.equal(_name, "id");
1709            if (_equals) {
1710              _or = true;
1711            } else {
1712              boolean _isTransient = e.isTransient();
1713              _or = _isTransient;
1714            }
1715            return Boolean.valueOf((!_or));
1716          }
1717        };
1718        Iterable<Attribute> _filter = IterableExtensions.<Attribute>filter(_allAttributes, _function_1);
1719        for(final Attribute att : _filter) {
1720          {
1721            String _collectionType = att.getCollectionType();
1722            boolean _notEquals_2 = (!Objects.equal(_collectionType, null));
1723            if (_notEquals_2) {
1724              _builder.append("\t");
1725              _builder.append("result.put(\"");
1726              String _databaseName = this.dbHelper.getDatabaseName(att);
1727              _builder.append(_databaseName, "\t");
1728              _builder.append("\", new java.util.ArrayList<Object>(from.");
1729              String _getAccessor = this.helper.getGetAccessor(att);
1730              _builder.append(_getAccessor, "\t");
1731              _builder.append("()));");
1732              _builder.newLineIfNotEmpty();
1733            } else {
1734              boolean _isJodaTemporal = this.dbHelper.isJodaTemporal(att);
1735              if (_isJodaTemporal) {
1736                _builder.append("\t");
1737                _builder.append("result.put(\"");
1738                String _databaseName_1 = this.dbHelper.getDatabaseName(att);
1739                _builder.append(_databaseName_1, "\t");
1740                _builder.append("\", ");
1741                String _xifexpression = null;
1742                String _type = att.getType();
1743                boolean _equals_1 = Objects.equal(_type, "Date");
1744                if (_equals_1) {
1745                  _xifexpression = "JodaLocalDate";
1746                } else {
1747                  _xifexpression = "JodaDateTime";
1748                }
1749                String _plus = ("accessimpl.mongodb." + _xifexpression);
1750                String _plus_1 = (_plus + "Mapper");
1751                String _fw = this.properties.fw(_plus_1);
1752                _builder.append(_fw, "\t");
1753                _builder.append(".getInstance().toData(from.");
1754                String _getAccessor_1 = this.helper.getGetAccessor(att);
1755                _builder.append(_getAccessor_1, "\t");
1756                _builder.append("()));");
1757                _builder.newLineIfNotEmpty();
1758              } else {
1759                _builder.append("\t");
1760                _builder.append("result.put(\"");
1761                String _databaseName_2 = this.dbHelper.getDatabaseName(att);
1762                _builder.append(_databaseName_2, "\t");
1763                _builder.append("\", from.");
1764                String _getAccessor_2 = this.helper.getGetAccessor(att);
1765                _builder.append(_getAccessor_2, "\t");
1766                _builder.append("());");
1767                _builder.newLineIfNotEmpty();
1768              }
1769            }
1770          }
1771        }
1772      }
1773      _builder.newLine();
1774      {
1775        Collection<Reference> _allEnumReferences = this.helper.getAllEnumReferences(it);
1776        final Function1<Reference, Boolean> _function_2 = new Function1<Reference, Boolean>() {
1777          @Override
1778          public Boolean apply(final Reference e) {
1779            boolean _isTransient = e.isTransient();
1780            return Boolean.valueOf((!_isTransient));
1781          }
1782        };
1783        Iterable<Reference> _filter_1 = IterableExtensions.<Reference>filter(_allEnumReferences, _function_2);
1784        for(final Reference enumRef : _filter_1) {
1785          _builder.append("\t");
1786          _builder.append("result.put(\"");
1787          String _databaseName_3 = this.dbHelper.getDatabaseName(enumRef);
1788          _builder.append(_databaseName_3, "\t");
1789          _builder.append("\", from.");
1790          String _getAccessor_3 = this.helper.getGetAccessor(enumRef);
1791          _builder.append(_getAccessor_3, "\t");
1792          _builder.append("() == null ? null : from.");
1793          String _getAccessor_4 = this.helper.getGetAccessor(enumRef);
1794          _builder.append(_getAccessor_4, "\t");
1795          _builder.append("().name());");
1796          _builder.newLineIfNotEmpty();
1797        }
1798      }
1799      _builder.newLine();
1800      {
1801        final Function1<Reference, Boolean> _function_3 = new Function1<Reference, Boolean>() {
1802          @Override
1803          public Boolean apply(final Reference e) {
1804            boolean _or = false;
1805            boolean _isBasicTypeReference = MongoDbMapperTmpl.this.helper.isBasicTypeReference(e);
1806            if (_isBasicTypeReference) {
1807              _or = true;
1808            } else {
1809              boolean _and = false;
1810              boolean _and_1 = false;
1811              boolean _isMany = e.isMany();
1812              boolean _not = (!_isMany);
1813              if (!_not) {
1814                _and_1 = false;
1815              } else {
1816                boolean _bothEndsInSameAggregateRoot = MongoDbMapperTmpl.this.helper.bothEndsInSameAggregateRoot(e);
1817                _and_1 = _bothEndsInSameAggregateRoot;
1818              }
1819              if (!_and_1) {
1820                _and = false;
1821              } else {
1822                Reference _opposite = e.getOpposite();
1823                boolean _equals = Objects.equal(_opposite, null);
1824                _and = _equals;
1825              }
1826              _or = _and;
1827            }
1828            return Boolean.valueOf(_or);
1829          }
1830        };
1831        Iterable<Reference> _filter_2 = IterableExtensions.<Reference>filter(allNonEnumNonTransientReferences, _function_3);
1832        for(final Reference ref : _filter_2) {
1833          _builder.append("\t");
1834          _builder.append("result.put(\"");
1835          String _databaseName_4 = this.dbHelper.getDatabaseName(ref);
1836          _builder.append(_databaseName_4, "\t");
1837          _builder.append("\", ");
1838          _builder.newLineIfNotEmpty();
1839          _builder.append("\t");
1840          _builder.append("\t");
1841          DomainObject _to = ref.getTo();
1842          Module _module = _to.getModule();
1843          String _mapperPackage = this.mongoDbHelper.getMapperPackage(_module);
1844          _builder.append(_mapperPackage, "\t\t");
1845          _builder.append(".");
1846          DomainObject _to_1 = ref.getTo();
1847          String _name_3 = _to_1.getName();
1848          _builder.append(_name_3, "\t\t");
1849          _builder.append("Mapper.getInstance().toData(");
1850          _builder.newLineIfNotEmpty();
1851          _builder.append("\t");
1852          _builder.append("\t\t");
1853          _builder.append("from.get");
1854          String _name_4 = ref.getName();
1855          String _firstUpper = this.helperBase.toFirstUpper(_name_4);
1856          _builder.append(_firstUpper, "\t\t\t");
1857          _builder.append("()));");
1858          _builder.newLineIfNotEmpty();
1859        }
1860      }
1861      _builder.newLine();
1862      {
1863        final Function1<Reference, Boolean> _function_4 = new Function1<Reference, Boolean>() {
1864          @Override
1865          public Boolean apply(final Reference e) {
1866            boolean _and = false;
1867            boolean _and_1 = false;
1868            boolean _isBasicTypeReference = MongoDbMapperTmpl.this.helper.isBasicTypeReference(e);
1869            boolean _not = (!_isBasicTypeReference);
1870            if (!_not) {
1871              _and_1 = false;
1872            } else {
1873              boolean _isMany = e.isMany();
1874              _and_1 = _isMany;
1875            }
1876            if (!_and_1) {
1877              _and = false;
1878            } else {
1879              boolean _bothEndsInSameAggregateRoot = MongoDbMapperTmpl.this.helper.bothEndsInSameAggregateRoot(e);
1880              _and = _bothEndsInSameAggregateRoot;
1881            }
1882            return Boolean.valueOf(_and);
1883          }
1884        };
1885        Iterable<Reference> _filter_3 = IterableExtensions.<Reference>filter(allNonEnumNonTransientReferences, _function_4);
1886        for(final Reference ref_1 : _filter_3) {
1887          _builder.append("\t");
1888          _builder.append("java.util.List<com.mongodb.DBObject> ");
1889          String _name_5 = ref_1.getName();
1890          _builder.append(_name_5, "\t");
1891          _builder.append("Data = new java.util.ArrayList<com.mongodb.DBObject>();");
1892          _builder.newLineIfNotEmpty();
1893          _builder.append("\t");
1894          _builder.append("for (");
1895          String _typeName = this.helperBase.getTypeName(ref_1);
1896          _builder.append(_typeName, "\t");
1897          _builder.append(" each : from.get");
1898          String _name_6 = ref_1.getName();
1899          String _firstUpper_1 = this.helperBase.toFirstUpper(_name_6);
1900          _builder.append(_firstUpper_1, "\t");
1901          _builder.append("()) {");
1902          _builder.newLineIfNotEmpty();
1903          _builder.append("\t");
1904          _builder.append("\t");
1905          String _name_7 = ref_1.getName();
1906          _builder.append(_name_7, "\t\t");
1907          _builder.append("Data.add(");
1908          DomainObject _to_2 = ref_1.getTo();
1909          Module _module_1 = _to_2.getModule();
1910          String _mapperPackage_1 = this.mongoDbHelper.getMapperPackage(_module_1);
1911          _builder.append(_mapperPackage_1, "\t\t");
1912          _builder.append(".");
1913          DomainObject _to_3 = ref_1.getTo();
1914          String _name_8 = _to_3.getName();
1915          _builder.append(_name_8, "\t\t");
1916          _builder.append("Mapper.getInstance().toData(each));");
1917          _builder.newLineIfNotEmpty();
1918          _builder.append("\t");
1919          _builder.append("}");
1920          _builder.newLine();
1921          _builder.append("\t");
1922          _builder.append("result.put(\"");
1923          String _name_9 = ref_1.getName();
1924          _builder.append(_name_9, "\t");
1925          _builder.append("\", ");
1926          String _name_10 = ref_1.getName();
1927          _builder.append(_name_10, "\t");
1928          _builder.append("Data);");
1929          _builder.newLineIfNotEmpty();
1930        }
1931      }
1932      _builder.newLine();
1933      {
1934        final Function1<Reference, Boolean> _function_5 = new Function1<Reference, Boolean>() {
1935          @Override
1936          public Boolean apply(final Reference e) {
1937            boolean _and = false;
1938            boolean _isMany = e.isMany();
1939            boolean _not = (!_isMany);
1940            if (!_not) {
1941              _and = false;
1942            } else {
1943              boolean _isUnownedReference = MongoDbMapperTmpl.this.helper.isUnownedReference(e);
1944              _and = _isUnownedReference;
1945            }
1946            return Boolean.valueOf(_and);
1947          }
1948        };
1949        Iterable<Reference> _filter_4 = IterableExtensions.<Reference>filter(allNonEnumNonTransientReferences, _function_5);
1950        for(final Reference ref_2 : _filter_4) {
1951          _builder.append("\t");
1952          _builder.append("result.put(\"");
1953          String _databaseName_5 = this.dbHelper.getDatabaseName(ref_2);
1954          _builder.append(_databaseName_5, "\t");
1955          _builder.append("\", from.get");
1956          String _name_11 = ref_2.getName();
1957          String _firstUpper_2 = this.helperBase.toFirstUpper(_name_11);
1958          _builder.append(_firstUpper_2, "\t");
1959          _builder.append("Id()); ");
1960          _builder.newLineIfNotEmpty();
1961        }
1962      }
1963      _builder.newLine();
1964      {
1965        final Function1<Reference, Boolean> _function_6 = new Function1<Reference, Boolean>() {
1966          @Override
1967          public Boolean apply(final Reference e) {
1968            boolean _and = false;
1969            boolean _isMany = e.isMany();
1970            if (!_isMany) {
1971              _and = false;
1972            } else {
1973              boolean _isUnownedReference = MongoDbMapperTmpl.this.helper.isUnownedReference(e);
1974              _and = _isUnownedReference;
1975            }
1976            return Boolean.valueOf(_and);
1977          }
1978        };
1979        Iterable<Reference> _filter_5 = IterableExtensions.<Reference>filter(allNonEnumNonTransientReferences, _function_6);
1980        for(final Reference ref_3 : _filter_5) {
1981          _builder.append("\t");
1982          _builder.append("java.util.List<");
1983          String _javaType = this.helperBase.getJavaType("IDTYPE");
1984          _builder.append(_javaType, "\t");
1985          _builder.append("> ");
1986          String _name_12 = ref_3.getName();
1987          _builder.append(_name_12, "\t");
1988          _builder.append("Data = new java.util.ArrayList<");
1989          String _javaType_1 = this.helperBase.getJavaType("IDTYPE");
1990          _builder.append(_javaType_1, "\t");
1991          _builder.append(">();");
1992          _builder.newLineIfNotEmpty();
1993          _builder.append("\t");
1994          _builder.append("for (");
1995          String _javaType_2 = this.helperBase.getJavaType("IDTYPE");
1996          _builder.append(_javaType_2, "\t");
1997          _builder.append(" each : from.get");
1998          String _name_13 = ref_3.getName();
1999          String _firstUpper_3 = this.helperBase.toFirstUpper(_name_13);
2000          _builder.append(_firstUpper_3, "\t");
2001          _builder.append("Ids()) {");
2002          _builder.newLineIfNotEmpty();
2003          _builder.append("\t");
2004          _builder.append("\t");
2005          String _name_14 = ref_3.getName();
2006          _builder.append(_name_14, "\t\t");
2007          _builder.append("Data.add(each);");
2008          _builder.newLineIfNotEmpty();
2009          _builder.append("\t");
2010          _builder.append("}");
2011          _builder.newLine();
2012          _builder.append("\t");
2013          _builder.append("result.put(\"");
2014          String _databaseName_6 = this.dbHelper.getDatabaseName(ref_3);
2015          _builder.append(_databaseName_6, "\t");
2016          _builder.append("\", ");
2017          String _name_15 = ref_3.getName();
2018          _builder.append(_name_15, "\t");
2019          _builder.append("Data);");
2020          _builder.newLineIfNotEmpty();
2021        }
2022      }
2023      _builder.append("\t");
2024      _builder.append("return result;");
2025      _builder.newLine();
2026      _builder.append("}");
2027      _builder.newLine();
2028      _xblockexpression = _builder.toString();
2029    }
2030    return _xblockexpression;
2031  }
2032  
2033  public String indexes(final DomainObject it) {
2034    StringConcatenation _builder = new StringConcatenation();
2035    _builder.append("@Override");
2036    _builder.newLine();
2037    _builder.append("public java.util.List<");
2038    String _fw = this.properties.fw("accessimpl.mongodb.IndexSpecification");
2039    _builder.append(_fw, "");
2040    _builder.append("> indexes() {");
2041    _builder.newLineIfNotEmpty();
2042    {
2043      boolean _isAggregateRoot = it.isAggregateRoot();
2044      if (_isAggregateRoot) {
2045        _builder.append("java.util.List<");
2046        String _fw_1 = this.properties.fw("accessimpl.mongodb.IndexSpecification");
2047        _builder.append(_fw_1, "");
2048        _builder.append("> indexes = new java.util.ArrayList<");
2049        String _fw_2 = this.properties.fw("accessimpl.mongodb.IndexSpecification");
2050        _builder.append(_fw_2, "");
2051        _builder.append(">();");
2052        _builder.newLineIfNotEmpty();
2053        {
2054          boolean _hasNaturalKey = this.helper.hasNaturalKey(it);
2055          if (_hasNaturalKey) {
2056            _builder.append("com.mongodb.DBObject naturalKey = new com.mongodb.BasicDBObject();");
2057            _builder.newLine();
2058            String _populateNaturalKeyIndex = this.populateNaturalKeyIndex(it, "");
2059            _builder.append(_populateNaturalKeyIndex, "");
2060            _builder.newLineIfNotEmpty();
2061            _builder.append("indexes.add(new ");
2062            String _fw_3 = this.properties.fw("accessimpl.mongodb.IndexSpecification");
2063            _builder.append(_fw_3, "");
2064            _builder.append("(\"naturalKey\", naturalKey, true));");
2065            _builder.newLineIfNotEmpty();
2066          }
2067        }
2068        {
2069          Collection<Attribute> _allAttributes = this.helper.getAllAttributes(it);
2070          final Function1<Attribute, Boolean> _function = new Function1<Attribute, Boolean>() {
2071            @Override
2072            public Boolean apply(final Attribute e) {
2073              return Boolean.valueOf(e.isIndex());
2074            }
2075          };
2076          Iterable<Attribute> _filter = IterableExtensions.<Attribute>filter(_allAttributes, _function);
2077          for(final Attribute att : _filter) {
2078            _builder.append("indexes.add(new ");
2079            String _fw_4 = this.properties.fw("accessimpl.mongodb.IndexSpecification");
2080            _builder.append(_fw_4, "");
2081            _builder.append("(\"");
2082            String _name = att.getName();
2083            _builder.append(_name, "");
2084            _builder.append("\", new com.mongodb.BasicDBObject(\"");
2085            String _name_1 = att.getName();
2086            _builder.append(_name_1, "");
2087            _builder.append("\", 1), false));");
2088            _builder.newLineIfNotEmpty();
2089          }
2090        }
2091        _builder.append("return indexes;");
2092        _builder.newLine();
2093      } else {
2094        _builder.append("return java.util.Collections.emptyList();");
2095        _builder.newLine();
2096      }
2097    }
2098    _builder.append("}");
2099    _builder.newLine();
2100    return _builder.toString();
2101  }
2102  
2103  public String populateNaturalKeyIndex(final DomainObject it, final String parent) {
2104    StringConcatenation _builder = new StringConcatenation();
2105    List<Attribute> _allNaturalKeyAttributes = this.helper.getAllNaturalKeyAttributes(it);
2106    final Function1<Attribute, String> _function = new Function1<Attribute, String>() {
2107      @Override
2108      public String apply(final Attribute it) {
2109        return MongoDbMapperTmpl.this.putNaturalKeyIndex(it, parent);
2110      }
2111    };
2112    List<String> _map = ListExtensions.<Attribute, String>map(_allNaturalKeyAttributes, _function);
2113    String _join = IterableExtensions.join(_map);
2114    _builder.append(_join, "");
2115    _builder.newLineIfNotEmpty();
2116    List<Reference> _allNaturalKeyReferences = this.helper.getAllNaturalKeyReferences(it);
2117    final Function1<Reference, Boolean> _function_1 = new Function1<Reference, Boolean>() {
2118      @Override
2119      public Boolean apply(final Reference e) {
2120        return Boolean.valueOf(MongoDbMapperTmpl.this.helper.isEnumReference(e));
2121      }
2122    };
2123    Iterable<Reference> _filter = IterableExtensions.<Reference>filter(_allNaturalKeyReferences, _function_1);
2124    final Function1<Reference, String> _function_2 = new Function1<Reference, String>() {
2125      @Override
2126      public String apply(final Reference it) {
2127        return MongoDbMapperTmpl.this.putNaturalKeyIndex(it, parent);
2128      }
2129    };
2130    Iterable<String> _map_1 = IterableExtensions.<Reference, String>map(_filter, _function_2);
2131    String _join_1 = IterableExtensions.join(_map_1);
2132    _builder.append(_join_1, "");
2133    _builder.newLineIfNotEmpty();
2134    List<Reference> _allNaturalKeyReferences_1 = this.helper.getAllNaturalKeyReferences(it);
2135    final Function1<Reference, Boolean> _function_3 = new Function1<Reference, Boolean>() {
2136      @Override
2137      public Boolean apply(final Reference e) {
2138        return Boolean.valueOf(MongoDbMapperTmpl.this.helper.isUnownedReference(e));
2139      }
2140    };
2141    Iterable<Reference> _filter_1 = IterableExtensions.<Reference>filter(_allNaturalKeyReferences_1, _function_3);
2142    final Function1<Reference, String> _function_4 = new Function1<Reference, String>() {
2143      @Override
2144      public String apply(final Reference it) {
2145        return MongoDbMapperTmpl.this.putNaturalKeyIndex(it, parent);
2146      }
2147    };
2148    Iterable<String> _map_2 = IterableExtensions.<Reference, String>map(_filter_1, _function_4);
2149    String _join_2 = IterableExtensions.join(_map_2);
2150    _builder.append(_join_2, "");
2151    _builder.newLineIfNotEmpty();
2152    {
2153      List<Reference> _allNaturalKeyReferences_2 = this.helper.getAllNaturalKeyReferences(it);
2154      final Function1<Reference, Boolean> _function_5 = new Function1<Reference, Boolean>() {
2155        @Override
2156        public Boolean apply(final Reference e) {
2157          boolean _or = false;
2158          boolean _or_1 = false;
2159          boolean _isEnumReference = MongoDbMapperTmpl.this.helper.isEnumReference(e);
2160          if (_isEnumReference) {
2161            _or_1 = true;
2162          } else {
2163            boolean _isUnownedReference = MongoDbMapperTmpl.this.helper.isUnownedReference(e);
2164            _or_1 = _isUnownedReference;
2165          }
2166          if (_or_1) {
2167            _or = true;
2168          } else {
2169            DomainObject _to = e.getTo();
2170            boolean _isAggregateRoot = _to.isAggregateRoot();
2171            _or = _isAggregateRoot;
2172          }
2173          return Boolean.valueOf((!_or));
2174        }
2175      };
2176      Iterable<Reference> _filter_2 = IterableExtensions.<Reference>filter(_allNaturalKeyReferences_2, _function_5);
2177      for(final Reference e : _filter_2) {
2178        DomainObject _to = e.getTo();
2179        String _databaseName = this.dbHelper.getDatabaseName(e);
2180        String _plus = (parent + _databaseName);
2181        String _plus_1 = (_plus + ".");
2182        String _populateNaturalKeyIndex = this.populateNaturalKeyIndex(_to, _plus_1);
2183        _builder.append(_populateNaturalKeyIndex, "");
2184        _builder.newLineIfNotEmpty();
2185      }
2186    }
2187    return _builder.toString();
2188  }
2189  
2190  public String putNaturalKeyIndex(final NamedElement it, final String parent) {
2191    StringConcatenation _builder = new StringConcatenation();
2192    _builder.append("naturalKey.put(\"");
2193    _builder.append(parent, "");
2194    String _databaseName = this.dbHelper.getDatabaseName(it);
2195    _builder.append(_databaseName, "");
2196    _builder.append("\", 1);");
2197    _builder.newLineIfNotEmpty();
2198    return _builder.toString();
2199  }
2200  
2201  public String getDBCollectionName(final DomainObject it) {
2202    if (it instanceof BasicType) {
2203      return _getDBCollectionName((BasicType)it);
2204    } else if (it != null) {
2205      return _getDBCollectionName(it);
2206    } else {
2207      throw new IllegalArgumentException("Unhandled parameter types: " +
2208        Arrays.<Object>asList(it).toString());
2209    }
2210  }
2211}