/**
 * Copyright (c) 2011, 2016 - Loetz GmbH&Co.KG (69115 Heidelberg, Germany)
 * 
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * 
 * Contributors:
 * Christophe Loetz (Loetz GmbH&Co.KG) - initial implementation
 * 
 * 
 *  This copyright notice shows up in the generated Java code
 */
package org.eclipse.osbp.xtext.reportdsl.jvmmodel;

import com.google.common.base.Objects;
import com.vaadin.data.Container;
import com.vaadin.ui.VerticalLayout;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.function.Consumer;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Inject;
import org.eclipse.e4.core.contexts.IEclipseContext;
import org.eclipse.e4.core.services.events.IEventBroker;
import org.eclipse.e4.ui.model.application.MApplication;
import org.eclipse.e4.ui.workbench.IPresentationEngine;
import org.eclipse.emf.common.util.EList;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.osbp.dsl.semantic.common.types.LTypedPackage;
import org.eclipse.osbp.dsl.semantic.entity.LEntity;
import org.eclipse.osbp.eventbroker.EventBrokerMsg;
import org.eclipse.osbp.ui.api.datamart.IDataMart;
import org.eclipse.osbp.ui.api.report.IReportProvider;
import org.eclipse.osbp.ui.api.themes.IThemeResourceService;
import org.eclipse.osbp.utils.constants.GeneratorConstants;
import org.eclipse.osbp.xtext.action.ActionPackage;
import org.eclipse.osbp.xtext.action.ActionToolbar;
import org.eclipse.osbp.xtext.datamartdsl.DatamartDefinition;
import org.eclipse.osbp.xtext.datamartdsl.jvmmodel.DatamartDSLJvmModelInferrer;
import org.eclipse.osbp.xtext.reportdsl.RenderingEnum;
import org.eclipse.osbp.xtext.reportdsl.Report;
import org.eclipse.osbp.xtext.reportdsl.ReportDesign;
import org.eclipse.osbp.xtext.reportdsl.ReportDesignFile;
import org.eclipse.osbp.xtext.reportdsl.ReportDesignTemplate;
import org.eclipse.osbp.xtext.reportdsl.ReportPackage;
import org.eclipse.osbp.xtext.reportdsl.common.AbstractReportBean;
import org.eclipse.osbp.xtext.reportdsl.common.BaseReport;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.common.types.JvmAnnotationReference;
import org.eclipse.xtext.common.types.JvmConstructor;
import org.eclipse.xtext.common.types.JvmDeclaredType;
import org.eclipse.xtext.common.types.JvmField;
import org.eclipse.xtext.common.types.JvmFormalParameter;
import org.eclipse.xtext.common.types.JvmGenericType;
import org.eclipse.xtext.common.types.JvmMember;
import org.eclipse.xtext.common.types.JvmOperation;
import org.eclipse.xtext.common.types.JvmTypeReference;
import org.eclipse.xtext.common.types.JvmVisibility;
import org.eclipse.xtext.naming.IQualifiedNameProvider;
import org.eclipse.xtext.naming.QualifiedName;
import org.eclipse.xtext.xbase.compiler.output.ITreeAppendable;
import org.eclipse.xtext.xbase.jvmmodel.AbstractModelInferrer;
import org.eclipse.xtext.xbase.jvmmodel.IJvmDeclaredTypeAcceptor;
import org.eclipse.xtext.xbase.jvmmodel.JvmTypesBuilder;
import org.eclipse.xtext.xbase.lib.Extension;
import org.eclipse.xtext.xbase.lib.Procedures.Procedure1;
import org.eclipse.xtext.xbase.lib.StringExtensions;

/**
 * <p>Infers a JVM model from the source model.</p>
 * 
 * <p>The JVM model should contain all elements that would appear in the Java code
 * which is generated from the source model. Other models link against the JVM model rather than the source model.</p>
 */
@SuppressWarnings("all")
public class ReportDSLJvmModelInferrer extends AbstractModelInferrer {
  /**
   * convenience API to build and initialize JVM types and their members.
   */
  @Inject
  @Extension
  private JvmTypesBuilder _jvmTypesBuilder;
  
  @Inject
  @Extension
  private IQualifiedNameProvider _iQualifiedNameProvider;
  
  @Inject
  @Extension
  private DatamartDSLJvmModelInferrer _datamartDSLJvmModelInferrer;
  
  protected void _infer(final ReportPackage pckg, final IJvmDeclaredTypeAcceptor acceptor, final boolean isPreIndexingPhase) {
    EList<Report> _reports = pckg.getReports();
    final Consumer<Report> _function = new Consumer<Report>() {
      public void accept(final Report report) {
        QualifiedName _fullyQualifiedName = ReportDSLJvmModelInferrer.this._iQualifiedNameProvider.getFullyQualifiedName(report);
        String _plus = (_fullyQualifiedName + "Report");
        JvmGenericType cls = ReportDSLJvmModelInferrer.this._jvmTypesBuilder.toClass(report, _plus);
        final Procedure1<JvmGenericType> _function = new Procedure1<JvmGenericType>() {
          public void apply(final JvmGenericType it) {
            EList<JvmTypeReference> _superTypes = it.getSuperTypes();
            JvmTypeReference _typeRef = ReportDSLJvmModelInferrer.this._typeReferenceBuilder.typeRef(BaseReport.class);
            _superTypes.add(_typeRef);
            ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setDocumentation(it, GeneratorConstants.GENERATED_CLASSES_DOCUMENTATION);
            ReportDSLJvmModelInferrer.this.toConstructor(it, report);
            ReportDSLJvmModelInferrer.this.toOperations(it, pckg, report);
          }
        };
        acceptor.<JvmGenericType>accept(cls, _function);
        ReportDSLJvmModelInferrer.this.addReportBean(cls, pckg, report, acceptor);
      }
    };
    _reports.forEach(_function);
  }
  
  public void addReportBean(final JvmDeclaredType type, final ReportPackage pckg, final Report report, final IJvmDeclaredTypeAcceptor acceptor) {
    JvmGenericType beanCls = this._jvmTypesBuilder.toClass(report, "Bean");
    EList<JvmMember> _members = type.getMembers();
    this._jvmTypesBuilder.<JvmGenericType>operator_add(_members, beanCls);
    final Procedure1<JvmGenericType> _function = new Procedure1<JvmGenericType>() {
      public void apply(final JvmGenericType it) {
        EList<JvmTypeReference> _superTypes = it.getSuperTypes();
        JvmTypeReference _typeRef = ReportDSLJvmModelInferrer.this._typeReferenceBuilder.typeRef(AbstractReportBean.class);
        _superTypes.add(_typeRef);
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setDocumentation(it, GeneratorConstants.GENERATED_CLASSES_DOCUMENTATION);
        it.setStatic(true);
        EList<JvmMember> _members = it.getMembers();
        JvmTypeReference _typeRef_1 = ReportDSLJvmModelInferrer.this._typeReferenceBuilder.typeRef(BaseReport.class);
        final Procedure1<JvmOperation> _function = new Procedure1<JvmOperation>() {
          public void apply(final JvmOperation it) {
            it.setVisibility(JvmVisibility.PROTECTED);
            EList<JvmAnnotationReference> _annotations = it.getAnnotations();
            JvmAnnotationReference _annotationRef = ReportDSLJvmModelInferrer.this._annotationTypesBuilder.annotationRef(Override.class);
            ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, _annotationRef);
            final Procedure1<ITreeAppendable> _function = new Procedure1<ITreeAppendable>() {
              public void apply(final ITreeAppendable it) {
                StringConcatenation _builder = new StringConcatenation();
                _builder.append("return new ");
                QualifiedName _fullyQualifiedName = ReportDSLJvmModelInferrer.this._iQualifiedNameProvider.getFullyQualifiedName(report);
                _builder.append(_fullyQualifiedName, "");
                _builder.append("Report(null,null,null);");
                it.append(_builder);
              }
            };
            ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setBody(it, _function);
          }
        };
        JvmOperation _method = ReportDSLJvmModelInferrer.this._jvmTypesBuilder.toMethod(report, "createReport", _typeRef_1, _function);
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmOperation>operator_add(_members, _method);
      }
    };
    acceptor.<JvmGenericType>accept(beanCls, _function);
  }
  
  public void toConstructor(final JvmDeclaredType type, final Report report) {
    EList<JvmMember> _members = type.getMembers();
    final Procedure1<JvmConstructor> _function = new Procedure1<JvmConstructor>() {
      public void apply(final JvmConstructor it) {
        String _documentation = ReportDSLJvmModelInferrer.this._jvmTypesBuilder.getDocumentation(report);
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setDocumentation(it, _documentation);
        EList<JvmAnnotationReference> _annotations = it.getAnnotations();
        JvmAnnotationReference _annotationRef = ReportDSLJvmModelInferrer.this._annotationTypesBuilder.annotationRef(Inject.class);
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, _annotationRef);
        EList<JvmFormalParameter> _parameters = it.getParameters();
        JvmTypeReference _typeRef = ReportDSLJvmModelInferrer.this._typeReferenceBuilder.typeRef(VerticalLayout.class);
        JvmFormalParameter _parameter = ReportDSLJvmModelInferrer.this._jvmTypesBuilder.toParameter(report, "parent", _typeRef);
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmFormalParameter>operator_add(_parameters, _parameter);
        EList<JvmFormalParameter> _parameters_1 = it.getParameters();
        JvmTypeReference _typeRef_1 = ReportDSLJvmModelInferrer.this._typeReferenceBuilder.typeRef(IEclipseContext.class);
        JvmFormalParameter _parameter_1 = ReportDSLJvmModelInferrer.this._jvmTypesBuilder.toParameter(report, "context", _typeRef_1);
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmFormalParameter>operator_add(_parameters_1, _parameter_1);
        EList<JvmFormalParameter> _parameters_2 = it.getParameters();
        JvmTypeReference _typeRef_2 = ReportDSLJvmModelInferrer.this._typeReferenceBuilder.typeRef(MApplication.class);
        JvmFormalParameter _parameter_2 = ReportDSLJvmModelInferrer.this._jvmTypesBuilder.toParameter(report, "app", _typeRef_2);
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmFormalParameter>operator_add(_parameters_2, _parameter_2);
        final Procedure1<ITreeAppendable> _function = new Procedure1<ITreeAppendable>() {
          public void apply(final ITreeAppendable it) {
            StringConcatenation _builder = new StringConcatenation();
            _builder.append("super(parent,context,app);");
            it.append(_builder);
          }
        };
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setBody(it, _function);
      }
    };
    JvmConstructor _constructor = this._jvmTypesBuilder.toConstructor(report, _function);
    this._jvmTypesBuilder.<JvmConstructor>operator_add(_members, _constructor);
  }
  
  public void toOperations(final JvmDeclaredType type, final ReportPackage pckg, final Report report) {
    EList<JvmMember> _members = type.getMembers();
    JvmTypeReference _typeRef = this._typeReferenceBuilder.typeRef(IEventBroker.class);
    final Procedure1<JvmField> _function = new Procedure1<JvmField>() {
      public void apply(final JvmField it) {
        EList<JvmAnnotationReference> _annotations = it.getAnnotations();
        JvmAnnotationReference _annotationRef = ReportDSLJvmModelInferrer.this._annotationTypesBuilder.annotationRef(Inject.class);
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, _annotationRef);
      }
    };
    JvmField _field = this._jvmTypesBuilder.toField(report, "eventBroker", _typeRef, _function);
    this._jvmTypesBuilder.<JvmField>operator_add(_members, _field);
    EList<JvmMember> _members_1 = type.getMembers();
    JvmTypeReference _typeRef_1 = this._typeReferenceBuilder.typeRef(IPresentationEngine.class);
    final Procedure1<JvmField> _function_1 = new Procedure1<JvmField>() {
      public void apply(final JvmField it) {
        EList<JvmAnnotationReference> _annotations = it.getAnnotations();
        JvmAnnotationReference _annotationRef = ReportDSLJvmModelInferrer.this._annotationTypesBuilder.annotationRef(Inject.class);
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, _annotationRef);
      }
    };
    JvmField _field_1 = this._jvmTypesBuilder.toField(report, "renderingEngine", _typeRef_1, _function_1);
    this._jvmTypesBuilder.<JvmField>operator_add(_members_1, _field_1);
    EList<JvmMember> _members_2 = type.getMembers();
    JvmTypeReference _typeRef_2 = this._typeReferenceBuilder.typeRef(IThemeResourceService.class);
    final Procedure1<JvmField> _function_2 = new Procedure1<JvmField>() {
      public void apply(final JvmField it) {
        EList<JvmAnnotationReference> _annotations = it.getAnnotations();
        JvmAnnotationReference _annotationRef = ReportDSLJvmModelInferrer.this._annotationTypesBuilder.annotationRef(Inject.class);
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, _annotationRef);
      }
    };
    JvmField _field_2 = this._jvmTypesBuilder.toField(report, "themeResourceService", _typeRef_2, _function_2);
    this._jvmTypesBuilder.<JvmField>operator_add(_members_2, _field_2);
    ActionToolbar _toolbar = report.getToolbar();
    boolean _notEquals = (!Objects.equal(_toolbar, null));
    if (_notEquals) {
      ActionToolbar _toolbar_1 = report.getToolbar();
      EObject _eContainer = _toolbar_1.eContainer();
      QualifiedName _fullyQualifiedName = this._iQualifiedNameProvider.getFullyQualifiedName(((ActionPackage) _eContainer));
      String packageName = _fullyQualifiedName.toString();
      EList<JvmMember> _members_3 = type.getMembers();
      StringConcatenation _builder = new StringConcatenation();
      _builder.append(packageName, "");
      _builder.append(".");
      ActionToolbar _toolbar_2 = report.getToolbar();
      String _name = _toolbar_2.getName();
      String _string = _name.toString();
      String _firstUpper = StringExtensions.toFirstUpper(_string);
      _builder.append(_firstUpper, "");
      _builder.append("Action");
      JvmTypeReference _typeRef_3 = this._typeReferenceBuilder.typeRef(_builder.toString());
      JvmField _field_3 = this._jvmTypesBuilder.toField(report, "toolbarClass", _typeRef_3);
      this._jvmTypesBuilder.<JvmField>operator_add(_members_3, _field_3);
    }
    EList<JvmMember> _members_4 = type.getMembers();
    JvmTypeReference _typeRef_4 = this._typeReferenceBuilder.typeRef(Void.TYPE);
    final Procedure1<JvmOperation> _function_3 = new Procedure1<JvmOperation>() {
      public void apply(final JvmOperation it) {
        EList<JvmFormalParameter> _parameters = it.getParameters();
        JvmTypeReference _typeRef = ReportDSLJvmModelInferrer.this._typeReferenceBuilder.typeRef(VerticalLayout.class);
        JvmFormalParameter _parameter = ReportDSLJvmModelInferrer.this._jvmTypesBuilder.toParameter(report, "parent", _typeRef);
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmFormalParameter>operator_add(_parameters, _parameter);
        final Procedure1<ITreeAppendable> _function = new Procedure1<ITreeAppendable>() {
          public void apply(final ITreeAppendable it) {
            StringConcatenation _builder = new StringConcatenation();
            CharSequence _createView = ReportDSLJvmModelInferrer.this.createView(report);
            _builder.append(_createView, "");
            it.append(_builder);
          }
        };
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setBody(it, _function);
      }
    };
    JvmOperation _method = this._jvmTypesBuilder.toMethod(report, "createView", _typeRef_4, _function_3);
    this._jvmTypesBuilder.<JvmOperation>operator_add(_members_4, _method);
    EList<JvmMember> _members_5 = type.getMembers();
    JvmTypeReference _typeRef_5 = this._typeReferenceBuilder.typeRef(Void.TYPE);
    final Procedure1<JvmOperation> _function_4 = new Procedure1<JvmOperation>() {
      public void apply(final JvmOperation it) {
        it.setVisibility(JvmVisibility.PROTECTED);
        EList<JvmAnnotationReference> _annotations = it.getAnnotations();
        JvmAnnotationReference _annotationRef = ReportDSLJvmModelInferrer.this._annotationTypesBuilder.annotationRef(PostConstruct.class);
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, _annotationRef);
        final Procedure1<ITreeAppendable> _function = new Procedure1<ITreeAppendable>() {
          public void apply(final ITreeAppendable it) {
            Set<LEntity> entites = ReportDSLJvmModelInferrer.this.findRequestedEntities(report);
            for (final LEntity entity : entites) {
              StringConcatenation _builder = new StringConcatenation();
              _builder.append("eventBroker.subscribe(EventBrokerMsg.REFRESH_VIEW+\"");
              EObject _eContainer = entity.eContainer();
              String _name = ((LTypedPackage) _eContainer).getName();
              String _name_1 = entity.getName();
              String _entityIdModifiedCategory = EventBrokerMsg.getEntityIdModifiedCategory(_name, _name_1);
              _builder.append(_entityIdModifiedCategory, "");
              _builder.append("\", fModifiedEntityIdsListener);");
              _builder.newLineIfNotEmpty();
              it.append(_builder);
            }
          }
        };
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setBody(it, _function);
      }
    };
    JvmOperation _method_1 = this._jvmTypesBuilder.toMethod(report, "subscribe", _typeRef_5, _function_4);
    this._jvmTypesBuilder.<JvmOperation>operator_add(_members_5, _method_1);
    EList<JvmMember> _members_6 = type.getMembers();
    JvmTypeReference _typeRef_6 = this._typeReferenceBuilder.typeRef(Void.TYPE);
    final Procedure1<JvmOperation> _function_5 = new Procedure1<JvmOperation>() {
      public void apply(final JvmOperation it) {
        it.setVisibility(JvmVisibility.PROTECTED);
        EList<JvmAnnotationReference> _annotations = it.getAnnotations();
        JvmAnnotationReference _annotationRef = ReportDSLJvmModelInferrer.this._annotationTypesBuilder.annotationRef(PreDestroy.class);
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, _annotationRef);
        final Procedure1<ITreeAppendable> _function = new Procedure1<ITreeAppendable>() {
          public void apply(final ITreeAppendable it) {
            StringConcatenation _builder = new StringConcatenation();
            _builder.append("eventBroker.unsubscribe(fModifiedEntityIdsListener);");
            _builder.newLine();
            it.append(_builder);
          }
        };
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setBody(it, _function);
      }
    };
    JvmOperation _method_2 = this._jvmTypesBuilder.toMethod(report, "unsubscribe", _typeRef_6, _function_5);
    this._jvmTypesBuilder.<JvmOperation>operator_add(_members_6, _method_2);
    EList<JvmMember> _members_7 = type.getMembers();
    JvmTypeReference _typeRef_7 = this._typeReferenceBuilder.typeRef(IReportProvider.Rendering.class);
    final Procedure1<JvmOperation> _function_6 = new Procedure1<JvmOperation>() {
      public void apply(final JvmOperation it) {
        it.setVisibility(JvmVisibility.PROTECTED);
        EList<JvmAnnotationReference> _annotations = it.getAnnotations();
        JvmAnnotationReference _annotationRef = ReportDSLJvmModelInferrer.this._annotationTypesBuilder.annotationRef(Override.class);
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, _annotationRef);
        final Procedure1<ITreeAppendable> _function = new Procedure1<ITreeAppendable>() {
          public void apply(final ITreeAppendable it) {
            RenderingEnum _rendering = report.getRendering();
            if (_rendering != null) {
              switch (_rendering) {
                case HTML:
                  StringConcatenation _builder = new StringConcatenation();
                  _builder.append("return Rendering.HTML_STREAM;");
                  it.append(_builder);
                  break;
                case PDF:
                  StringConcatenation _builder_1 = new StringConcatenation();
                  _builder_1.append("return Rendering.PDF_STREAM;");
                  it.append(_builder_1);
                  break;
                default:
                  break;
              }
            }
          }
        };
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setBody(it, _function);
      }
    };
    JvmOperation _method_3 = this._jvmTypesBuilder.toMethod(report, "getRenderingAs", _typeRef_7, _function_6);
    this._jvmTypesBuilder.<JvmOperation>operator_add(_members_7, _method_3);
    EList<JvmMember> _members_8 = type.getMembers();
    JvmTypeReference _typeRef_8 = this._typeReferenceBuilder.typeRef(String.class);
    final Procedure1<JvmOperation> _function_7 = new Procedure1<JvmOperation>() {
      public void apply(final JvmOperation it) {
        it.setVisibility(JvmVisibility.PROTECTED);
        EList<JvmAnnotationReference> _annotations = it.getAnnotations();
        JvmAnnotationReference _annotationRef = ReportDSLJvmModelInferrer.this._annotationTypesBuilder.annotationRef(Override.class);
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, _annotationRef);
        final Procedure1<ITreeAppendable> _function = new Procedure1<ITreeAppendable>() {
          public void apply(final ITreeAppendable it) {
            StringConcatenation _builder = new StringConcatenation();
            _builder.append("return \"");
            String _name = report.getName();
            _builder.append(_name, "");
            _builder.append("\";");
            it.append(_builder);
          }
        };
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setBody(it, _function);
      }
    };
    JvmOperation _method_4 = this._jvmTypesBuilder.toMethod(report, "getReportName", _typeRef_8, _function_7);
    this._jvmTypesBuilder.<JvmOperation>operator_add(_members_8, _method_4);
    boolean _or = false;
    String _externalCssURIBundle = pckg.getExternalCssURIBundle();
    boolean _notEquals_1 = (!Objects.equal(_externalCssURIBundle, null));
    if (_notEquals_1) {
      _or = true;
    } else {
      String _externalCssURIBundle_1 = report.getExternalCssURIBundle();
      boolean _notEquals_2 = (!Objects.equal(_externalCssURIBundle_1, null));
      _or = _notEquals_2;
    }
    if (_or) {
      EList<JvmMember> _members_9 = type.getMembers();
      JvmTypeReference _typeRef_9 = this._typeReferenceBuilder.typeRef(String.class);
      final Procedure1<JvmOperation> _function_8 = new Procedure1<JvmOperation>() {
        public void apply(final JvmOperation it) {
          it.setVisibility(JvmVisibility.PROTECTED);
          EList<JvmAnnotationReference> _annotations = it.getAnnotations();
          JvmAnnotationReference _annotationRef = ReportDSLJvmModelInferrer.this._annotationTypesBuilder.annotationRef(Override.class);
          ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, _annotationRef);
          final Procedure1<ITreeAppendable> _function = new Procedure1<ITreeAppendable>() {
            public void apply(final ITreeAppendable it) {
              String _externalCssURIBundle = report.getExternalCssURIBundle();
              boolean _notEquals = (!Objects.equal(_externalCssURIBundle, null));
              if (_notEquals) {
                StringConcatenation _builder = new StringConcatenation();
                _builder.append("return \"");
                String _externalCssURIBundle_1 = report.getExternalCssURIBundle();
                _builder.append(_externalCssURIBundle_1, "");
                _builder.append("\";");
                it.append(_builder);
              } else {
                StringConcatenation _builder_1 = new StringConcatenation();
                _builder_1.append("return \"");
                String _externalCssURIBundle_2 = pckg.getExternalCssURIBundle();
                _builder_1.append(_externalCssURIBundle_2, "");
                _builder_1.append("\";");
                it.append(_builder_1);
              }
            }
          };
          ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setBody(it, _function);
        }
      };
      JvmOperation _method_5 = this._jvmTypesBuilder.toMethod(report, "getExternalCssURIBundle", _typeRef_9, _function_8);
      this._jvmTypesBuilder.<JvmOperation>operator_add(_members_9, _method_5);
    }
    boolean _or_1 = false;
    String _externalCssURI = pckg.getExternalCssURI();
    boolean _notEquals_3 = (!Objects.equal(_externalCssURI, null));
    if (_notEquals_3) {
      _or_1 = true;
    } else {
      String _externalCssURI_1 = report.getExternalCssURI();
      boolean _notEquals_4 = (!Objects.equal(_externalCssURI_1, null));
      _or_1 = _notEquals_4;
    }
    if (_or_1) {
      EList<JvmMember> _members_10 = type.getMembers();
      JvmTypeReference _typeRef_10 = this._typeReferenceBuilder.typeRef(String.class);
      final Procedure1<JvmOperation> _function_9 = new Procedure1<JvmOperation>() {
        public void apply(final JvmOperation it) {
          it.setVisibility(JvmVisibility.PROTECTED);
          EList<JvmAnnotationReference> _annotations = it.getAnnotations();
          JvmAnnotationReference _annotationRef = ReportDSLJvmModelInferrer.this._annotationTypesBuilder.annotationRef(Override.class);
          ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, _annotationRef);
          final Procedure1<ITreeAppendable> _function = new Procedure1<ITreeAppendable>() {
            public void apply(final ITreeAppendable it) {
              String _externalCssURI = report.getExternalCssURI();
              boolean _notEquals = (!Objects.equal(_externalCssURI, null));
              if (_notEquals) {
                StringConcatenation _builder = new StringConcatenation();
                _builder.append("return \"");
                String _externalCssURI_1 = report.getExternalCssURI();
                _builder.append(_externalCssURI_1, "");
                _builder.append("\";");
                it.append(_builder);
              } else {
                StringConcatenation _builder_1 = new StringConcatenation();
                _builder_1.append("return \"");
                String _externalCssURI_2 = pckg.getExternalCssURI();
                _builder_1.append(_externalCssURI_2, "");
                _builder_1.append("\";");
                it.append(_builder_1);
              }
            }
          };
          ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setBody(it, _function);
        }
      };
      JvmOperation _method_6 = this._jvmTypesBuilder.toMethod(report, "getExternalCssURI", _typeRef_10, _function_9);
      this._jvmTypesBuilder.<JvmOperation>operator_add(_members_10, _method_6);
    }
    EList<JvmMember> _members_11 = type.getMembers();
    JvmTypeReference _typeRef_11 = this._typeReferenceBuilder.typeRef(IDataMart.class);
    final Procedure1<JvmOperation> _function_10 = new Procedure1<JvmOperation>() {
      public void apply(final JvmOperation it) {
        DatamartDefinition _datamartRef = report.getDatamartRef();
        String _documentation = ReportDSLJvmModelInferrer.this._jvmTypesBuilder.getDocumentation(_datamartRef);
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setDocumentation(it, _documentation);
        it.setVisibility(JvmVisibility.PROTECTED);
        EList<JvmAnnotationReference> _annotations = it.getAnnotations();
        JvmAnnotationReference _annotationRef = ReportDSLJvmModelInferrer.this._annotationTypesBuilder.annotationRef(Override.class);
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, _annotationRef);
        final Procedure1<ITreeAppendable> _function = new Procedure1<ITreeAppendable>() {
          public void apply(final ITreeAppendable it) {
            StringConcatenation _builder = new StringConcatenation();
            _builder.append("return new ");
            DatamartDefinition _datamartRef = report.getDatamartRef();
            QualifiedName _fullyQualifiedName = ReportDSLJvmModelInferrer.this._iQualifiedNameProvider.getFullyQualifiedName(_datamartRef);
            _builder.append(_fullyQualifiedName, "");
            _builder.append("Datamart();");
            it.append(_builder);
          }
        };
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setBody(it, _function);
      }
    };
    JvmOperation _method_7 = this._jvmTypesBuilder.toMethod(report, "getDatamartInstance", _typeRef_11, _function_10);
    this._jvmTypesBuilder.<JvmOperation>operator_add(_members_11, _method_7);
    ReportDesign _design = report.getDesign();
    if ((_design instanceof ReportDesignFile)) {
      EList<JvmMember> _members_12 = type.getMembers();
      JvmTypeReference _typeRef_12 = this._typeReferenceBuilder.typeRef(String.class);
      final Procedure1<JvmOperation> _function_11 = new Procedure1<JvmOperation>() {
        public void apply(final JvmOperation it) {
          ReportDesign _design = report.getDesign();
          String _documentation = ReportDSLJvmModelInferrer.this._jvmTypesBuilder.getDocumentation(_design);
          ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setDocumentation(it, _documentation);
          it.setVisibility(JvmVisibility.PROTECTED);
          EList<JvmAnnotationReference> _annotations = it.getAnnotations();
          JvmAnnotationReference _annotationRef = ReportDSLJvmModelInferrer.this._annotationTypesBuilder.annotationRef(Override.class);
          ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, _annotationRef);
          final Procedure1<ITreeAppendable> _function = new Procedure1<ITreeAppendable>() {
            public void apply(final ITreeAppendable it) {
              StringConcatenation _builder = new StringConcatenation();
              _builder.append("return \"");
              ReportDesign _design = report.getDesign();
              String _name = ((ReportDesignFile) _design).getName();
              _builder.append(_name, "");
              _builder.append("\";");
              it.append(_builder);
            }
          };
          ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setBody(it, _function);
        }
      };
      JvmOperation _method_8 = this._jvmTypesBuilder.toMethod(report, "getReportDesignFilename", _typeRef_12, _function_11);
      this._jvmTypesBuilder.<JvmOperation>operator_add(_members_12, _method_8);
      EList<JvmMember> _members_13 = type.getMembers();
      JvmTypeReference _typeRef_13 = this._typeReferenceBuilder.typeRef(void.class);
      final Procedure1<JvmOperation> _function_12 = new Procedure1<JvmOperation>() {
        public void apply(final JvmOperation it) {
          it.setVisibility(JvmVisibility.PROTECTED);
          EList<JvmAnnotationReference> _annotations = it.getAnnotations();
          JvmAnnotationReference _annotationRef = ReportDSLJvmModelInferrer.this._annotationTypesBuilder.annotationRef(Override.class);
          ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, _annotationRef);
          final Procedure1<ITreeAppendable> _function = new Procedure1<ITreeAppendable>() {
            public void apply(final ITreeAppendable it) {
            }
          };
          ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setBody(it, _function);
        }
      };
      JvmOperation _method_9 = this._jvmTypesBuilder.toMethod(report, "buildReport", _typeRef_13, _function_12);
      this._jvmTypesBuilder.<JvmOperation>operator_add(_members_13, _method_9);
    } else {
      ReportDesign _design_1 = report.getDesign();
      if ((_design_1 instanceof ReportDesignTemplate)) {
        EList<JvmMember> _members_14 = type.getMembers();
        JvmTypeReference _typeRef_14 = this._typeReferenceBuilder.typeRef(String.class);
        final Procedure1<JvmOperation> _function_13 = new Procedure1<JvmOperation>() {
          public void apply(final JvmOperation it) {
            it.setVisibility(JvmVisibility.PROTECTED);
            EList<JvmAnnotationReference> _annotations = it.getAnnotations();
            JvmAnnotationReference _annotationRef = ReportDSLJvmModelInferrer.this._annotationTypesBuilder.annotationRef(Override.class);
            ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, _annotationRef);
            final Procedure1<ITreeAppendable> _function = new Procedure1<ITreeAppendable>() {
              public void apply(final ITreeAppendable it) {
                StringConcatenation _builder = new StringConcatenation();
                _builder.append("return null;");
                it.append(_builder);
              }
            };
            ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setBody(it, _function);
          }
        };
        JvmOperation _method_10 = this._jvmTypesBuilder.toMethod(report, "getReportDesignFilename", _typeRef_14, _function_13);
        this._jvmTypesBuilder.<JvmOperation>operator_add(_members_14, _method_10);
        EList<JvmMember> _members_15 = type.getMembers();
        JvmTypeReference _typeRef_15 = this._typeReferenceBuilder.typeRef(void.class);
        final Procedure1<JvmOperation> _function_14 = new Procedure1<JvmOperation>() {
          public void apply(final JvmOperation it) {
            ReportDesign _design = report.getDesign();
            String _documentation = ReportDSLJvmModelInferrer.this._jvmTypesBuilder.getDocumentation(_design);
            ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setDocumentation(it, _documentation);
            it.setVisibility(JvmVisibility.PROTECTED);
            EList<JvmAnnotationReference> _annotations = it.getAnnotations();
            JvmAnnotationReference _annotationRef = ReportDSLJvmModelInferrer.this._annotationTypesBuilder.annotationRef(Override.class);
            ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmAnnotationReference>operator_add(_annotations, _annotationRef);
            final Procedure1<ITreeAppendable> _function = new Procedure1<ITreeAppendable>() {
              public void apply(final ITreeAppendable it) {
              }
            };
            ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setBody(it, _function);
          }
        };
        JvmOperation _method_11 = this._jvmTypesBuilder.toMethod(report, "buildReport", _typeRef_15, _function_14);
        this._jvmTypesBuilder.<JvmOperation>operator_add(_members_15, _method_11);
      }
    }
    EList<JvmMember> _members_16 = type.getMembers();
    JvmTypeReference _typeRef_16 = this._typeReferenceBuilder.typeRef(Void.TYPE);
    final Procedure1<JvmOperation> _function_15 = new Procedure1<JvmOperation>() {
      public void apply(final JvmOperation it) {
        EList<JvmFormalParameter> _parameters = it.getParameters();
        JvmTypeReference _typeRef = ReportDSLJvmModelInferrer.this._typeReferenceBuilder.typeRef(Container.Filter.class);
        JvmFormalParameter _parameter = ReportDSLJvmModelInferrer.this._jvmTypesBuilder.toParameter(report, "filter", _typeRef);
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmFormalParameter>operator_add(_parameters, _parameter);
        final Procedure1<ITreeAppendable> _function = new Procedure1<ITreeAppendable>() {
          public void apply(final ITreeAppendable it) {
            StringConcatenation _builder = new StringConcatenation();
            _builder.append("// !!! no datamart, entity and DTO found for the report --> nothing can be done in here !!!");
            _builder.newLine();
            it.append(_builder);
          }
        };
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setBody(it, _function);
      }
    };
    JvmOperation _method_12 = this._jvmTypesBuilder.toMethod(report, "applyBeanFilter", _typeRef_16, _function_15);
    this._jvmTypesBuilder.<JvmOperation>operator_add(_members_16, _method_12);
    EList<JvmMember> _members_17 = type.getMembers();
    JvmTypeReference _typeRef_17 = this._typeReferenceBuilder.typeRef(Void.TYPE);
    final Procedure1<JvmOperation> _function_16 = new Procedure1<JvmOperation>() {
      public void apply(final JvmOperation it) {
        EList<JvmFormalParameter> _parameters = it.getParameters();
        JvmTypeReference _typeRef = ReportDSLJvmModelInferrer.this._typeReferenceBuilder.typeRef(Object.class);
        JvmFormalParameter _parameter = ReportDSLJvmModelInferrer.this._jvmTypesBuilder.toParameter(report, "dto", _typeRef);
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.<JvmFormalParameter>operator_add(_parameters, _parameter);
        final Procedure1<ITreeAppendable> _function = new Procedure1<ITreeAppendable>() {
          public void apply(final ITreeAppendable it) {
            StringConcatenation _builder = new StringConcatenation();
            _builder.append("// !!! no datamart, entity and DTO found for the report --> nothing can be done in here !!!");
            _builder.newLine();
            it.append(_builder);
          }
        };
        ReportDSLJvmModelInferrer.this._jvmTypesBuilder.setBody(it, _function);
      }
    };
    JvmOperation _method_13 = this._jvmTypesBuilder.toMethod(report, "applyBeanDto", _typeRef_17, _function_16);
    this._jvmTypesBuilder.<JvmOperation>operator_add(_members_17, _method_13);
  }
  
  /**
   * get a set of all entities used in the given report
   */
  public Set<LEntity> findRequestedEntities(final Report report) {
    HashSet<LEntity> entities = new HashSet<LEntity>();
    DatamartDefinition _datamartRef = report.getDatamartRef();
    Set<LEntity> _findAllEntities = this._datamartDSLJvmModelInferrer.findAllEntities(_datamartRef);
    entities.addAll(_findAllEntities);
    return entities;
  }
  
  public CharSequence createView(final Report report) {
    StringConcatenation _builder = new StringConcatenation();
    _builder.append("fWorkset\t= new ReportGeneratorWorkSet();");
    _builder.newLine();
    {
      ActionToolbar _toolbar = report.getToolbar();
      boolean _notEquals = (!Objects.equal(_toolbar, null));
      if (_notEquals) {
        _builder.append("toolbarClass = new ");
        ActionToolbar _toolbar_1 = report.getToolbar();
        String _name = _toolbar_1.getName();
        String _string = _name.toString();
        String _firstUpper = StringExtensions.toFirstUpper(_string);
        _builder.append(_firstUpper, "");
        _builder.append("Action(UUID.randomUUID().toString());");
        _builder.newLineIfNotEmpty();
        _builder.append("toolbarClass.createToolbar(getContext(), renderingEngine, themeResourceService);");
        _builder.newLine();
        _builder.append("addPDFDownload(toolbarClass);");
        _builder.newLine();
      }
    }
    _builder.append("createFilter();");
    _builder.newLine();
    return _builder;
  }
  
  public void infer(final EObject pckg, final IJvmDeclaredTypeAcceptor acceptor, final boolean isPreIndexingPhase) {
    if (pckg instanceof ReportPackage) {
      _infer((ReportPackage)pckg, acceptor, isPreIndexingPhase);
      return;
    } else if (pckg != null) {
      _infer(pckg, acceptor, isPreIndexingPhase);
      return;
    } else {
      throw new IllegalArgumentException("Unhandled parameter types: " +
        Arrays.<Object>asList(pckg, acceptor, isPreIndexingPhase).toString());
    }
  }
}
