annis.sqlgen.TableAccessStrategy.java Source code

Java tutorial

Introduction

Here is the source code for annis.sqlgen.TableAccessStrategy.java

Source

/*
 * Copyright 2009-2011 Collaborative Research Centre SFB 632 
 *
 * 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 annis.sqlgen;

import java.util.HashMap;
import java.util.Map;

import org.apache.commons.collections.Bag;
import org.apache.commons.collections.bag.HashBag;

import annis.model.QueryNode;

public class TableAccessStrategy {

    // default table names
    public final static String NODE_TABLE = "node";
    public final static String RANK_TABLE = "rank";
    public final static String COMPONENT_TABLE = "component";
    public final static String NODE_ANNOTATION_TABLE = "node_annotation";
    public final static String EDGE_ANNOTATION_TABLE = "edge_annotation";
    public final static String ANNOTATION_POOL_TABLE = "annotation_pool";
    public final static String FACTS_TABLE = "facts";
    public final static String CORPUS_TABLE = "corpus";
    public final static String CORPUS_ANNOTATION_TABLE = "corpus_annotation";
    public final static String TEXT_TABLE = "text";

    // the wrapped node
    private QueryNode node;

    // table aliases
    private Map<String, String> tableAliases;

    // aliased column names
    private Map<String, Map<String, String>> columnAliases;

    public TableAccessStrategy() {
        this.tableAliases = new HashMap<String, String>();
        this.columnAliases = new HashMap<String, Map<String, String>>();

    }

    public TableAccessStrategy(QueryNode node) {
        this();
        this.node = node;
    }

    /** Copy constructor */
    public TableAccessStrategy(TableAccessStrategy tas) {
        this.tableAliases = new HashMap<String, String>(tas.getTableAliases());
        this.columnAliases = new HashMap<String, Map<String, String>>(tas.getColumnAliases());
        this.node = tas.getNode();
    }

    ///// table and column aliases

    public String tableName(String table) {
        return tableAliases.containsKey(table) ? tableAliases.get(table) : table;
    }

    public String columnName(String table, String column) {
        if (columnAliases.containsKey(table)) {
            Map<String, String> columns = columnAliases.get(table);
            if (columns.containsKey(column)) {
                return columns.get(column);
            }
        }
        return column;
    }

    public String aliasedTable(String table, int count) {
        if (node != null) {
            // sanity checks
            //         if (table.equals(NODE_ANNOTATION_TABLE) && count > node.getNodeAnnotations().size())
            //            throw new IllegalArgumentException("access to node annotation table out of range: " + count);
            if (table.equals(EDGE_ANNOTATION_TABLE) && count > node.getEdgeAnnotations().size())
                throw new IllegalArgumentException("access to edge annotation table out of range: " + count);
            if (table.equals(NODE_TABLE) && count > 1)
                throw new IllegalArgumentException("access to struct table out of range: " + count);
            if (table.equals(RANK_TABLE) && count > 1)
                throw new IllegalArgumentException("access to rank table out of range: " + count);

            // offset table count for edge annotations if node and edge annotations are the same table
            if (table.equals(EDGE_ANNOTATION_TABLE) && isMaterialized(EDGE_ANNOTATION_TABLE, NODE_ANNOTATION_TABLE))
                count = count + node.getNodeAnnotations().size() - 1;
        }

        if (count == 0) {
            count = 1;
        }

        // compute table counts
        Bag tables = computeSourceTables();

        String aliasedName = tableName(table);
        String aliasCount = node != null ? String.valueOf(node.getId()) : "";
        String countSuffix = tables.getCount(aliasedName) > 1 ? "_" + count : "";

        return aliasedName + aliasCount + countSuffix;
    }

    public String aliasedColumn(String table, String column) {
        return aliasedColumn(table, column, 1);
    }

    public String aliasedColumn(String table, String column, int count) {
        return column(aliasedTable(table, count), columnName(table, column));
    }

    protected String column(String table, String column) {
        return table + "." + column;
    }

    ///// table usage

    protected Bag computeSourceTables() {
        Bag tables = new HashBag();

        // hack to support table selections for ANNOTATE query
        if (node == null) {
            String[] tableNames = { NODE_TABLE, RANK_TABLE, COMPONENT_TABLE, NODE_ANNOTATION_TABLE,
                    EDGE_ANNOTATION_TABLE };
            for (String table : tableNames)
                tables.add(table);
            return tables;
        }

        tables.add(tableName(NODE_ANNOTATION_TABLE), node.getNodeAnnotations().size());
        if (node.getNodeAnnotations().isEmpty() && node.getNodeAnnotations().size() > 0)
            tables.add(tableName(NODE_ANNOTATION_TABLE));

        tables.add(tableName(EDGE_ANNOTATION_TABLE), node.getEdgeAnnotations().size());

        if (tables.getCount(tableName(RANK_TABLE)) == 0 && usesRankTable())
            tables.add(tableName(RANK_TABLE));
        if (tables.getCount(tableName(COMPONENT_TABLE)) == 0 && usesRankTable())
            tables.add(tableName(COMPONENT_TABLE));

        if (tables.getCount(tableName(NODE_TABLE)) == 0)
            tables.add(tableName(NODE_TABLE));

        return tables;
    }

    public boolean usesNodeAnnotationTable() {
        return node == null || !node.getNodeAnnotations().isEmpty();
    }

    public boolean usesRankTable() {
        return node == null || usesComponentTable() || node.isRoot() || node.getArity() != null;
    }

    public boolean usesComponentTable() {
        return node == null || node.isPartOfEdge() || usesEdgeAnnotationTable();
    }

    public boolean usesEdgeAnnotationTable() {
        return node == null || !node.getEdgeAnnotations().isEmpty();
    }

    public boolean isMaterialized(String table, String otherTable) {
        return tableName(table).equals(tableName(otherTable));
    }

    ///// delegates

    public void addTableAlias(String table, String alias) {
        tableAliases.put(table, alias);
    }

    public void addColumnAlias(String table, String column, String alias) {
        if (!columnAliases.containsKey(table))
            columnAliases.put(table, new HashMap<String, String>());

        Map<String, String> aliases = columnAliases.get(table);
        aliases.put(column, alias);
    }

    ///// Getter / Setter

    public QueryNode getNode() {
        return node;
    }

    public void setNode(QueryNode node) {
        this.node = node;
    }

    public Map<String, String> getTableAliases() {
        return tableAliases;
    }

    public void setTableAliases(Map<String, String> tableAliases) {
        this.tableAliases = tableAliases;
    }

    public Map<String, Map<String, String>> getColumnAliases() {
        return columnAliases;
    }

    public void setColumnAliases(Map<String, Map<String, String>> columnAliases) {
        this.columnAliases = columnAliases;
    }

}