Package ch.agent.crnickl.jdbc

Source Code of ch.agent.crnickl.jdbc.WriteMethodsForValueType

/*
*   Copyright 2012-2013 Hauser Olsson GmbH
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package ch.agent.crnickl.jdbc;

import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import ch.agent.crnickl.T2DBException;
import ch.agent.crnickl.T2DBMsg;
import ch.agent.crnickl.T2DBMsg.E;
import ch.agent.crnickl.api.Surrogate;
import ch.agent.crnickl.api.ValueType;
import ch.agent.crnickl.impl.Permission;
import ch.agent.crnickl.impl.SchemaUpdatePolicy;
import ch.agent.crnickl.impl.ValueTypeImpl;

/**
* A stateless object with methods providing write access to value types.
* @author Jean-Paul Vetterli
*/
public class WriteMethodsForValueType extends JDBCDatabaseMethods {

  public WriteMethodsForValueType() {
  }
 
  private PreparedStatement create_valuetype;
  private static final String CREATE_VALUETYPE =
    "insert into " + DB.VALUE_TYPE + " (label, restricted, scanner) " +
    "values(?, ?, ?)";
  /**
   * Create a value type in the database.
   * Throw an exception if the operation cannot be done.
   *
   * @param vt a value type
   * @throws T2DBException
   */
  public <T>void createValueType(ValueType<T> vt) throws T2DBException {
    Surrogate surrogate = null;
    Throwable cause = null;
    try {
      check(Permission.CREATE, vt);
      create_valuetype = open(CREATE_VALUETYPE, vt, create_valuetype);
      create_valuetype.setString(1, vt.getName());
      create_valuetype.setBoolean(2, vt.isRestricted());
      create_valuetype.setString(3, ((ValueTypeImpl<T>)vt).getExternalRepresentation());
      surrogate = makeSurrogate(vt, executeAndGetNewId(create_valuetype));
      vt.getSurrogate().upgrade(surrogate);
      updateValues(null, vt, null);
    } catch (Exception e) {
      cause = e;
    } finally {
      create_valuetype = close(create_valuetype);
    }
    if (surrogate == null || cause != null)
      throw T2DBMsg.exception(cause, E.E10114, vt.getName());
  }

  private PreparedStatement delete_valuetype;
  private static final String DELETE_VALUETYPE =
    "delete from " + DB.VALUE_TYPE + " where id = ?";
  /**
   * Delete a value type from the database.
   * Throw an exception if the operation cannot be done.
   *
   * @param vt a value type
   * @param policy a schema udpdating policy
   * @throws T2DBException
   */
  public <T>void deleteValueType(ValueType<T> vt, SchemaUpdatePolicy policy) throws T2DBException {
    boolean done = false;
    Throwable cause = null;
    try {
      check(Permission.MODIFY, vt);
      policy.willDelete(vt);
      if (vt.isRestricted())
        deleteValues(vt);
      delete_valuetype = open(DELETE_VALUETYPE, vt, delete_valuetype);
      delete_valuetype.setInt(1, getId(vt));
      delete_valuetype.execute();
      done = delete_valuetype.getUpdateCount() > 0;
    } catch (Exception e) {
      cause = e;
    } finally {
      delete_valuetype = close(delete_valuetype);
    }
    if (!done || cause != null)
      throw T2DBMsg.exception(cause, E.E10145, vt.getName());
  }
 
  private PreparedStatement update_valuetype;
  private static final String UPDATE_VALUETYPE =
    "update " + DB.VALUE_TYPE + " set label = ? where id = ?";
  /**
   * Update a value type in the database.
   * Throw an exception if the operation cannot be done.
   *
   * @param vt a value type
   * @param policy a schema udpdating policy
   * @throws T2DBException
   */
  public <T>void updateValueType(ValueType<T> vt, SchemaUpdatePolicy policy) throws T2DBException {
    boolean done = false;
    Throwable cause = null;
    try {
      check(Permission.MODIFY, vt);
      Surrogate s = vt.getSurrogate();
      ValueType<T> original =
          ((JDBCDatabase) s.getDatabase()).getReadMethodsForValueType().getValueType(s);
      if (!original.getName().equals(vt.getName())) {
        update_valuetype = open(UPDATE_VALUETYPE, vt, update_valuetype);
        update_valuetype.setString(1, vt.getName());
        update_valuetype.setInt(2, getId(vt));
        update_valuetype.execute();
        done = update_valuetype.getUpdateCount() > 0;
      }
      done |= updateValues(original, vt, policy);
    } catch (Exception e) {
      cause = e;
    } finally {
      update_valuetype = close(update_valuetype);
    }
    if (!done || cause != null)
      throw T2DBMsg.exception(cause, E.E10146, vt.getName());
  }
 
  private <T>boolean updateValues(ValueType<T> original, ValueType<T> vt, SchemaUpdatePolicy policy) throws T2DBException {
    boolean done = false;
    if (vt.isRestricted()) {
      Map<T, String> added;
      Set<T> deleted;
      Map<T, String> edited;
      Map<T, String> updates = vt.getValueDescriptions();
      if (original == null) {
        added = updates;
        edited = new HashMap<T, String>();
        deleted = new HashSet<T>();
      } else {
        Map<T, String> current = (Map<T, String>) original.getValueDescriptions();
        Set<T> addedKeys = new HashSet<T>(updates.keySet());
        addedKeys.removeAll(current.keySet());
        added = new HashMap<T, String>();
        for (T key : addedKeys) {
          added.put(key, updates.get(key));
        }
       
        deleted = new HashSet<T>(current.keySet());
        deleted.removeAll(updates.keySet());
       
        edited = updates;
        for (T key : addedKeys) {
          edited.remove(key);
        }
      }
      done = updateValueType(vt, added, edited, deleted, policy);
    }
    return done;
  }
 
  /**
   * Add new values to the value type or update the description of existing values.
   * The maps passed as parameter can be empty but cannot be null.
   * Throw an exception if the operation cannot be done.
   *
   * @param vt a value type
   * @param added a map of values to add and their descriptions
   * @param edited a map of values to modify and their descriptions
   * @param deleted a set of values to delete
   * @param policy update policy
   * @return true if anything done
   * @throws T2DBException
   */
  private <T>boolean updateValueType(ValueType<T> vt, Map<T, String> added, Map<T, String> edited, Set<T> deleted, SchemaUpdatePolicy policy) throws T2DBException {
    int count = 0;
    for (Map.Entry<T, String> e : added.entrySet()) {
      // don't use vt.toString at this point, check will fail
      insertValueTypeValue(vt, vt.getScanner().toString(e.getKey()), e.getValue());
      count++;
    }
    for (Map.Entry<T, String> e : edited.entrySet()) {
      // don't use vt.toString at this point, check will fail
      updateValueTypeValue(vt, vt.getScanner().toString(e.getKey()), e.getValue());
      count++;
    }
    for (T value : deleted) {
      deleteValueTypeValue(vt, value, policy);
      count++;
    }
    return count > 0;
  }
 
  private PreparedStatement insert_valuelist;
  private static final String INSERT_VALUELIST =
    "insert into " + DB.VALUE_TYPE_VALUE + "(type, value, descrip) values(?, ?, ?)";
  /**
   * Insert or update the value. Throw an exception if there is anything wrong.
   *
   * @param session
   * @param name
   * @param id
   * @param value
   * @param description
   * @throws T2DBException
   */
  private <T>void insertValueTypeValue(ValueType<T> vt, String value, String description) throws T2DBException {
    boolean done = false;
    Throwable cause = null;
    if (value == null)
      throw new IllegalArgumentException("value null");
    if (description == null)
      description = "";
    try {
      insert_valuelist = open(INSERT_VALUELIST, vt, insert_valuelist);
      insert_valuelist.setInt(1, getId(vt));
      insert_valuelist.setString(2, value);
      insert_valuelist.setString(3, description);
      insert_valuelist.execute();
      done = insert_valuelist.getUpdateCount() > 0;
    } catch (Exception e) {
      cause = e;
    } finally {
      insert_valuelist = close(insert_valuelist);
    }
    if (!done || cause != null) {
      throw T2DBMsg.exception(cause, E.E10121, vt.getName());
    }
  }
 
  private PreparedStatement update_valuelist;
  private static final String UPDATE_VALUELIST =
    "update " + DB.VALUE_TYPE_VALUE + " set descrip = ? where type = ? and value = ?";
  private <T>void updateValueTypeValue(ValueType<T> vt, String value, String description) throws T2DBException {
    boolean done = false;
    Throwable cause = null;
    try {
      update_valuelist = open(UPDATE_VALUELIST, vt, update_valuelist);
      update_valuelist.setString(1, description);
      update_valuelist.setInt(2, getId(vt));
      update_valuelist.setString(3, value);
      update_valuelist.execute();
      done = update_valuelist.getUpdateCount() > 0;
    } catch (Exception e) {
      cause = e;
    } finally {
      update_valuelist = close(update_valuelist);
    }
    if (!done || cause != null) {
      throw T2DBMsg.exception(cause, E.E10122, vt.getName());
    }
  }

  private PreparedStatement delete_valuelist;
  private static final String DELETE_VALUELIST =
    "delete from " + DB.VALUE_TYPE_VALUE + " where type = ? and value = ?";
  /**
   * Delete the value. Throw an exception if there is anything wrong.
   * What can go wrong is that the value is in use, either as a
   * default value in an attribute definition or as an actual attribute value.
   *
   * @param session
   * @param name
   * @param id
   * @param value
   * @param policy update policy or null (when creating)
   * @throws T2DBException
   */
  private <T>void deleteValueTypeValue(ValueType<T> vt, T value, SchemaUpdatePolicy policy) throws T2DBException {
    boolean done = false;
    Throwable cause = null;
    String name = vt.getName();
    try {
      int id = getId(vt);
      if (policy != null
        policy.willDelete(vt, value);
      delete_valuelist = open(DELETE_VALUELIST, vt, delete_valuelist);
      delete_valuelist.setInt(1, id);
      delete_valuelist.setString(2, vt.toString(value));
      delete_valuelist.execute();
      done = delete_valuelist.getUpdateCount() > 0;
    } catch (SQLException e) {
      cause =e ;
    } finally {
      delete_valuelist = close(delete_valuelist);
    }
    if (!done|| cause != null)
      throw T2DBMsg.exception(cause, E.E10126, name, value);
  }

  private PreparedStatement delete_values;
  private static final String DELETE_VALUES =
    "delete from " + DB.VALUE_TYPE_VALUE + " where type = ?";
  private void deleteValues(ValueType<?> vt) throws T2DBException, SQLException {
    try  {
      delete_values = open(DELETE_VALUES, vt, delete_values);
      delete_values.setInt(1, getId(vt));
      delete_values.execute();
    } finally {
      delete_values = close(delete_values);
    }
  }

}
TOP

Related Classes of ch.agent.crnickl.jdbc.WriteMethodsForValueType

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.