All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.ctakes.ytex.kernel.tree.InstanceTreeBuilderImpl Maven / Gradle / Ivy

/**
 * 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 org.slf4j.LoggerFactory;
import org.slf4j.Logger;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;
import java.io.*;
import java.util.*;

public class InstanceTreeBuilderImpl implements InstanceTreeBuilder {
	static final Logger LOGGER = LoggerFactory.getLogger("InstanceTreeBuilderImpl");
	JdbcTemplate jdbcTemplate;
	private DataSource dataSource;

	public DataSource getDataSource() {
		return dataSource;
	}

	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
		this.jdbcTemplate = new JdbcTemplate(dataSource);		
	}

	Node nodeFromRow(NodeMappingInfo nodeInfo, Map nodeValues) {
		Node n = null;
		Map values = new HashMap(
				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 loadInstanceTrees(String filename)
			throws IOException, ClassNotFoundException {
		ObjectInputStream os = null;
		try {
			os = new ObjectInputStream(new BufferedInputStream(
					new FileInputStream(filename)));
			return (Map) 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 loadInstanceTrees(TreeMappingInfo mappingInfo) {
		Map nodeKeyMap = new HashMap();
		this.prepare(mappingInfo.getPrepareScript(), mappingInfo.getPrepareScriptStatementDelimiter());
		Map 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 prepareScript
	 * @param prepareScriptDelimiter
	 */
	protected void prepare(String prepareScript, String prepareScriptDelimiter) {
		if(prepareScript != null && prepareScript.length() > 0) {
			String[] statements = prepareScript.split(prepareScriptDelimiter);
			List listStatements = new ArrayList(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 loadInstanceTrees(String instanceIDField,
			QueryMappingInfo qInfo, Map nodeKeyMap) {
		Node[] currentPath = new Node[qInfo.getNodeTypes().size()];
		Map instanceMap = new HashMap();
		List> rowData = jdbcTemplate.queryForList(
				qInfo.getQuery(), qInfo.getQueryArgs());
		for (Map 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 nodeKeyMap,
			QueryMappingInfo qInfo) {
		// run query
		List> rowData = jdbcTemplate.queryForList(
				qInfo.getQuery(), qInfo.getQueryArgs());
		// iterate through rows, adding nodes as children of existing nodes
		for (Map 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 ( LOGGER.isWarnEnabled()) {
						LOGGER.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);
							}
						}
					}
				}
			}
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy