Package org.apache.ctakes.ytex.kernel.tree

Source Code of org.apache.ctakes.ytex.kernel.tree.InstanceTreeBuilderImpl

/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  The ASF licenses this file
* to you 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 org.apache.ctakes.ytex.kernel.tree;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.sql.DataSource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;

public class InstanceTreeBuilderImpl implements InstanceTreeBuilder {
  static final Log log = LogFactory.getLog(InstanceTreeBuilderImpl.class);
  SimpleJdbcTemplate simpleJdbcTemplate;
  private DataSource dataSource;

  public DataSource getDataSource() {
    return dataSource;
  }

  public void setDataSource(DataSource dataSource) {
    this.dataSource = dataSource;
    this.simpleJdbcTemplate = new SimpleJdbcTemplate(dataSource);
  }

  Node nodeFromRow(NodeMappingInfo nodeInfo, Map<String, Object> nodeValues) {
    Node n = null;
    Map<String, Serializable> values = new HashMap<String, Serializable>(
        nodeInfo.getValues().size());
    for (String valueName : nodeInfo.getValues()) {
      if (nodeValues.containsKey(valueName)
          && nodeValues.get(valueName) != null) {
        values.put(valueName, (Serializable) nodeValues.get(valueName));
      }
    }
    // make sure there is something to put in
    if (!values.isEmpty()) {
      n = new Node();
      n.setType(nodeInfo.getNodeType());
      n.setValue(values);
    }
    return n;
  }

  @SuppressWarnings("unchecked")
  @Override
  public Map<Long, Node> loadInstanceTrees(String filename)
      throws IOException, ClassNotFoundException {
    ObjectInputStream os = null;
    try {
      os = new ObjectInputStream(new BufferedInputStream(
          new FileInputStream(filename)));
      return (Map<Long, Node>) os.readObject();
    } finally {
      if (os != null)
        os.close();
    }
  }

  @Override
  public void serializeInstanceTrees(TreeMappingInfo mappingInfo,
      String filename) throws IOException {
    ObjectOutputStream os = null;
    try {
      os = new ObjectOutputStream(new BufferedOutputStream(
          new FileOutputStream(filename)));
      os.writeObject(loadInstanceTrees(mappingInfo));
    } finally {
      if (os != null)
        os.close();
    }
  }

  public Map<Long, Node> loadInstanceTrees(TreeMappingInfo mappingInfo) {
    Map<NodeKey, Node> nodeKeyMap = new HashMap<NodeKey, Node>();
    this.prepare(mappingInfo.getPrepareScript(), mappingInfo.getPrepareScriptStatementDelimiter());
    Map<Long, Node> instanceMap = loadInstanceTrees(
        mappingInfo.getInstanceIDField(),
        mappingInfo.getInstanceQueryMappingInfo(), nodeKeyMap);
    if (mappingInfo.getNodeQueryMappingInfos() != null) {
      for (QueryMappingInfo qInfo : mappingInfo
          .getNodeQueryMappingInfos()) {
        this.addChildrenToNodes(nodeKeyMap, qInfo);
      }
    }
    return instanceMap;
  }
 

  /**
   * run 'preparation' statements.  These may e.g. create temporary tables in the database.
   * @param prepareStatementList
   */
  protected void prepare(String prepareScript, String prepareScriptDelimiter) {
    if(prepareScript != null && prepareScript.length() > 0) {
      String[] statements = prepareScript.split(prepareScriptDelimiter);
      List<String> listStatements = new ArrayList<String>(statements.length);
      // throw out empty lines
      for(String sql : statements) {
        if(sql != null && sql.trim().length() > 0)
          listStatements.add(sql);
      }
      JdbcTemplate jt = new JdbcTemplate(this.getDataSource());
      jt.batchUpdate(listStatements.toArray(new String[]{}));
    }
  }

  /*
   * (non-Javadoc)
   *
   * @see
   * org.apache.ctakes.ytex.kernel.tree.InstanceTreeBuilder#loadInstanceTrees(java.util.List,
   * java.lang.String, java.lang.String, java.util.Map)
   */
  protected Map<Long, Node> loadInstanceTrees(String instanceIDField,
      QueryMappingInfo qInfo, Map<NodeKey, Node> nodeKeyMap) {
    Node[] currentPath = new Node[qInfo.getNodeTypes().size()];
    Map<Long, Node> instanceMap = new HashMap<Long, Node>();
    List<Map<String, Object>> rowData = simpleJdbcTemplate.queryForList(
        qInfo.getQuery(), qInfo.getQueryArgs());
    for (Map<String, Object> row : rowData) {
      for (int i = 0; i < qInfo.getNodeTypes().size(); i++) {
        Node newNode = this.nodeFromRow(qInfo.getNodeTypes().get(i),
            row);
        if (newNode != null) {
          if (!newNode.equals(currentPath[i])) {
            if (i > 0) {
              // add the node to the parent
              currentPath[i - 1].getChildren().add(newNode);
            } else {
              // this is a new root, i.e. a new instance
              // add it to the instance map
              instanceMap.put(((Number) row.get(instanceIDField)).longValue(),
                  newNode);
            }
            // put the new node in the path
            // we don't really care about nodes 'after' this one in
            // the path list
            // because we only add to parents, not to children
            currentPath[i] = newNode;
            if (nodeKeyMap != null)
              nodeKeyMap.put(new NodeKey(newNode), newNode);
          }
        }
      }
    }
    return instanceMap;
  }

  public void addChildrenToNodes(Map<NodeKey, Node> nodeKeyMap,
      QueryMappingInfo qInfo) {
    // run query
    List<Map<String, Object>> rowData = simpleJdbcTemplate.queryForList(
        qInfo.getQuery(), qInfo.getQueryArgs());
    // iterate through rows, adding nodes as children of existing nodes
    for (Map<String, Object> row : rowData) {
      // allocate array for holding node path corresponding to row
      Node[] currentPath = new Node[qInfo.getNodeTypes().size()];
      // get the root of this subtree - temporary node contains values
      Node parentTmp = nodeFromRow(qInfo.getNodeTypes().get(0), row);
      if (parentTmp != null) {
        // get the node from the tree that correponds to this node
        Node parent = nodeKeyMap.get(new NodeKey(parentTmp));
        if (parent == null) {
          if (log.isWarnEnabled()) {
            log.warn("couldn't find node for key: " + parentTmp);
          }
        } else {
          // found the parent - add the subtree
          currentPath[0] = parent;
          for (int i = 1; i < qInfo.getNodeTypes().size(); i++) {
            Node newNode = this.nodeFromRow(qInfo.getNodeTypes()
                .get(i), row);
            if (newNode != null) {
              if (!newNode.equals(currentPath[i])) {
                // null out everything after this index in the path
                Arrays.fill(currentPath, i,
                    currentPath.length - 1, null);
                // add the node to the parent
                currentPath[i - 1].getChildren().add(newNode);
                // put the new node in the path
                // we don't really care about nodes 'after' this
                // one in the path list
                // because we only add to parents, not to
                // children
                currentPath[i] = newNode;
                if (nodeKeyMap != null)
                  nodeKeyMap.put(new NodeKey(newNode),
                      newNode);
              }
            }
          }
        }
      }
    }
  }

}
TOP

Related Classes of org.apache.ctakes.ytex.kernel.tree.InstanceTreeBuilderImpl

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.