disko.AnalysisContext.java Source code

Java tutorial

Introduction

Here is the source code for disko.AnalysisContext.java

Source

/*******************************************************************************
 * Copyright (c) 2005, Kobrix Software, Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Lesser Public License v2.1
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Borislav Iordanov - initial API and implementation
 *     Murilo Saraiva de Queiroz - initial API and implementation
 ******************************************************************************/
package disko;

import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hypergraphdb.HGHandle;
import org.hypergraphdb.HyperGraph;
import org.hypergraphdb.HGQuery.hg;
import org.hypergraphdb.query.HGQueryCondition;
import org.hypergraphdb.query.Or;

import relex.corpus.TextInterval;

public class AnalysisContext<DocumentType> {
    protected static Log log = LogFactory.getLog(AnalysisContext.class);

    private HyperGraph graph;
    private ThreadLocal<LinkedList<HGHandle>> scope = new ThreadLocal<LinkedList<HGHandle>>();
    private HGHandle initialScope = null;
    private DocumentType document;

    protected LinkedList<HGHandle> getScope() {
        LinkedList<HGHandle> S = scope.get();
        if (S == null) {
            S = new LinkedList<HGHandle>();
            if (initialScope != null)
                S.push(initialScope);
            scope.set(S);
        }
        return S;
    }

    public AnalysisContext(HyperGraph graph, DocumentType document) {
        this.graph = graph;
        this.document = document;
    }

    public HyperGraph getGraph() {
        return graph;
    }

    public void setGraph(HyperGraph graph) {
        this.graph = graph;
    }

    public DocumentType getDocument() {
        return document;
    }

    public HGHandle getInitialScope() {
        return initialScope;
    }

    public void setInitialScope(HGHandle initialScope) {
        this.initialScope = initialScope;
    }

    public HGHandle getTopScope() {
        if (getScope().isEmpty())
            return null;
        else
            return getScope().getLast();
    }

    public HGHandle getScoping() {
        return getScope().peek();
    }

    public void pushScoping(HGHandle scoping) {
        getScope().add(0, scoping);
    }

    public HGHandle popScope() {
        return getScope().remove(0);
    }

    public void addInScope(HGHandle h) {
        graph.add(new ScopeLink(getScope().peek(), h));
    }

    public HGHandle add(Object x) {
        HGHandle h = graph.add(x);
        addInScope(h);
        return h;
    }

    public HGHandle addTyped(Object x, HGHandle type) {
        HGHandle h = graph.add(x, type);
        graph.add(new ScopeLink(getScope().peek(), h));
        return h;
    }

    public HGHandle add(Object x, HGHandle... scope) {
        HGHandle result = graph.add(x);
        for (HGHandle s : scope)
            graph.add(new ScopeLink(s, result));
        return result;
    }

    public HGHandle addTyped(Object x, HGHandle type, HGHandle... scope) {
        HGHandle result = graph.add(x, type);
        for (HGHandle s : scope)
            graph.add(new ScopeLink(s, result));
        return result;
    }

    /**
     * <p>
     * Return all scopes of a given atom. 
     * </p>
     * 
     * @param data
     * @return
     */
    public List<HGHandle> getScopes(HGHandle data) {
        return hg.findAll(graph, hg.apply(hg.linkProjection(0), hg.apply(hg.deref(graph),
                hg.and(hg.type(ScopeLink.class), hg.incident(data), hg.orderedLink(hg.anyHandle(), data)))));
    }

    /**
     * <p>
     * Return a single scope of a given atom. This is a convenience method
     * when it is known that an atom has only one scope.
     * </p>
     * 
     * @param data
     * @return
     */
    public HGHandle getOneScope(HGHandle data) {
        List<HGHandle> scopes = getScopes(data);
        return scopes.size() > 0 ? scopes.get(0) : null;
    }

    /**
     * <p>
     * Find a set of objects within the current scope.
     * </p>
     * 
     * @param <T>
     * @param type
     * @return
     */
    public <T> Set<T> find(Class<T> type) {
        return find(hg.type(type), getScoping());
    }

    /**
     * <p>
     * Find a set of annotations within the current scope and within 
     * the specified interval.  
     * </p>
     * 
     * @param <T>
     * @param type
     * @param within
     * @return
     */
    public <T extends Ann> Set<T> find(Class<T> type, TextInterval within) {
        return find(hg.and(hg.type(type), hg.gte("interval.start", within.getStart()),
                hg.lte("interval.end", within.getEnd())), getScoping());
    }

    /**
     * <p>
     * Find a set of objects satisfying a particular condition and within
     * the specified scope.
     * </p>
     * 
     * <p>
     * For each atom satisfying the condition <code>cond</code>, its scope
     * is recursively constructed and matched against the passed in scope
     * (i.e. the set of scope handles passed as parameters must be a subset
     * of the full scope of the atom).
     * </p>
     * 
     * @param <T>
     * @return
     */
    @SuppressWarnings("unchecked")
    public <T> Set<T> find(HGQueryCondition cond, HGHandle... scope) {
        Set<T> result = new HashSet<T>();
        if (scope != null && scope.length > 0) {
            Or or = new Or();
            for (HGHandle s : scope)
                or.add(hg.and(cond, hg.bfs(s, hg.type(ScopeLink.class), null, false, true)));
            cond = or;
        }
        List<HGHandle> tmp = hg.findAll(graph, cond);
        for (HGHandle h : tmp)
            result.add((T) graph.get(h));
        return result;
    }
}