public ClusterSchema loadClusterSchema(ObjectId id_cluster_schema, List<SlaveServer> slaveServers)
      throws KettleException {
    ClusterSchema clusterSchema = new ClusterSchema();
    RowMetaAndData row = getClusterSchema(id_cluster_schema);

    clusterSchema.setObjectId(id_cluster_schema);
    clusterSchema.setName(row.getString(KettleDatabaseRepository.FIELD_CLUSTER_NAME, null));
    clusterSchema.setBasePort(
        row.getString(KettleDatabaseRepository.FIELD_CLUSTER_BASE_PORT, null));
    clusterSchema.setSocketsBufferSize(
        row.getString(KettleDatabaseRepository.FIELD_CLUSTER_SOCKETS_BUFFER_SIZE, null));
    clusterSchema.setSocketsFlushInterval(
        row.getString(KettleDatabaseRepository.FIELD_CLUSTER_SOCKETS_FLUSH_INTERVAL, null));
    clusterSchema.setSocketsCompressed(
        row.getBoolean(KettleDatabaseRepository.FIELD_CLUSTER_SOCKETS_COMPRESSED, true));
    clusterSchema.setDynamic(row.getBoolean(KettleDatabaseRepository.FIELD_CLUSTER_DYNAMIC, true));

    ObjectId[] pids = repository.getClusterSlaveIDs(id_cluster_schema);
    for (int i = 0; i < pids.length; i++) {
      SlaveServer slaveServer = repository.loadSlaveServer(pids[i], null); // Load last version
      SlaveServer reference = SlaveServer.findSlaveServer(slaveServers, slaveServer.getName());
      if (reference != null) {
        clusterSchema.getSlaveServers().add(reference);
      } else {
        clusterSchema.getSlaveServers().add(slaveServer);
      }
    }

    return clusterSchema;
  }
  protected void replaceSharedObjects(TransMeta transMeta) throws KettleException {
    replaceSharedObjects((AbstractMeta) transMeta);
    for (ClusterSchema clusterSchema : getSharedObjects(ClusterSchema.class)) {
      int index = transMeta.getClusterSchemas().indexOf(clusterSchema);
      if (index < 0) {
        transMeta.getClusterSchemas().add(clusterSchema);
      } else {
        ClusterSchema imported = transMeta.getClusterSchemas().get(index);
        // Preserve the object id so we can update without having to look up the id
        imported.setObjectId(clusterSchema.getObjectId());
        if (equals(clusterSchema, imported)
            || !getPromptResult(
                BaseMessages.getString(
                    PKG,
                    "RepositoryImporter.Dialog.ClusterSchemaExistsOverWrite.Message",
                    imported.getName()),
                BaseMessages.getString(
                    PKG,
                    "RepositoryImporter.Dialog.ConnectionExistsOverWrite.DontShowAnyMoreMessage"),
                IMPORT_ASK_ABOUT_REPLACE_CS)) {
          imported.replaceMeta(clusterSchema);
          // We didn't actually change anything
          imported.clearChanged();
        } else {
          imported.setChanged();
        }
      }
    }

    for (PartitionSchema partitionSchema : getSharedObjects(PartitionSchema.class)) {
      int index = transMeta.getPartitionSchemas().indexOf(partitionSchema);
      if (index < 0) {
        transMeta.getPartitionSchemas().add(partitionSchema);
      } else {
        PartitionSchema imported = transMeta.getPartitionSchemas().get(index);
        // Preserve the object id so we can update without having to look up the id
        imported.setObjectId(partitionSchema.getObjectId());
        if (equals(partitionSchema, imported)
            || !getPromptResult(
                BaseMessages.getString(
                    PKG,
                    "RepositoryImporter.Dialog.PartitionSchemaExistsOverWrite.Message",
                    imported.getName()),
                BaseMessages.getString(
                    PKG,
                    "RepositoryImporter.Dialog.ConnectionExistsOverWrite.DontShowAnyMoreMessage"),
                IMPORT_ASK_ABOUT_REPLACE_PS)) {
          imported.replaceMeta(partitionSchema);
          // We didn't actually change anything
          imported.clearChanged();
        } else {
          imported.setChanged();
        }
      }
    }
  }
  public void saveClusterSchema(
      ClusterSchema clusterSchema,
      String versionComment,
      ObjectId id_transformation,
      boolean isUsedByTransformation,
      boolean overwrite)
      throws KettleException {
    ObjectId existingClusterSchemaId = getClusterID(clusterSchema.getName());
    if (existingClusterSchemaId != null) {
      clusterSchema.setObjectId(existingClusterSchemaId);
    }

    if (clusterSchema.getObjectId() == null) {
      // New Slave Server
      clusterSchema.setObjectId(insertCluster(clusterSchema));
    } else {

      // If we received a clusterSchemaId and it is different from the cluster schema we are working
      // with...
      if (existingClusterSchemaId != null
          && !clusterSchema.getObjectId().equals(existingClusterSchemaId)) {
        // A cluster with this name already exists
        if (overwrite) {
          // Proceed with save, removing the original version from the repository first
          repository.deleteClusterSchema(existingClusterSchemaId);
          updateCluster(clusterSchema);
        } else {
          throw new KettleObjectExistsException(
              "Failed to save object to repository. Object ["
                  + clusterSchema.getName()
                  + "] already exists.");
        }
      } else {
        // There are no naming collisions (either it is the same object or the name is unique)
        updateCluster(clusterSchema);
      }
    }

    repository.delClusterSlaves(clusterSchema.getObjectId());

    // Also save the used slave server references.
    for (int i = 0; i < clusterSchema.getSlaveServers().size(); i++) {
      SlaveServer slaveServer = clusterSchema.getSlaveServers().get(i);
      if (slaveServer.getObjectId() == null) // oops, not yet saved!
      {
        repository.save(
            slaveServer,
            versionComment,
            null,
            id_transformation,
            isUsedByTransformation,
            overwrite);
      }
      repository.insertClusterSlave(clusterSchema, slaveServer);
    }

    // Save a link to the transformation to keep track of the use of this cluster schema
    // Only save it if it's really used by the transformation
    if (isUsedByTransformation) {
      repository.insertTransformationCluster(id_transformation, clusterSchema.getObjectId());
    }
  }