protected void generateSetObjectKeyMethod(SourcePrinter srcWriter) {
    srcWriter.println(
        "protected void setObjectKey("
            + getTargetObjectClassName()
            + " object, "
            + getKeyTypeName()
            + " key){");

    if (hasCompositeKey()) {
      for (int i = 0; i < keyPath.length; i++) {
        String k = keyPath[i];
        JType jType = JClassUtils.getTypeForProperty(k, targetObjectType);
        String setterMethod = JClassUtils.getSetterMethod(k, targetObjectType, jType);
        srcWriter.println(
            "object."
                + setterMethod
                + "((key==null?null:("
                + jType.getParameterizedQualifiedSourceName()
                + ")key["
                + i
                + "]));");
      }
    } else {
      String k = keyPath[0];
      JType jType = JClassUtils.getTypeForProperty(k, targetObjectType);
      String setterMethod = JClassUtils.getSetterMethod(k, targetObjectType, jType);
      srcWriter.println("object." + setterMethod + "(key);");
    }
    srcWriter.println("}");
    srcWriter.println();
  }
 @Override
 protected void generateProxyFields(SourcePrinter srcWriter) throws CruxGeneratorException {
   srcWriter.println(
       "private "
           + controllerClass.getQualifiedSourceName()
           + ControllerProxyCreator.CONTROLLER_PROXY_SUFFIX
           + " _controller;");
   srcWriter.println(
       "private "
           + DeviceAdaptiveViewContainer.class.getCanonicalName()
           + " viewContainer = new "
           + DeviceAdaptiveViewContainer.class.getCanonicalName()
           + "();");
   for (String messageClass : viewFactoryCreator.getDeclaredMessages().keySet()) {
     srcWriter.println(
         "private "
             + messageClass
             + " "
             + viewFactoryCreator.getDeclaredMessages().get(messageClass)
             + " = GWT.create("
             + messageClass
             + ".class);");
   }
   srcWriter.println(
       "private static "
           + Logger.class.getCanonicalName()
           + " "
           + viewFactoryCreator.getLoggerVariable()
           + " = "
           + Logger.class.getCanonicalName()
           + ".getLogger("
           + getProxySimpleName()
           + ".class.getName());");
   srcWriter.println("private static int _idGen = 0;");
 }
 protected void generateOpenCursorMethod(SourcePrinter srcWriter) {
   srcWriter.println(
       "public void openCursor(KeyRange<"
           + getKeyTypeName()
           + "> keyRange, CursorDirection direction, final DatabaseCursorCallback<"
           + getKeyTypeName()
           + ", "
           + getTargetObjectClassName()
           + "> callback){");
   String cursorClassName =
       new SQLCursorProxyCreator(
               context,
               targetObjectType,
               objectStoreName,
               autoIncrement,
               getIndexColumns(),
               keyPath,
               keyPath,
               "ObjectStore_" + getTargetObjectClassName())
           .create();
   srcWriter.println(
       "new "
           + cursorClassName
           + "("
           + dbVariable
           + ", (WSQLKeyRange<"
           + getKeyTypeName()
           + ">)keyRange, direction, transaction).start(callback);");
   srcWriter.println("}");
   srcWriter.println();
 }
  @Override
  protected void generateProxyContructor(SourcePrinter srcWriter) throws CruxGeneratorException {
    srcWriter.println(
        "public "
            + getProxySimpleName()
            + "(WSQLAbstractDatabase db, String name, WSQLTransaction transaction){");
    srcWriter.println("super(db, name, transaction);");

    srcWriter.println("}");
  }
  protected void generateObjectStoresCreation(SourcePrinter srcWriter, String callback) {
    srcWriter.println("deleteDBTables(tx, new DatabaseCallback(){");
    srcWriter.println("public void onSuccess(){");

    ObjectStoreDef[] objectStores = databaseMetadata.objectStores();
    Set<String> addedObjectStores = new HashSet<String>();

    String objectStoreVar = "objectStore";
    String indexNamesVar = "indexNames";
    srcWriter.println("WSQLAbstractObjectStore " + objectStoreVar + ";");
    srcWriter.println("Array<String> " + indexNamesVar + ";");
    for (ObjectStoreDef objectStoreMetadata : objectStores) {
      JClassType objectStoreTarget = getObjectStoreTarget(objectStoreMetadata);
      String objectStoreName = getObjectStoreName(objectStoreMetadata, objectStoreTarget);
      if (addedObjectStores.contains(objectStoreName)) {
        throw new CruxGeneratorException(
            "Duplicated objectstore declared on Datasource [" + databaseMetadata.name() + "]");
      }
      addedObjectStores.add(objectStoreName);

      srcWriter.println(
          objectStoreVar + " = getObjectStore(" + EscapeUtils.quote(objectStoreName) + ", null);");

      srcWriter.println(objectStoreVar + ".createTable(tx, null);");
    }

    srcWriter.println("createFileStore(tx);");

    srcWriter.println("}");
    srcWriter.println("}, getDeleteErrorHandler(callback), false);");
  }
  protected void generateUpdateDatabaseStructureMethod(SourcePrinter srcWriter) {
    srcWriter.println(
        "protected void updateDatabaseStructure(final "
            + SQLTransaction.class.getCanonicalName()
            + " tx, final DatabaseCallback callback){");

    generateObjectStoresCreation(srcWriter, "callback");

    srcWriter.println("}");
    srcWriter.println();
  }
 /**
  * @param srcWriter
  * @param type
  * @param parentVariable
  * @param added
  * @param iocContainerVariable
  * @param configurations
  */
 private static void injectFields(
     SourcePrinter srcWriter,
     JClassType type,
     String parentVariable,
     Set<String> added,
     String iocContainerVariable,
     Map<String, IocConfig<?>> configurations) {
   for (JField field : type.getFields()) {
     String fieldName = field.getName();
     if (!added.contains(fieldName)) {
       added.add(fieldName);
       JType fieldType = field.getType();
       if ((fieldType.isPrimitive() == null)) {
         String injectionExpression =
             getFieldInjectionExpression(field, iocContainerVariable, configurations);
         if (injectionExpression != null) {
           if (JClassUtils.isPropertyVisibleToWrite(type, field, false)) {
             if (JClassUtils.hasSetMethod(field, type)) {
               String setterMethodName =
                   "set" + Character.toUpperCase(fieldName.charAt(0)) + fieldName.substring(1);
               JMethod method = type.findMethod(setterMethodName, new JType[] {field.getType()});
               if (method.getAnnotation(Inject.class)
                   == null) // Annotated methods are handled apart
               {
                 srcWriter.println(
                     fieldType.getQualifiedSourceName()
                         + " field_"
                         + fieldName
                         + " = "
                         + injectionExpression
                         + ";");
                 srcWriter.println(
                     parentVariable + "." + setterMethodName + "(field_" + fieldName + ");");
               }
             } else {
               srcWriter.println(
                   parentVariable + "." + fieldName + " = " + injectionExpression + ";");
             }
           } else {
             throw new IoCException(
                 "IoC Error Field ["
                     + field.getName()
                     + "] from class ["
                     + type.getQualifiedSourceName()
                     + "] is not a writeable property.");
           }
         }
       }
     }
   }
 }
 /**
  * @param srcWriter
  * @param type
  * @param parentVariable
  * @param added
  * @param iocContainerVariable
  * @param configurations
  */
 private static void injectMethods(
     SourcePrinter srcWriter,
     JClassType type,
     String parentVariable,
     Set<String> added,
     String iocContainerVariable,
     Map<String, IocConfig<?>> configurations) {
   for (JMethod method : type.getMethods()) {
     Inject inject = method.getAnnotation(Inject.class);
     if (inject != null && !method.isStatic()) {
       String methodName = method.getName();
       if (!added.contains(methodName + "()")) {
         added.add(methodName + "()");
         JParameter[] parameters = method.getParameters();
         List<String> params = new ArrayList<String>();
         for (JParameter parameter : parameters) {
           JType parameterType = parameter.getType();
           if ((parameterType.isPrimitive() != null)) {
             throw new IoCException(
                 "IoC Error Method ["
                     + methodName
                     + "] from class ["
                     + type.getQualifiedSourceName()
                     + "] declares an invalid parameter. Primitive types are not allowed here");
           }
           String variableName = "parameter_" + methodName + "_" + parameter.getName();
           params.add(variableName);
           String injectionExpression =
               getParameterInjectionExpression(parameter, iocContainerVariable, configurations);
           srcWriter.println(
               parameterType.getQualifiedSourceName()
                   + " "
                   + variableName
                   + " = "
                   + injectionExpression
                   + ";");
         }
         srcWriter.print(parentVariable + "." + methodName + "(");
         boolean first = true;
         for (String param : params) {
           if (!first) {
             srcWriter.print(", ");
           }
           first = false;
           srcWriter.print(param);
         }
         srcWriter.println(");");
       }
     }
   }
 }
 /**
  * @param srcWriter
  * @param className
  */
 private void generateFieldsPopulationCallback(SourcePrinter srcWriter, JClassType type) {
   String className = type.getQualifiedSourceName();
   srcWriter.println("new IocScope.CreateCallback<" + className + ">(){");
   srcWriter.println("public void onCreate(" + className + " newObject){");
   injectFieldsAndMethods(
       srcWriter,
       type,
       "newObject",
       new HashSet<String>(),
       getProxySimpleName() + ".this",
       configurations);
   srcWriter.println("}");
   srcWriter.println("}");
 }
 /** @param srcWriter */
 protected void createController(SourcePrinter srcWriter, String viewVariable) {
   String genClass = new ControllerProxyCreator(logger, context, controllerClass).create();
   srcWriter.println("this._controller = new " + genClass + "(" + viewVariable + ");");
   srcWriter.println(
       "(("
           + DeviceAdaptiveController.class.getCanonicalName()
           + ")this._controller).setBoundWidget(this);");
   IocContainerRebind.injectFieldsAndMethods(
       srcWriter,
       controllerClass,
       "this._controller",
       viewVariable + ".getTypedIocContainer()",
       view,
       device);
 }
  protected void generateGetIndexNamesMethod(SourcePrinter srcWriter) {
    srcWriter.println("public String[] getIndexNames(){");
    srcWriter.print("return new String[]{");

    boolean first = true;
    for (IndexData index : indexes) {
      if (!first) {
        srcWriter.print(",");
      }
      first = false;
      srcWriter.print(EscapeUtils.quote(index.indexName));
    }

    srcWriter.println("};");
    srcWriter.println("}");
    srcWriter.println();
  }
  @Override
  protected void generateWrapperMethod(JMethod method, SourcePrinter srcWriter) {
    if (mustDelegateToController(method)) {
      JType returnType = method.getReturnType().getErasedType();

      srcWriter.println(method.getReadableDeclaration(false, false, false, false, true) + "{");
      if (returnType != JPrimitiveType.VOID) {
        srcWriter.print("return ");
      }
      srcWriter.print("this._controller." + method.getName() + "(");
      boolean needsComma = false;
      for (JParameter parameter : method.getParameters()) {
        if (needsComma) {
          srcWriter.print(", ");
        }
        needsComma = true;
        srcWriter.print(parameter.getName());
      }
      srcWriter.println(");");

      srcWriter.println("}");
    }
  }
  protected void generateGetObjectStoreMethod(SourcePrinter srcWriter) {
    srcWriter.println(
        "protected <K, V> WSQLAbstractObjectStore<K, V> getObjectStore(String storeName, WSQLTransaction transaction){");

    boolean first = true;
    ObjectStoreDef[] objectStores = databaseMetadata.objectStores();

    for (ObjectStoreDef objectStoreMetadata : objectStores) {
      JClassType objectStoreTarget = getObjectStoreTarget(objectStoreMetadata);
      String objectStoreName = getObjectStoreName(objectStoreMetadata, objectStoreTarget);
      if (!first) {
        srcWriter.print("else ");
      }
      first = false;
      Set<IndexData> indexes =
          getIndexes(objectStoreMetadata.indexes(), objectStoreTarget, objectStoreName);
      srcWriter.println(
          "if (StringUtils.unsafeEquals(storeName, " + EscapeUtils.quote(objectStoreName) + ")){");
      String[] keyPath = getKeyPath(objectStoreMetadata, objectStoreTarget);
      String objectStore =
          new SQLObjectStoreProxyCreator(
                  context,
                  logger,
                  objectStoreTarget,
                  objectStoreName,
                  keyPath,
                  isAutoIncrement(objectStoreTarget),
                  indexes)
              .create();
      srcWriter.println(
          "return (WSQLAbstractObjectStore<K, V>) new "
              + objectStore
              + "(this, storeName, transaction);");
      srcWriter.println("}");
    }

    srcWriter.println("return null;");
    srcWriter.println("}");
    srcWriter.println();
  }
  protected void generateGetIndexMethod(SourcePrinter srcWriter) {
    srcWriter.println(
        "public <I> Index<"
            + getKeyTypeName()
            + ", I, "
            + getTargetObjectClassName()
            + "> getIndex(String name){");
    for (IndexData index : indexes) {
      srcWriter.println(
          "if (StringUtils.unsafeEquals(name, " + EscapeUtils.quote(index.indexName) + ")){");
      String indexClassName =
          new SQLIndexProxyCreator(
                  context,
                  targetObjectType,
                  objectStoreName,
                  autoIncrement,
                  index.keyPath,
                  index.indexName,
                  keyPath,
                  getIndexColumns(),
                  index.unique)
              .create();
      srcWriter.println(
          "return (Index<"
              + getKeyTypeName()
              + ", I, "
              + getTargetObjectClassName()
              + ">) new "
              + indexClassName
              + "("
              + dbVariable
              + ", transaction);");
      srcWriter.println("}");
    }

    srcWriter.println("return null;");
    srcWriter.println("}");
    srcWriter.println();
  }
  @Override
  protected void generateProxyContructor(SourcePrinter srcWriter) throws CruxGeneratorException {
    srcWriter.println("public " + getProxySimpleName() + "(){");

    String viewVariable = ViewFactoryCreator.createVariableName("view");
    srcWriter.println(
        viewClassName
            + " "
            + viewVariable
            + " = new "
            + viewClassName
            + "("
            + EscapeUtils.quote(baseIntf.getSimpleSourceName())
            + "+(_idGen++));");
    createController(srcWriter, viewVariable);
    srcWriter.println(viewVariable + ".setController(this._controller);");

    srcWriter.println("initWidget(viewContainer.asWidget());");
    srcWriter.println("viewContainer.add(" + viewVariable + ", true, null);");
    srcWriter.println(
        "((" + DeviceAdaptiveController.class.getCanonicalName() + ")this._controller).init();");
    srcWriter.println("}");
  }
 protected void generateGetObjectStoreNameMethod(SourcePrinter srcWriter) {
   srcWriter.println("public String getObjectStoreName(){");
   srcWriter.println("return " + EscapeUtils.quote(objectStoreName) + ";");
   srcWriter.println("}");
   srcWriter.println();
 }
  protected void generateGetCreateTableSQLMethod(SourcePrinter srcWriter) {
    srcWriter.println("protected String getCreateTableSQL(){");
    srcWriter.print(
        "String sql = \"CREATE TABLE  \\\"\"+name+\"\\\" (\\\"value\\\" BLOB"); // TODO alterar nome
    // da coluna pra
    // evitar conflito
    // com indices
    Set<String> addedColumns = new HashSet<String>();

    for (String col : keyPath) {
      if (!addedColumns.contains(col)) {
        addedColumns.add(col);
        JType propertyType = getPropertyType(col);
        srcWriter.print(
            ",\\\"" + col + "\\\" " + getSQLTypeForProperty(propertyType) + " PRIMARY KEY");
        if (autoIncrement) {
          if (!getKeyTypeName().equals("Integer")) {
            throw new CruxGeneratorException(
                "Auto increment keys can only be used on integer keys");
          }
          srcWriter.print(" AUTOINCREMENT");
        }
      } else {
        throw new CruxGeneratorException(
            "Invalid KeyPath for object store ["
                + objectStoreName
                + "]. Duplicated column on keyPath ["
                + col
                + "]");
      }
    }

    StringBuilder uniqueConstraints = new StringBuilder();
    for (IndexData indexData : indexes) {
      if (indexData.unique) {
        uniqueConstraints.append(", UNIQUE(");
      }
      boolean firstCostraint = true;
      for (String col : indexData.keyPath) {
        if (!addedColumns.contains(col)) {
          addedColumns.add(col);
          JType propertyType = getPropertyType(col);
          srcWriter.print(",\\\"" + col + "\\\" " + getSQLTypeForProperty(propertyType));
        }
        if (indexData.unique) {
          if (!firstCostraint) {
            uniqueConstraints.append(",");
          }
          uniqueConstraints.append("\\\"" + col + "\\\"");
          firstCostraint = false;
        }
      }
      if (indexData.unique) {
        uniqueConstraints.append(") ON CONFLICT REPLACE");
      }
    }

    srcWriter.print(uniqueConstraints.toString());
    srcWriter.println(")\";");
    srcWriter.println("return sql;");
    srcWriter.println("}");
    srcWriter.println();
  }
 protected void generateIsAutoIncrementMethod(SourcePrinter srcWriter) {
   srcWriter.println("public boolean isAutoIncrement(){");
   srcWriter.println("return " + autoIncrement + ";");
   srcWriter.println("}");
   srcWriter.println();
 }
  /**
   * @param srcWriter
   * @param className
   */
  private void generateContainerInstatiationMethod(SourcePrinter srcWriter, String className) {
    try {
      srcWriter.println(
          "public  "
              + className
              + " get"
              + className.replace('.', '_')
              + "("
              + Scope.class.getCanonicalName()
              + " scope, String subscope){");
      JClassType type =
          JClassUtils.getType(context.getGeneratorContext().getTypeOracle(), className);

      IocConfigImpl<?> iocConfig = (IocConfigImpl<?>) configurations.get(className);
      Class<?> providerClass = iocConfig.getProviderClass();
      if (providerClass != null) {
        srcWriter.println(
            className
                + " result = _getScope(scope).getValue(GWT.create("
                + providerClass.getCanonicalName()
                + ".class), "
                + EscapeUtils.quote(className)
                + ", subscope, ");
        generateFieldsPopulationCallback(srcWriter, type);
        srcWriter.println(");");
      } else if (iocConfig.getToClass() != null) {
        srcWriter.println(
            className
                + " result = _getScope(scope).getValue(new "
                + IocProvider.class.getCanonicalName()
                + "<"
                + className
                + ">(){");
        srcWriter.println("public " + className + " get(){");
        srcWriter.println(
            "return GWT.create(" + iocConfig.getToClass().getCanonicalName() + ".class);");
        srcWriter.println("}");
        srcWriter.println("}, " + EscapeUtils.quote(className) + ", subscope, ");
        generateFieldsPopulationCallback(srcWriter, type);
        srcWriter.println(");");
      } else {
        srcWriter.println(
            className
                + " result = _getScope(scope).getValue(new "
                + IocProvider.class.getCanonicalName()
                + "<"
                + className
                + ">(){");
        srcWriter.println("public " + className + " get(){");
        String instantiationClass = getInstantiationClass(className);
        JClassType instantiationType =
            context.getGeneratorContext().getTypeOracle().findType(instantiationClass);
        if (instantiationType == null) {
          throw new CruxGeneratorException("Can not found type: " + instantiationClass);
        }
        if (instantiationType.isAssignableTo(remoteServiceType)
            && ConfigurationFactory.getConfigurations()
                .sendCruxViewNameOnClientRequests()
                .equals("true")) {
          srcWriter.println(className + " ret = GWT.create(" + instantiationClass + ".class);");
          srcWriter.println(
              "(("
                  + ServiceDefTarget.class.getCanonicalName()
                  + ")ret).setRpcRequestBuilder(new "
                  + CruxRpcRequestBuilder.class.getCanonicalName()
                  + "(getBoundCruxViewId()));");
          srcWriter.println("return ret;");
        } else {
          srcWriter.println("return GWT.create(" + instantiationClass + ".class);");
        }
        srcWriter.println("}");
        srcWriter.println("}, " + EscapeUtils.quote(className) + ", subscope, ");
        generateFieldsPopulationCallback(srcWriter, type);
        srcWriter.println(");");
      }

      if (type.isAssignableTo(viewBindableType)) {
        srcWriter.println(
            "if (scope != "
                + Scope.class.getCanonicalName()
                + "."
                + Scope.SINGLETON.name()
                + " && result.getBoundCruxViewId() == null){");
        srcWriter.println("result.bindCruxView(this.getBoundCruxViewId());");
        srcWriter.println("}");
      }
      srcWriter.println("return result;");
      srcWriter.println("}");
    } catch (NotFoundException e) {
      throw new IoCException("IoC Error Class [" + className + "] not found.", e);
    }
  }
 @Override
 protected void generateProxyContructor(SourcePrinter srcWriter) throws CruxGeneratorException {
   srcWriter.println("public " + getProxySimpleName() + "(View view){");
   srcWriter.println("super(view);");
   srcWriter.println("}");
 }
  protected void generateDeriveKeyMethod(SourcePrinter srcWriter) {
    srcWriter.println(
        "protected " + getKeyTypeName() + " getKey(" + getTargetObjectClassName() + " object){");

    srcWriter.print("boolean hasKey = ");
    boolean first = true;
    for (String k : keyPath) {
      if (!first) {
        srcWriter.print(" || ");
      }
      String getterMethod = JClassUtils.getGetterMethod(k, targetObjectType);
      srcWriter.print("object." + getterMethod + "() != null");
      first = false;
    }
    srcWriter.println(";");

    srcWriter.println("if (hasKey){");
    srcWriter.print(getKeyTypeName() + " key");
    if (hasCompositeKey()) {
      srcWriter.println(" = new Object[" + keyPath.length + "];");
      int i = 0;
      for (String k : keyPath) {
        String getterMethod = JClassUtils.getGetterMethod(k, targetObjectType);
        srcWriter.print("key [" + i + "] = object." + getterMethod + "();");
        i++;
      }
    } else {
      srcWriter.println(
          " = object." + JClassUtils.getGetterMethod(keyPath[0], targetObjectType) + "();");
    }
    srcWriter.println("return key;");

    if (autoIncrement) {
      if (!getKeyTypeName().equals("Integer")) {
        throw new CruxGeneratorException("Auto increment keys can only be used on integer keys");
      }
      srcWriter.println("} else {");
      srcWriter.println("return null;");
    } else {
      srcWriter.println("} else {");
      srcWriter.println("reportError(db.messages.objectStoreDeriveKeyError(name));");
      srcWriter.println("return null;");
    }
    srcWriter.println("}");
    srcWriter.println("}");
    srcWriter.println();
  }