Package my.home.dsl.generator

Source Code of my.home.dsl.generator.DeepCloneGenerator

package my.home.dsl.generator;

import com.google.common.collect.Iterables;
import com.google.inject.Inject;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import my.home.dsl.deepClone.Body;
import my.home.dsl.deepClone.ClassCloner;
import my.home.dsl.deepClone.ComplexField;
import my.home.dsl.deepClone.ContainerType;
import my.home.dsl.deepClone.FieldClonerType;
import my.home.dsl.deepClone.PackageConfig;
import my.home.dsl.deepClone.ReferenceField;
import my.home.dsl.deepClone.SimpleField;
import my.home.dsl.utils.DeepCloneUtils;
import my.home.dsl.utils.ReflectionUtils;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.util.TypeReferences;
import org.eclipse.xtext.generator.IFileSystemAccess;
import org.eclipse.xtext.generator.IGenerator;
import org.eclipse.xtext.naming.IQualifiedNameConverter;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.IterableExtensions;
import org.eclipse.xtext.xbase.lib.IteratorExtensions;
import org.eclipse.xtext.xbase.lib.ObjectExtensions;
import org.eclipse.xtext.xbase.lib.StringExtensions;

/**
* Generate Java code for DeepClone DSL for cloning Java bean instances.
* Input is complete set of all cloning definitions, potentially spread across several physical DSL files.
* Output is set of physical Java files arranged to appropriate directory hierarchy.
*
* Note: on the input there is Resource, usually it is mapped to one file, one particular
* DSL file, but it can be created synthetically, merging contents of several DSL files, preferably all of the same type.
*
* @see http://code.google.com/p/google-guice/wiki/InjectionPoints
* @author espinosa, 17.10.2012, 18.10.2012, 19.10, 9.11.2012
*/
@SuppressWarnings("all")
public class DeepCloneGenerator implements IGenerator {
  @Inject
  @Extension
  private IQualifiedNameConverter _iQualifiedNameConverter;
 
  @Inject
  @Extension
  private DeepCloneUtils _deepCloneUtils;
 
  @Inject
  @Extension
  private ReflectionUtils _reflectionUtils;
 
  private String packageNamespace;
 
  public void doGenerate(final Resource resource, final IFileSystemAccess fsa) {
    String _elvis = null;
    EList<EObject> _contents = resource.getContents();
    Iterable<Body> _filter = Iterables.<Body>filter(_contents, Body.class);
    Body _head = IterableExtensions.<Body>head(_filter);
    PackageConfig _packageConfig = _head.getPackageConfig();
    String _name = null;
    if (_packageConfig!=null) {
      _name=_packageConfig.getName();
    }
    if (_name != null) {
      _elvis = _name;
    } else {
      _elvis = ObjectExtensions.<String>operator_elvis(_name, "default");
    }
    this.packageNamespace = _elvis;
    TreeIterator<EObject> _allContents = resource.getAllContents();
    Iterable<EObject> _iterable = IteratorExtensions.<EObject>toIterable(_allContents);
    Iterable<ClassCloner> _filter_1 = Iterables.<ClassCloner>filter(_iterable, ClassCloner.class);
    for (final ClassCloner cc : _filter_1) {
      {
        JvmTypeReference _classToClone = cc.getClassToClone();
        final String clonedClassSimpleName = _classToClone.getSimpleName();
        String _elvis_1 = null;
        String _name_1 = cc.getName();
        if (_name_1 != null) {
          _elvis_1 = _name_1;
        } else {
          _elvis_1 = ObjectExtensions.<String>operator_elvis(_name_1, (clonedClassSimpleName + "Cloner"));
        }
        final String classClonerClassName = _elvis_1;
        QualifiedName _qualifiedName = this._iQualifiedNameConverter.toQualifiedName(this.packageNamespace);
        final QualifiedName clonerClassFQN = _qualifiedName.append(classClonerClassName);
        String _string = clonerClassFQN.toString("/");
        String _plus = (_string + ".java");
        CharSequence _generateJavaFileContent = this.generateJavaFileContent(cc, clonerClassFQN);
        fsa.generateFile(_plus, _generateJavaFileContent);
      }
    }
  }
 
  /**
   * Generate root level cloner
   */
  public CharSequence generateJavaFileContent(final ClassCloner cc, final QualifiedName clonerClassFQN) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("package ");
    QualifiedName _skipLast = clonerClassFQN.skipLast(1);
    _builder.append(_skipLast, "");
    _builder.append(";");
    _builder.newLineIfNotEmpty();
    _builder.append("public class ");
    String _lastSegment = clonerClassFQN.getLastSegment();
    _builder.append(_lastSegment, "");
    _builder.append(" {");
    _builder.newLineIfNotEmpty();
    _builder.append("\t");
    CharSequence _generateApplyMethodAndSubCloners = this.generateApplyMethodAndSubCloners(cc);
    _builder.append(_generateApplyMethodAndSubCloners, "\t");
    _builder.newLineIfNotEmpty();
    _builder.append("}");
    _builder.newLine();
    return _builder;
  }
 
  /**
   * Generate cloner for complex field, a sub-cloner.
   *
   * Current implementation generates static nested class inside main cloner class.
   * Sub cloners are nested recursively. This is an ultimate prevention of any name conflicts.
   * This method is recursively called for child complex fields.
   */
  public CharSequence generateSubClonerClass(final ComplexField complexField) {
    CharSequence _xblockexpression = null;
    {
      String _firstUpper = null;
      String _fieldName = complexField.getFieldName();
      if (_fieldName!=null) {
        _firstUpper=StringExtensions.toFirstUpper(_fieldName);
      }
      final String fieldClonerClass = (_firstUpper + "Cloner");
      String _firstLower = null;
      String _fieldName_1 = complexField.getFieldName();
      if (_fieldName_1!=null) {
        _firstLower=StringExtensions.toFirstLower(_fieldName_1);
      }
      final String fieldClonerInstance = (_firstLower + "Cloner");
      StringConcatenation _builder = new StringConcatenation();
      _builder.newLine();
      _builder.append("private final ");
      _builder.append(fieldClonerClass, "");
      _builder.append(" ");
      _builder.append(fieldClonerInstance, "");
      _builder.append(" = new ");
      _builder.append(fieldClonerClass, "");
      _builder.append("();");
      _builder.newLineIfNotEmpty();
      _builder.append("public static class ");
      _builder.append(fieldClonerClass, "");
      _builder.append(" {");
      _builder.newLineIfNotEmpty();
      _builder.append("\t");
      CharSequence _generateApplyMethodAndSubCloners = this.generateApplyMethodAndSubCloners(complexField);
      _builder.append(_generateApplyMethodAndSubCloners, "\t");
      _builder.newLineIfNotEmpty();
      _builder.append("}");
      _builder.newLine();
      _xblockexpression = (_builder);
    }
    return _xblockexpression;
  }
 
  /**
   * Declare instance of cloner for referenced cloner.
   * Example:
   * {@code private final SectionDeep sectionDeepCloner = new SectionDeep();}
   * for field:
   * {@code &section SectionDeep}
   */
  public CharSequence generateReferenceClonerInstance(final ReferenceField referenceField) {
    CharSequence _xblockexpression = null;
    {
      QualifiedName _qualifiedName = this._iQualifiedNameConverter.toQualifiedName(this.packageNamespace);
      ClassCloner _clonerReference = referenceField.getClonerReference();
      String _name = _clonerReference.getName();
      final QualifiedName fieldClonerClass = _qualifiedName.append(_name);
      String _firstLower = null;
      String _fieldName = referenceField.getFieldName();
      if (_fieldName!=null) {
        _firstLower=StringExtensions.toFirstLower(_fieldName);
      }
      final String fieldClonerInstance = (_firstLower + "Cloner");
      StringConcatenation _builder = new StringConcatenation();
      _builder.newLine();
      _builder.append("private final ");
      _builder.append(fieldClonerClass, "");
      _builder.append(" ");
      _builder.append(fieldClonerInstance, "");
      _builder.append(" = new ");
      _builder.append(fieldClonerClass, "");
      _builder.append("();");
      _builder.newLineIfNotEmpty();
      _xblockexpression = (_builder);
    }
    return _xblockexpression;
  }
 
  /**
   * Generate content for root and sub cloners: apply() method and all sub-cloners (if any)
   */
  public CharSequence generateApplyMethodAndSubCloners(final ContainerType container) {
    CharSequence _xblockexpression = null;
    {
      JvmTypeReference _javaType = container.getJavaType();
      JvmTypeReference _typeOrCollectionTypeParameter = this._reflectionUtils.getTypeOrCollectionTypeParameter(_javaType);
      final String containerType = _typeOrCollectionTypeParameter.getQualifiedName();
      StringConcatenation _builder = new StringConcatenation();
      _builder.append("public ");
      _builder.append(containerType, "");
      _builder.append(" apply(");
      _builder.append(containerType, "");
      _builder.append(" other) {");
      _builder.newLineIfNotEmpty();
      _builder.append("\t");
      _builder.append("if (other == null) return null;");
      _builder.newLine();
      _builder.append("\t");
      _builder.append(containerType, "\t");
      _builder.append(" it = new ");
      _builder.append(containerType, "\t");
      _builder.append("();");
      _builder.newLineIfNotEmpty();
      {
        EList<FieldClonerType> _fields = container.getFields();
        for(final FieldClonerType field : _fields) {
          {
            boolean _and = false;
            if (!(field instanceof SimpleField)) {
              _and = false;
            } else {
              boolean _isCollection = this._deepCloneUtils.isCollection(field);
              boolean _not = (!_isCollection);
              _and = ((field instanceof SimpleField) && _not);
            }
            if (_and) {
              _builder.append("\t");
              _builder.append("it.set");
              String _fieldName = field.getFieldName();
              String _firstUpper = StringExtensions.toFirstUpper(_fieldName);
              _builder.append(_firstUpper, "\t");
              _builder.append("(other.get");
              String _fieldName_1 = field.getFieldName();
              String _firstUpper_1 = StringExtensions.toFirstUpper(_fieldName_1);
              _builder.append(_firstUpper_1, "\t");
              _builder.append("());");
              _builder.newLineIfNotEmpty();
            } else {
              boolean _and_1 = false;
              if (!(field instanceof SimpleField)) {
                _and_1 = false;
              } else {
                boolean _isCollection_1 = this._deepCloneUtils.isCollection(field);
                _and_1 = ((field instanceof SimpleField) && _isCollection_1);
              }
              if (_and_1) {
                _builder.append("\t");
                _builder.append("it.set");
                String _fieldName_2 = field.getFieldName();
                String _firstUpper_2 = StringExtensions.toFirstUpper(_fieldName_2);
                _builder.append(_firstUpper_2, "\t");
                _builder.append("(");
                String _fieldName_3 = field.getFieldName();
                String _firstLower = StringExtensions.toFirstLower(_fieldName_3);
                _builder.append(_firstLower, "\t");
                _builder.append("CollectionCloner(it.get");
                String _fieldName_4 = field.getFieldName();
                String _firstUpper_3 = StringExtensions.toFirstUpper(_fieldName_4);
                _builder.append(_firstUpper_3, "\t");
                _builder.append("(), other.get");
                String _fieldName_5 = field.getFieldName();
                String _firstUpper_4 = StringExtensions.toFirstUpper(_fieldName_5);
                _builder.append(_firstUpper_4, "\t");
                _builder.append("()));");
                _builder.newLineIfNotEmpty();
              } else {
                boolean _and_2 = false;
                if (!(field instanceof ComplexField)) {
                  _and_2 = false;
                } else {
                  boolean _isCollection_2 = this._deepCloneUtils.isCollection(field);
                  boolean _not_1 = (!_isCollection_2);
                  _and_2 = ((field instanceof ComplexField) && _not_1);
                }
                if (_and_2) {
                  _builder.append("\t");
                  _builder.append("it.set");
                  String _fieldName_6 = field.getFieldName();
                  String _firstUpper_5 = StringExtensions.toFirstUpper(_fieldName_6);
                  _builder.append(_firstUpper_5, "\t");
                  _builder.append("(");
                  String _fieldName_7 = field.getFieldName();
                  String _firstLower_1 = StringExtensions.toFirstLower(_fieldName_7);
                  _builder.append(_firstLower_1, "\t");
                  _builder.append("Cloner.apply(other.get");
                  String _fieldName_8 = field.getFieldName();
                  String _firstUpper_6 = StringExtensions.toFirstUpper(_fieldName_8);
                  _builder.append(_firstUpper_6, "\t");
                  _builder.append("()));");
                  _builder.newLineIfNotEmpty();
                } else {
                  boolean _and_3 = false;
                  if (!(field instanceof ComplexField)) {
                    _and_3 = false;
                  } else {
                    boolean _isCollection_3 = this._deepCloneUtils.isCollection(field);
                    _and_3 = ((field instanceof ComplexField) && _isCollection_3);
                  }
                  if (_and_3) {
                    _builder.append("\t");
                    _builder.append("it.set");
                    String _fieldName_9 = field.getFieldName();
                    String _firstUpper_7 = StringExtensions.toFirstUpper(_fieldName_9);
                    _builder.append(_firstUpper_7, "\t");
                    _builder.append("(");
                    String _fieldName_10 = field.getFieldName();
                    String _firstLower_2 = StringExtensions.toFirstLower(_fieldName_10);
                    _builder.append(_firstLower_2, "\t");
                    _builder.append("CollectionCloner(it.get");
                    String _fieldName_11 = field.getFieldName();
                    String _firstUpper_8 = StringExtensions.toFirstUpper(_fieldName_11);
                    _builder.append(_firstUpper_8, "\t");
                    _builder.append("(), other.get");
                    String _fieldName_12 = field.getFieldName();
                    String _firstUpper_9 = StringExtensions.toFirstUpper(_fieldName_12);
                    _builder.append(_firstUpper_9, "\t");
                    _builder.append("()));");
                    _builder.newLineIfNotEmpty();
                  } else {
                    if ((field instanceof ReferenceField)) {
                      _builder.append("\t");
                      _builder.append("it.set");
                      String _fieldName_13 = field.getFieldName();
                      String _firstUpper_10 = StringExtensions.toFirstUpper(_fieldName_13);
                      _builder.append(_firstUpper_10, "\t");
                      _builder.append("(");
                      String _fieldName_14 = field.getFieldName();
                      String _firstLower_3 = StringExtensions.toFirstLower(_fieldName_14);
                      _builder.append(_firstLower_3, "\t");
                      _builder.append("Cloner.apply(other.get");
                      String _fieldName_15 = field.getFieldName();
                      String _firstUpper_11 = StringExtensions.toFirstUpper(_fieldName_15);
                      _builder.append(_firstUpper_11, "\t");
                      _builder.append("()));");
                      _builder.newLineIfNotEmpty();
                    }
                  }
                }
              }
            }
          }
        }
      }
      _builder.append("\t");
      _builder.append("return it;");
      _builder.newLine();
      _builder.append("}");
      _builder.newLine();
      {
        EList<FieldClonerType> _fields_1 = container.getFields();
        for(final FieldClonerType field_1 : _fields_1) {
          {
            boolean _and_4 = false;
            if (!(field_1 instanceof SimpleField)) {
              _and_4 = false;
            } else {
              boolean _isCollection_4 = this._deepCloneUtils.isCollection(field_1);
              _and_4 = ((field_1 instanceof SimpleField) && _isCollection_4);
            }
            if (_and_4) {
              CharSequence _generateCollectionFieldClonnerMethod = this.generateCollectionFieldClonnerMethod(((SimpleField) field_1));
              _builder.append(_generateCollectionFieldClonnerMethod, "");
              _builder.newLineIfNotEmpty();
            } else {
              boolean _and_5 = false;
              if (!(field_1 instanceof ComplexField)) {
                _and_5 = false;
              } else {
                boolean _isCollection_5 = this._deepCloneUtils.isCollection(field_1);
                _and_5 = ((field_1 instanceof ComplexField) && _isCollection_5);
              }
              if (_and_5) {
                CharSequence _generateCollectionComplexFieldClonnerMethod = this.generateCollectionComplexFieldClonnerMethod(((ComplexField) field_1));
                _builder.append(_generateCollectionComplexFieldClonnerMethod, "");
                _builder.newLineIfNotEmpty();
              }
            }
          }
          {
            if ((field_1 instanceof ComplexField)) {
              CharSequence _generateSubClonerClass = this.generateSubClonerClass(((ComplexField) field_1));
              _builder.append(_generateSubClonerClass, "");
              _builder.newLineIfNotEmpty();
            }
          }
          {
            if ((field_1 instanceof ReferenceField)) {
              CharSequence _generateReferenceClonerInstance = this.generateReferenceClonerInstance(((ReferenceField) field_1));
              _builder.append(_generateReferenceClonerInstance, "");
              _builder.newLineIfNotEmpty();
            }
          }
        }
      }
      _xblockexpression = (_builder);
    }
    return _xblockexpression;
  }
 
  /**
   * Generate private method for a field representing 1:N relation.
   * Every simple filed which is also a collection has a custom method generated.
   * Items are transfered one by one.
   */
  public CharSequence generateCollectionFieldClonnerMethod(final SimpleField field) {
    CharSequence _xblockexpression = null;
    {
      JvmTypeReference _javaType = field.getJavaType();
      final String collectionType = _javaType.getQualifiedName();
      JvmTypeReference _javaType_1 = field.getJavaType();
      JvmTypeReference _typeOrCollectionTypeParameter = this._reflectionUtils.getTypeOrCollectionTypeParameter(_javaType_1);
      final String collectionItemType = _typeOrCollectionTypeParameter.getQualifiedName();
      StringConcatenation _builder = new StringConcatenation();
      _builder.newLine();
      _builder.append("private ");
      _builder.append(collectionType, "");
      _builder.append(" ");
      String _fieldName = field.getFieldName();
      String _firstLower = StringExtensions.toFirstLower(_fieldName);
      _builder.append(_firstLower, "");
      _builder.append("CollectionCloner(");
      _builder.append(collectionType, "");
      _builder.append(" thisCollection, ");
      _builder.append(collectionType, "");
      _builder.append(" otherCollection) {");
      _builder.newLineIfNotEmpty();
      _builder.append("\t");
      _builder.append("if (otherCollection == null) return null;");
      _builder.newLine();
      _builder.append("\t");
      JvmTypeReference _javaType_2 = field.getJavaType();
      CharSequence _createCollection = this.createCollection(_javaType_2);
      _builder.append(_createCollection, "\t");
      _builder.newLineIfNotEmpty();
      _builder.append("\t");
      _builder.append("for (");
      _builder.append(collectionItemType, "\t");
      _builder.append(" otherCollectionItem : otherCollection) {");
      _builder.newLineIfNotEmpty();
      _builder.append("\t\t");
      _builder.append("thisCollection.add(otherCollectionItem);");
      _builder.newLine();
      _builder.append("\t");
      _builder.append("}");
      _builder.newLine();
      _builder.append("\t");
      _builder.append("return thisCollection;");
      _builder.newLine();
      _builder.append("}");
      _builder.newLine();
      _xblockexpression = (_builder);
    }
    return _xblockexpression;
  }
 
  /**
   * Generate private method for a field representing 1:N relation. A complex field with its own sub-cloner.
   * Every simple filed which is also a collection has a custom method generated.
   * Items are transfered one by one calling sub-cloner apply() method.
   */
  public CharSequence generateCollectionComplexFieldClonnerMethod(final ComplexField field) {
    CharSequence _xblockexpression = null;
    {
      JvmTypeReference _javaType = field.getJavaType();
      final String collectionType = _javaType.getQualifiedName();
      JvmTypeReference _javaType_1 = field.getJavaType();
      JvmTypeReference _typeOrCollectionTypeParameter = this._reflectionUtils.getTypeOrCollectionTypeParameter(_javaType_1);
      final String collectionItemType = _typeOrCollectionTypeParameter.getQualifiedName();
      StringConcatenation _builder = new StringConcatenation();
      _builder.newLine();
      _builder.append("private ");
      _builder.append(collectionType, "");
      _builder.append(" ");
      String _fieldName = field.getFieldName();
      String _firstLower = StringExtensions.toFirstLower(_fieldName);
      _builder.append(_firstLower, "");
      _builder.append("CollectionCloner(");
      _builder.append(collectionType, "");
      _builder.append(" thisCollection, ");
      _builder.append(collectionType, "");
      _builder.append(" otherCollection) {");
      _builder.newLineIfNotEmpty();
      _builder.append("\t");
      _builder.append("if (otherCollection == null) return null;");
      _builder.newLine();
      _builder.append("\t");
      JvmTypeReference _javaType_2 = field.getJavaType();
      CharSequence _createCollection = this.createCollection(_javaType_2);
      _builder.append(_createCollection, "\t");
      _builder.newLineIfNotEmpty();
      _builder.append("\t");
      _builder.append("for (");
      _builder.append(collectionItemType, "\t");
      _builder.append(" otherCollectionItem : otherCollection) {");
      _builder.newLineIfNotEmpty();
      _builder.append("\t\t");
      _builder.append("thisCollection.add(");
      String _fieldName_1 = field.getFieldName();
      String _firstLower_1 = StringExtensions.toFirstLower(_fieldName_1);
      _builder.append(_firstLower_1, "\t\t");
      _builder.append("Cloner.apply(otherCollectionItem));");
      _builder.newLineIfNotEmpty();
      _builder.append("\t");
      _builder.append("}");
      _builder.newLine();
      _builder.append("\t");
      _builder.append("return thisCollection;");
      _builder.newLine();
      _builder.append("}");
      _builder.newLine();
      _xblockexpression = (_builder);
    }
    return _xblockexpression;
  }
 
  @Inject
  @Extension
  private TypeReferences _typeReferences;
 
  public CharSequence createCollection(final JvmTypeReference collectionType) {
    CharSequence _switchResult = null;
    boolean _matched = false;
    if (!_matched) {
      boolean _isInstanceOf = this._typeReferences.isInstanceOf(collectionType, List.class);
      if (_isInstanceOf) {
        _matched=true;
        StringConcatenation _builder = new StringConcatenation();
        _builder.append("if (thisCollection == null) thisCollection = new java.util.ArrayList<");
        String _typeParameter = this._reflectionUtils.getTypeParameter(collectionType);
        _builder.append(_typeParameter, "");
        _builder.append(">();");
        _builder.newLineIfNotEmpty();
        _switchResult = _builder;
      }
    }
    if (!_matched) {
      boolean _isInstanceOf_1 = this._typeReferences.isInstanceOf(collectionType, Set.class);
      if (_isInstanceOf_1) {
        _matched=true;
        StringConcatenation _builder_1 = new StringConcatenation();
        _builder_1.append("if (thisCollection == null) thisCollection = new java.util.HashSet<");
        String _typeParameter_1 = this._reflectionUtils.getTypeParameter(collectionType);
        _builder_1.append(_typeParameter_1, "");
        _builder_1.append(">();");
        _builder_1.newLineIfNotEmpty();
        _switchResult = _builder_1;
      }
    }
    if (!_matched) {
      boolean _isInstanceOf_2 = this._typeReferences.isInstanceOf(collectionType, Collection.class);
      if (_isInstanceOf_2) {
        _matched=true;
        StringConcatenation _builder_2 = new StringConcatenation();
        _builder_2.append("if (thisCollection == null) thisCollection = new java.util.ArrayList<");
        String _typeParameter_2 = this._reflectionUtils.getTypeParameter(collectionType);
        _builder_2.append(_typeParameter_2, "");
        _builder_2.append(">();");
        _builder_2.newLineIfNotEmpty();
        _switchResult = _builder_2;
      }
    }
    if (!_matched) {
      StringConcatenation _builder_3 = new StringConcatenation();
      _builder_3.append("// unrecognized collection type");
      _switchResult = _builder_3;
    }
    return _switchResult;
  }
}
TOP

Related Classes of my.home.dsl.generator.DeepCloneGenerator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.