regexgaz.LinearDefinition.java Source code

Java tutorial

Introduction

Here is the source code for regexgaz.LinearDefinition.java

Source

package regexgaz;

/*
 *  LinearDefinition.java
 *
 *  Copyright (c) 1995-2012, The University of Sheffield. See the file
 *  COPYRIGHT.txt in the software or at http://gate.ac.uk/gate/COPYRIGHT.txt
 *
 *  This file is part of GATE (see http://gate.ac.uk/), and is free
 *  software, licenced under the GNU Library General Public License,
 *  Version 2, June 1991 (in the distribution as file licence.html,
 *  and also available at http://gate.ac.uk/gate/licence.html).
 *
 *  borislav popov 02/2002
 *
 *  $Id: LinearDefinition.java 17594 2014-03-08 12:07:09Z markagreenwood $
 */
import gate.creole.AbstractLanguageResource;
import gate.creole.ResourceInstantiationException;
import gate.creole.gazetteer.InvalidFormatException;
import gate.util.BomStrippingInputStreamReader;
import gate.util.Files;
import gate.util.GateRuntimeException;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Set;

import org.apache.commons.io.IOUtils;

/**
 * Represents a Linear Definition [lists.def] file <br>
 * The normal usage of the class will be * construct it * setURL * load * change
 * * store
 */
public class LinearDefinition extends AbstractLanguageResource implements List<LinearNode> {

    private static final long serialVersionUID = 4050479036709221175L;

    private final static String DEF_ENCODING = "UTF-8";

    /**
     * the list of nodes
     */
    private final List<LinearNode> nodes = new ArrayList<>();

    private URL url;

    /**
     * set of lists as strings
     */
    private final List<String> lists = new ArrayList<>();

    private String listEncoding = "UTF-8";

    /**
     * a mapping between a list and a node
     */
    private final Map<String, LinearNode> nodesByList = new HashMap<>();

    /**
     * a map of gazetteer lists by nodes. this is loaded on loadLists
     */
    private Map<LinearNode, GazetteerList> gazListsByNode = new HashMap<>();

    private boolean isModified = false;

    /**
     * the separator used to delimit feature name-value pairs in gazetteer lists
     */
    private String separator;

    public void setListEncoding(String encod) {
        listEncoding = encod;
    }

    public String getListEncoding() {
        return listEncoding;
    }

    /**
     * Loads the gazetteer lists and maps them to the nodes
     *
     * @return a map of nodes vs GazetteerLists
     * @throws ResourceInstantiationException when the resource cannot be
     * created
     */
    public Map<LinearNode, GazetteerList> loadLists() throws ResourceInstantiationException {
        return loadLists(false);
    }

    /**
     * Loads the gazetteer lists and maps them to the nodes
     *
     * @return a map of nodes vs GazetteerLists
     * @param isOrdered true if the feature maps used should be ordered
     * @throws ResourceInstantiationException when the resource cannot be
     * created
     */
    public Map<LinearNode, GazetteerList> loadLists(boolean isOrdered) throws ResourceInstantiationException {
        try {
            gazListsByNode = new HashMap<>();
            Iterator<LinearNode> inodes = nodes.iterator();
            while (inodes.hasNext()) {
                LinearNode node = inodes.next();

                GazetteerList list = new GazetteerList();
                list.setSeparator(separator);
                URL lurl = new URL(url, node.getList());
                list.setURL(lurl);
                list.setEncoding(listEncoding);
                list.load(isOrdered);

                gazListsByNode.put(node, list);
            }
        } catch (MalformedURLException | ResourceInstantiationException ex) {
            throw new ResourceInstantiationException(ex);
        }
        return gazListsByNode;
    }

    /**
     * Loads a single gazetteer list given a name
     *
     * @param listName the name of the list to be loaded
     * @return the loaded gazetteer list
     * @throws ResourceInstantiationException
     */
    public GazetteerList loadSingleList(String listName) throws ResourceInstantiationException {
        return loadSingleList(listName, false);
    }

    /**
     * Loads a single gazetteer list given a name
     *
     * @param listName the name of the list to be loaded
     * @param isOrdered true if the feature maps used should be ordered
     * @return the loaded gazetteer list
     * @throws ResourceInstantiationException
     */
    public GazetteerList loadSingleList(String listName, boolean isOrdered) throws ResourceInstantiationException {
        GazetteerList list = new GazetteerList();
        list.setSeparator(separator);
        try {

            try {
                URL lurl = new URL(url, listName);
                list.setURL(lurl);
                list.load(isOrdered);
            } catch (MalformedURLException | ResourceInstantiationException x) {
                String path = url.getPath();
                int slash = path.lastIndexOf("/");
                if (-1 != slash) {
                    path = path.substring(0, slash + 1);
                }

                File f = new File(path + listName);

                if (!f.exists()) {
                    f.createNewFile();
                }

                URL lurl = new URL(url, listName);
                list.setURL(lurl);
                list.load(isOrdered);
            }

        } catch (MalformedURLException murle) {
            throw new ResourceInstantiationException(murle);
        } catch (IOException ioex) {
            throw new ResourceInstantiationException(ioex);
        }
        return list;
    }

    public Map<LinearNode, GazetteerList> getListsByNode() {
        return gazListsByNode;
    }

    public Map<String, LinearNode> getNodesByListNames() {
        return nodesByList;
    }

    @Override
    public boolean isModified() {
        return isModified;
    }

    public void setModified(boolean modified) {
        isModified = modified;
    }

    public URL getURL() {
        return url;
    }

    public void setURL(URL aUrl) {
        url = aUrl;
    }

    public String getSeparator() {
        return separator;
    }

    public void setSeparator(String separator) {
        this.separator = separator;
    }

    /**
     * Loads linear definition
     */
    public void load() throws ResourceInstantiationException {
        if (null == url) {
            throw new ResourceInstantiationException("URL not set (null).");
        }
        BufferedReader defReader = null;
        try {
            if ("file".equals(url.getProtocol())) {
                File definitionFile = Files.fileFromURL(url);
                // create an new definition file only if not existing
                definitionFile.createNewFile();
            }
            defReader = new BomStrippingInputStreamReader((url).openStream(), DEF_ENCODING);

            String line;
            LinearNode node;
            while (null != (line = defReader.readLine())) {
                node = new LinearNode(line);

                this.add(node);

            } // while
            isModified = false;
        } catch (IllegalArgumentException | IOException | InvalidFormatException x) {
            throw new ResourceInstantiationException(x);
        } finally {
            IOUtils.closeQuietly(defReader);
        }
    }

    /**
     * Stores this to a definition file.
     */
    public void store() throws ResourceInstantiationException {
        if (null == url) {
            throw new ResourceInstantiationException("URL not set.(null)");
        }
        try {
            File fileo = Files.fileFromURL(url);
            fileo.delete();
            BufferedWriter defWriter = new BufferedWriter(new FileWriter(fileo));
            Iterator<LinearNode> inodes = nodes.iterator();
            while (inodes.hasNext()) {
                defWriter.write(inodes.next().toString());
                defWriter.newLine();
            }
            defWriter.close();
            isModified = false;
        } catch (IllegalArgumentException | IOException x) {
            throw new ResourceInstantiationException(x);
        }

    }

    /**
     * Gets gazetteer lists of this definition. note that a new list is created
     * so the adding and removing of lists will not affect the internal members.
     * Also there is no setLists method since the leading member of the class is
     * nodes, and lists cannot be added individually without being associated
     * with a node.
     *
     * @return a list of the gazetteer lists names
     */
    public List<String> getLists() {
        return new ArrayList<String>(lists);
    }

    public List<LinearNode> getNodes() {
        return new ArrayList<LinearNode>(nodes);
    }

    /**
     * Gets the set of all major types in this definition
     * @return the set of all major types present in this definition
     */
    public Set<String> getMajors() {
        Set<String> result = new HashSet<>();
        for (int i = 0; i < nodes.size(); i++) {
            String maj = nodes.get(i).getMajorType();
            if (null != maj) {
                result.add(maj);
            }
        }
        return result;
    }

    /**
     * Gets the set of all minor types in this definition
     * @return the set of all minor types present in this definition
     */
    public Set<String> getMinors() {
        Set<String> result = new HashSet<>();
        for (int i = 0; i < nodes.size(); i++) {
            String min = nodes.get(i).getMinorType();
            if (null != min) {
                result.add(min);
            }
        }
        result.add("");
        return result;
    }

    /**
     * Gets the set of languages in this definition
     * @return the set of languages present in this definition
     */
    public Set<String> getLanguages() {
        Set<String> result = new HashSet<>();
        for (int i = 0; i < nodes.size(); i++) {
            String lang = nodes.get(i).getLanguage();
            if (null != lang) {
                result.add(lang);
            }
        }
        result.add("");
        return result;
    }

    /*---implementation of interface java.util.List---*/
    @Override
    public boolean addAll(int index, Collection<? extends LinearNode> c) {
        int size = nodes.size();
        Iterator<? extends LinearNode> iter = c.iterator();
        LinearNode o;
        while (iter.hasNext()) {
            o = iter.next();
            add(index, o);
        }
        boolean result = (size != nodes.size());
        isModified |= result;
        return result;
    }

    @Override
    public LinearNode get(int index) {
        return nodes.get(index);
    }

    @Override
    public LinearNode set(int index, LinearNode element) {
        throw new UnsupportedOperationException("this method has not been implemented");
    }

    /**
     * Add a node to this LinearDefinition.
     * NOTE: this will throw a GateRuntimeException if anything goes wrong when
     * reading the list.
     *
     * @param index
     * @param ln
     */
    @Override
    public void add(int index, LinearNode ln) {
        String list = ln.getList();
        if (!nodesByList.containsKey(list)) {
            try {
                GazetteerList gl = loadSingleList(list);
                gazListsByNode.put(ln, gl);
                nodes.add(index, ln);
                nodesByList.put(list, ln);
                lists.add(list);
                isModified = true;
            } catch (ResourceInstantiationException x) {
                throw new GateRuntimeException("Error loading list: " + list + ": " + x.getMessage(), x);
            }
        } // if unique
    }

    @Override
    public LinearNode remove(int index) {
        LinearNode result;
        int size = nodes.size();
        result = nodes.remove(index);
        if (null != result) {
            String list = result.getList();
            lists.remove(list);
            nodesByList.remove(list);
            gazListsByNode.remove(result);
            isModified |= (size != nodes.size());
        }
        return result;
    }

    @Override
    public int indexOf(Object o) {
        return nodes.indexOf(o);
    }

    @Override
    public int lastIndexOf(Object o) {
        return nodes.lastIndexOf(o);
    }

    @Override
    public ListIterator<LinearNode> listIterator() {
        throw new UnsupportedOperationException("this method is not implemented");
    }

    @Override
    public ListIterator<LinearNode> listIterator(int index) {
        throw new UnsupportedOperationException("this method is not implemented");
    }

    @Override
    public List<LinearNode> subList(int fromIndex, int toIndex) {
        return nodes.subList(fromIndex, toIndex);
    } // class SafeIterator

    @Override
    public int size() {
        return nodes.size();
    }

    @Override
    public boolean isEmpty() {
        return 0 == nodes.size();
    }

    @Override
    public boolean contains(Object o) {
        return nodes.contains(o);
    }

    @Override
    public Iterator<LinearNode> iterator() {
        return new SafeIterator();
    }

    @Override
    public Object[] toArray() {
        return nodes.toArray();
    }

    @Override
    public <T> T[] toArray(T[] a) {
        return nodes.toArray(a);
    }

    /**
     * Adds a new node, only if its list is new and uniquely mapped to this
     * node.
     * <p>
     * NOTE: this will throw a GateRuntimeException if anything goes wrong
     * reading the list.
     *
     * @param o a node
     * @return true if the list of node is not already mapped with another node.
     */
    @Override
    public boolean add(LinearNode o) {
        boolean result = false;
        String list = o.getList();
        if (!nodesByList.containsKey(list)) {
            try {
                GazetteerList gl = loadSingleList(list);
                gazListsByNode.put(o, gl);
                result = nodes.add(o);
                nodesByList.put(list, o);
                lists.add(list);
                isModified = true;
            } catch (ResourceInstantiationException x) {
                throw new GateRuntimeException("Error loading list: " + list + ": " + x.getMessage(), x);
                // result = false;
            }
        } // if unique
        return result;
    }

    @Override
    public boolean remove(Object o) {
        boolean result = false;
        int size = nodes.size();
        if (o instanceof LinearNode) {
            result = nodes.remove(o);
            String list = ((LinearNode) o).getList();
            lists.remove(list);
            nodesByList.remove(list);
            gazListsByNode.remove(o);
            isModified |= (size != nodes.size());
        }
        return result;
    }

    @Override
    public boolean containsAll(Collection<?> c) {
        return nodes.containsAll(c);
    }

    @Override
    public boolean addAll(Collection<? extends LinearNode> c) {
        boolean result = false;
        Iterator<? extends LinearNode> iter = c.iterator();
        LinearNode o;
        while (iter.hasNext()) {
            o = iter.next();
            result |= add(o);
        }
        return result;
    }

    @Override
    public boolean removeAll(Collection<?> c) {
        boolean result = false;
        Iterator<?> iter = c.iterator();
        Object o;
        while (iter.hasNext()) {
            o = iter.next();
            result |= remove(o);
        }
        return result;
    }

    @Override
    public boolean retainAll(Collection<?> c) {
        int aprioriSize = nodes.size();
        List<LinearNode> scrap = new ArrayList<>();

        LinearNode node;
        Iterator<LinearNode> inodes = nodes.iterator();
        while (inodes.hasNext()) {
            node = inodes.next();
            if (c.contains(node)) {
                scrap.add(node);
            }
        }
        removeAll(scrap);
        isModified |= (aprioriSize != nodes.size());
        return aprioriSize != nodes.size();
    }

    @Override
    public void clear() {
        nodes.clear();
        lists.clear();
        nodesByList.clear();
        gazListsByNode.clear();
        isModified = true;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((lists == null) ? 0 : lists.hashCode());
        result = prime * result + ((nodes == null) ? 0 : nodes.hashCode());
        result = prime * result + ((nodesByList == null) ? 0 : nodesByList.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        LinearDefinition other = (LinearDefinition) obj;
        if (lists == null) {
            if (other.lists != null) {
                return false;
            }
        } else if (!lists.equals(other.lists)) {
            return false;
        }
        if (nodes == null) {
            if (other.nodes != null) {
                return false;
            }
        } else if (!nodes.equals(other.nodes)) {
            return false;
        }
        if (nodesByList == null) {
            if (other.nodesByList != null) {
                return false;
            }
        } else if (!nodesByList.equals(other.nodesByList)) {
            return false;
        }
        return true;
    }

    /*---end of implementation of interface java.util.List---*/

    /*-----------internal classes -------------*/
    /**
     * SafeIterator class provides an iterator which is safe to be iterated and
     * objects removed from it
     */
    private class SafeIterator implements Iterator<LinearNode> {

        private Iterator<LinearNode> iter = LinearDefinition.this.nodes.iterator();

        private boolean removeCalled = false;

        private LinearNode last = null;

        @Override
        public boolean hasNext() {
            return iter.hasNext();
        }

        @Override
        public LinearNode next() {
            removeCalled = false;
            last = iter.next();
            return last;
        }

        @Override
        public void remove() {
            if (!removeCalled && null != last) {
                LinearDefinition.this.remove(last);
            } // if possible remove
            removeCalled = true;
        }
    } // class SafeIterator

}//class LinearDefinition