JGraphSQLBackend.java :  » Natural-Language-Processing » Stanford-CoreNLP » com » jgraph » example » adapter » Java Open Source

Java Open Source » Natural Language Processing » Stanford CoreNLP 
Stanford CoreNLP » com » jgraph » example » adapter » JGraphSQLBackend.java
/*
 * $Id: JGraphSQLBackend.java,v 1.1.1.1 2005/08/06 05:26:45 gaudenz Exp $
 * 
 * Copyright (c) 2001-2005, Gaudenz Alder
 * 
 * See LICENSE file in distribution for licensing details of this source file
 */
package com.jgraph.example.adapter;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.jgraph.graph.DefaultGraphCell;
import org.jgraph.graph.DefaultGraphModel;
import org.jgraph.graph.GraphConstants;

/**
 * Maps changes to the graph model to a custom backend, eg. an SQL database.
 * (This should use prepared statements.)
 */
public class JGraphSQLBackend implements JGraphAdapterBackend {

  protected static final String NO_ID = "0";

  protected int lastId = 0;

  protected boolean trxInProgress = false;

  protected Object vertexPrototype, edgePrototype;

  protected Connection conn;

  public JGraphSQLBackend(Connection conn, Object vertexPrototype,
      Object edgePrototype) throws ClassNotFoundException, SQLException {
    this.conn = conn;
    this.vertexPrototype = vertexPrototype;
    this.edgePrototype = edgePrototype;
    try {
      update("SET AUTOCOMMIT FALSE");
      update("CREATE TABLE entity ( id INTEGER, parent_id INTEGER)");
      update("CREATE TABLE relation ( entity_id INTEGER, source_id INTEGER, target_id INTEGER)");
      update("CREATE TABLE property ( entity_id INTEGER, key VARCHAR(256), value VARCHAR(256))");
      update("CREATE INDEX prp_entity_idx ON property (entity_id)");
      update("CREATE INDEX rel_entity_idx ON relation (entity_id)");
      update("CREATE INDEX rel_source_idx ON relation (source_id)");
      update("CREATE INDEX rel_target_idx ON relation (target_id)");
      // Triggers to update the model if the db changes...
      // update("CREATE TRIGGER test_trigger AFTER UPDATE ON property CALL
      // org.jgraph.studio.business.JGraphStudioSQLBackend.TestTrigger");
      update("COMMIT");
    } catch (SQLException ex2) {
      // this will have no effect on the db
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#valueForCellChanged(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object, java.lang.Object)
   */
  public void commit() throws Exception {
    if (trxInProgress) {
      update("COMMIT");
      trxInProgress = false;
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#valueForCellChanged(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object, java.lang.Object)
   */
  public void rollback() throws Exception {
    if (trxInProgress) {
      update("ROLLBACK");
      trxInProgress = false;
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#vertexAdded(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object)
   */
  public void vertexAdded(JGraphAdapterModel sender, Object vertex,
      boolean validate) throws Exception {
    if (!validate)
      objectAdded(sender.getValue(vertex));
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#valueForCellChanged(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object, java.lang.Object)
   */
  public void edgeAdded(JGraphAdapterModel sender, Object object,
      Object source, Object target, boolean validate) throws Exception {
    if (!validate) {
      Object id = objectAdded(sender.getValue(object));
      if (id != null)
        update("INSERT INTO relation(entity_id, source_id, target_id) VALUES ("
            + id + ", 0, 0)");
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#valueForCellChanged(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object, java.lang.Object)
   */
  protected Object objectAdded(Object object) throws SQLException {
    if (object instanceof JGraphSQLEntity) {
      JGraphSQLEntity entity = (JGraphSQLEntity) object;
      if (entity.getID() == null) {
        entity.setID(getNextEntityId());
        update("INSERT INTO entity(id) VALUES (" + entity.getID() + ")");
        Iterator it = entity.getProperties().entrySet().iterator();
        while (it.hasNext()) {
          Map.Entry entry = (Map.Entry) it.next();
          update("INSERT INTO property(entity_id, key, value) VALUES ("
              + entity.getID()
              + ", '"
              + entry.getKey()
              + "', '"
              + entry.getValue() + "')");
        }
      }
      return entity.getID();
    }
    return null;
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#valueForCellChanged(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object, java.lang.Object)
   */
  public void cellRemoved(JGraphAdapterModel sender, Object cell,
      boolean validate) throws Exception {
    Object userObj = sender.getValue(cell);
    if (!validate && userObj instanceof JGraphSQLEntity) {
      JGraphSQLEntity entity = (JGraphSQLEntity) userObj;
      Object entityId = entity.getID();
      update("DELETE FROM entity WHERE id = " + entityId);
      update("DELETE FROM relation WHERE entity_id = " + entityId);
      update("DELETE FROM property WHERE entity_id = " + entityId);
      update("UPDATE entity SET parent_id = " + NO_ID
          + " WHERE parent_id = " + entityId);
      entity.setID(null);
    }
  }

  public void parentChanged(JGraphAdapterModel sender, Object child,
      Object parent, boolean validate) throws Exception {
    Object childObj = sender.getValue(child);
    Object parentObj = sender.getValue(parent);
    if (!validate && childObj instanceof JGraphSQLEntity
        && parentObj instanceof JGraphSQLEntity) {
      JGraphSQLEntity childEntity = (JGraphSQLEntity) childObj;
      JGraphSQLEntity parentEntity = (JGraphSQLEntity) parentObj;
      update("UPDATE entity SET parent_id = " + parentEntity.getID()
          + " where id = " + childEntity.getID());
      childEntity.setParent(parentEntity);
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#valueForCellChanged(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object, java.lang.Object)
   */
  public void sourceChanged(JGraphAdapterModel sender, Object edge,
      Object source, boolean validate) throws Exception {
    Object object = sender.getValue(edge);
    source = sender.getParentUserObject(source);
    if (!validate && object instanceof JGraphSQLRelation) {
      JGraphSQLRelation relation = (JGraphSQLRelation) object;
      Object id = NO_ID;
      if (source instanceof JGraphSQLEntity) {
        relation.setSource((JGraphSQLEntity) source);
        id = relation.getSource().getID();
      } else
        relation.setSource(null);
      update("UPDATE relation SET source_id = " + id
          + " where entity_id = " + relation.getID());
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#valueForCellChanged(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object, java.lang.Object)
   */
  public void targetChanged(JGraphAdapterModel sender, Object edge,
      Object target, boolean validate) throws Exception {
    Object object = sender.getValue(edge);
    target = sender.getParentUserObject(target);
    if (!validate && object instanceof JGraphSQLRelation) {
      JGraphSQLRelation relation = (JGraphSQLRelation) object;
      Object id = NO_ID;
      if (target instanceof JGraphSQLEntity) {
        relation.setTarget((JGraphSQLEntity) target);
        id = relation.getTarget().getID();
      } else
        relation.setTarget(null);
      update("UPDATE relation SET target_id = " + id
          + " where entity_id = " + relation.getID());
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#valueForCellChanged(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object, java.lang.Object)
   */
  public void attributesChanged(JGraphAdapterModel sender, Object cell,
      Map attributes, boolean validate) throws Exception {
    if (!validate) {
      if (cell instanceof JGraphSQLEntity) {
        propertiesChanged(cell, attributes);
      } else {
        Object value = GraphConstants.getValue(attributes);
        if (value != null) {
          Map properties = new Hashtable();
          properties.put("value", value);
          propertiesChanged(sender.getValue(cell),
              properties);
        }
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#valueForCellChanged(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object, java.lang.Object)
   */
  public void propertiesChanged(Object object, Map properties)
      throws Exception {
    if (object instanceof JGraphSQLEntity) {
      JGraphSQLEntity entity = (JGraphSQLEntity) object;
      Iterator it = properties.entrySet().iterator();
      while (it.hasNext()) {
        Map.Entry entry = (Map.Entry) it.next();
        // TODO: Handle new attributes here?
        propertyChanged(entity, entry.getKey(), entry.getValue());
      }
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#valueForCellChanged(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object, java.lang.Object)
   */
  public void propertyChanged(JGraphSQLEntity entity, Object key, Object value)
      throws Exception {
    update("UPDATE property SET value = '" + value + "' where key='" + key
        + "' AND entity_id = " + entity.getID());
  }

  /*
   * This method is called from the Studio UI. (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#valueForCellChanged(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object, java.lang.Object)
   */
  public void propertyAdded(JGraphSQLEntity entity, Object key, Object value)
      throws Exception {
    update("INSERT INTO property(entity_id, key, value) VALUES ("
        + entity.getID() + ", '" + key + "', '" + value + "')");
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#valueForCellChanged(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object, java.lang.Object)
   */
  public Collection findVertices(JGraphAdapterModel sender, Object query,
      Object parent) throws SQLException {
    Object object = sender.getValue(parent);
    String parentClause = (object instanceof JGraphSQLEntity) ? " and parent_id = "
        + ((JGraphSQLEntity) object).getID()
        : "";
    String whereClause = "where "
        + createFilter(query)
        + parentClause
        + " and not exists (select 1 from relation where relation.entity_id = property.entity_id)";
    return findCells(sender, whereClause);
  }

  protected Collection findCells(JGraphAdapterModel context,
      String whereClause) throws SQLException {
    Collection objs = find(whereClause);
    List result = new ArrayList(objs.size());
    Iterator it = objs.iterator();
    while (it.hasNext()) {
      JGraphSQLEntity entity = (JGraphSQLEntity) it.next();
      result.add(createCell(context, entity));
    }
    return result;
  }

  public Object getParent(Object object) {
    if (object instanceof JGraphSQLEntity)
      return ((JGraphSQLEntity) object).getParent();
    return null;
  }

  public Object getSource(Object object) {
    if (object instanceof JGraphSQLRelation)
      return ((JGraphSQLRelation) object).getSource();
    return null;
  }

  public Object getTarget(Object object) {
    if (object instanceof JGraphSQLRelation)
      return ((JGraphSQLRelation) object).getTarget();
    return null;
  }

  // All relations with cells (parent, source, target) must be
  // set when inserting the cells. the backend only sets the relations
  // on the business-object level.
  public Object createCell(JGraphAdapterModel context, JGraphSQLEntity entity)
      throws SQLException {
    Object prototype = (entity instanceof JGraphSQLRelation) ? edgePrototype
        : vertexPrototype;

    // TODO: Do not create if mapped?
    Object vertex = DefaultGraphModel.cloneCell(context, prototype);
    if (vertex instanceof DefaultGraphCell) {
      DefaultGraphCell cell = (DefaultGraphCell) vertex;
      cell.setUserObject(entity);
    }
    return vertex;
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#valueForCellChanged(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object, java.lang.Object)
   */
  public Collection findEdges(JGraphAdapterModel sender, Object query,
      Object parent, Object source, Object target, boolean directed)
      throws SQLException {
    Object object = sender.getValue(parent);
    source = sender.getValue(source);
    target = sender.getValue(target);
    String parentClause = (object instanceof JGraphSQLEntity) ? " and parent_id = "
        + ((JGraphSQLEntity) object).getID()
        : "";
    String edgeWhereClause = "1=1 ";
    if (source instanceof JGraphSQLEntity) {
      JGraphSQLEntity entity = (JGraphSQLEntity) source;
      edgeWhereClause += "and source_id = " + entity.getID() + " ";
    }
    if (target instanceof JGraphSQLEntity) {
      JGraphSQLEntity entity = (JGraphSQLEntity) target;
      edgeWhereClause += "and target_id = " + entity.getID() + " ";
    } else if (!directed && source != null) { // TODO: Shortcut for now...
      JGraphSQLEntity entity = (JGraphSQLEntity) source;
      edgeWhereClause += "or target_id = " + entity.getID() + " ";
    }
    String whereClause = "where "
        + createFilter(query)
        + parentClause
        + " and exists (select 1 from relation where relation.entity_id = property.entity_id and ("
        + edgeWhereClause + "))";
    return findCells(sender, whereClause);
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#valueForCellChanged(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object, java.lang.Object)
   */
  protected String createFilter(Object query) {
    if (query != null && query.toString().length() > 0) {
      String[] tokens = query.toString().split(" ");
      if (tokens.length > 0) {
        String filter = "soundex(value) IN (soundex('" + tokens[0]
            + "')";
        for (int i = 1; i < tokens.length; i++)
          filter += ", soundex('" + tokens[i] + "')";
        return filter + ")";
      }
    }
    return "1=1";
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#valueForCellChanged(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object, java.lang.Object)
   */
  protected Collection find(String whereClause) throws SQLException {
    Statement st = (conn != null) ? conn.createStatement() : null;
    String sql = "select entity_id, count(entity_id) as ranking from property "
        + whereClause + " group by entity_id order by ranking desc";
    println("SQL: " + sql);
    ResultSet rs = (st != null) ? st.executeQuery(sql) : null;
    List objects = new LinkedList();
    while (rs != null && rs.next()) {
      Object object = get(rs.getObject(1));
      if (object != null)
        objects.add(object);
    }
    if (st != null)
      st.close();
    return objects;
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#valueForCellChanged(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object, java.lang.Object)
   */
  protected synchronized Object getNextEntityId() {
    int id = lastId;
    try {
      Statement st = (conn != null) ? conn.createStatement() : null;
      ResultSet rs = (st != null) ? st
          .executeQuery("select max(id) from entity") : null;
      if (st != null)
        st.close();
      if (rs != null && rs.next())
        id = rs.getInt(1) + 1;
      else
        // use local var for ids
        lastId++;
    } catch (SQLException e) {
      // ignore and return lastId
    }
    return new Integer(id);
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#valueForCellChanged(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object, java.lang.Object)
   */
  public JGraphSQLEntity get(Object id) throws SQLException {
    Statement st = (conn != null) ? conn.createStatement() : null;
    JGraphSQLEntity entity = null;
    ResultSet rs = st
        .executeQuery("select id, parent_id from entity where id = "
            + id);

    Object entityId = null;
    JGraphSQLEntity parent = null;
    if (rs.next()) {
      entityId = rs.getObject(1);
      parent = get(rs.getObject(2));
    }

    // Assumes that the entity exists
    rs = st
        .executeQuery("select source_id, target_id from relation where entity_id = "
            + id);

    // Fetch the source and target, or create a vertex
    if (rs.next()) {
      JGraphSQLEntity source = get(rs.getObject(1));
      JGraphSQLEntity target = get(rs.getObject(2));
      entity = new JGraphSQLRelation(entityId, parent, source, target); // TODO.
      // Add
      // Parent
    } else {
      entity = new JGraphSQLEntity(entityId, parent);
    }

    // Fill-in the properties
    rs = st
        .executeQuery("select key, value from property where entity_id = "
            + id);
    Hashtable properties = new Hashtable();
    while (rs.next()) {
      String key = rs.getString(1);
      String value = rs.getString(2);
      if (key != null) {
        properties.put(key, value);
      }
    }
    st.close();
    entity.setProperties(properties);

    return entity;
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#valueForCellChanged(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object, java.lang.Object)
   */
  public synchronized void query(String expression) throws SQLException {
    Statement st = (conn != null) ? conn.createStatement() : null;
    ResultSet rs = (st != null) ? st.executeQuery(expression) : null;
    dump(rs);
    st.close();
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#valueForCellChanged(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object, java.lang.Object)
   */
  public void dump(ResultSet rs) throws SQLException {
    ResultSetMetaData meta = rs.getMetaData();
    int colmax = meta.getColumnCount();
    while (rs.next()) {
      for (int i = 0; i < colmax; ++i) {
        Object o = rs.getObject(i + 1);
        if (o != null)
          System.out.print(o.toString() + " ");
      }
      println(" ");
    }
  }

  /*
   * (non-Javadoc)
   * 
   * @see org.jgraph.editor.business.JGraphBusinessBackend#valueForCellChanged(org.jgraph.editor.business.JGraphBusinessModel,
   *      java.lang.Object, java.lang.Object)
   */
  public synchronized void update(String expression) throws SQLException {
    trxInProgress = true;
    Statement st = (conn != null) ? conn.createStatement() : null;
    int i = (st != null) ? st.executeUpdate(expression) : 0;
    if (i == -1) {
      println("db error : " + expression);
    } else {
      println("SQL: " + expression);
    }
    if (st != null)
      st.close();
  }

  protected static void println(String msg) {
    JGraphAdapterExample.println(msg);
  }

}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.