blob: b06b23721303c8cb71ab7a959e2f67a215c22c22 [file] [log] [blame]
/*
* 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.uima.ruta.resource;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
* Class MultipleTextNode.
*
*
* Represents a node of the data structure MultiTreeWordList.
*/
public class MultiTextNode {
/** The Character represented by the node. */
private char value;
// /** Indicates whether this is a word end. */
// private boolean isWordEnd;
/** The Map of child nodes. */
private Map<Character, MultiTextNode> children;
/** Documents/Types that contain the value specified by the super class. */
private Set<String> types;
private boolean isWordEnd = false;
private static final int DEFAUL_INITIAL_CAPACITY = 5;
/** Default constructor uses a space as value. */
public MultiTextNode() {
this(' ', false);
}
/**
* Constructs a MultiTextNode with a character and the information, whether this is a word end or
* not.
*
* @param value
* The Character represented by the node.
* @param isWordEnd
* Indicates whether this is a word end.
*/
public MultiTextNode(char value, boolean isWordEnd) {
this(value, isWordEnd, DEFAUL_INITIAL_CAPACITY);
}
/**
* Constructs a MultiTextNode with a character and the information, whether this is a word end or
* not. Documents are the documents, where the word, represented by the path from the root to this
* node, occurs.
*
* @param value
* The Character represented by the node.
* @param isWordEnd
* Indicates whether this is a word end.
* @param capacity
* The initial capacity of the map of child nodes.
*/
private MultiTextNode(char value, boolean isWordEnd, int capacity) {
this.value = value;
this.children = new HashMap<Character, MultiTextNode>(capacity);
setWordEnd(isWordEnd);
}
/**
* Adds the MultiTextNode n to the map of children.
*
* @param n
* The MultiTextNode, which should be added.
* @return The previous value associated with the value of n, if exists, null otherwise.
*/
public MultiTextNode addChild(MultiTextNode n) {
if (children == null) {
children = new HashMap<Character, MultiTextNode>();
}
return children.put(n.getValue(), n);
}
/**
* Returns the child, when you follow the c-edge, if exists. Returns null otherwise.
*
* @param c
* The edge which is chosen.
* @return The child of the c-edge, if exists, null otherwise.
*/
public MultiTextNode getChildNode(char c) {
// Remember Lazy Initialization.
if (children == null) {
return null;
}
return children.get(c);
}
/**
* Returns the value of the MultiTextNode.
*
* @return The value of the MultiTextNode.
*/
public char getValue() {
return this.value;
}
public void setValue(char c) {
this.value = c;
}
/**
* Returns a value which specifies, whether the word is finished or not.
*
* @return A value which specifies, whether the word is finished or not.
*/
public boolean isWordEnd() {
return isWordEnd;
}
/**
* Returns the map of children as an unmodifiable map.
*
* @return the map of children as an unmodifiable map.
*/
public Map<Character, MultiTextNode> getChildren() {
// Remember Lazy Initialization.
if (children == null) {
return Collections.unmodifiableMap(new HashMap<Character, MultiTextNode>());
}
return Collections.unmodifiableMap(children);
}
/**
* Adds the string that specifies a document to the list of sources.
*
* @param type
* The string that specifies a document.
* @return True, if the sources did not already contain the string document, false otherwise.
*/
public boolean addType(String type) {
if (types == null) {
types = new HashSet<String>();
}
return types.add(type);
}
/**
* Returns an unmodifiable Collection containing the types.
*
* @return An unmodifiable Collection containing the types.
*/
public Collection<String> getTypes() {
// Remember Lazy Initialization.
if (types == null) {
return Collections.emptyList();
}
return types;
}
/**
* Sets isWordEnd to the specified boolean.
*
* @param b
* The boolean, isWordEnd is set to.
*/
public void setWordEnd(boolean b) {
isWordEnd = b;
}
/**
* Returns a String representation of the MultiTextNode.
*
* @return A String representation of the MultiTextNode.
*/
@Override
public String toString() {
StringBuilder s = new StringBuilder(Character.toString(getValue()) + "\n");
if (getChildren() != null) {
List<Character> sortedList = new LinkedList<Character>();
sortedList.addAll(getChildren().keySet());
Collections.sort(sortedList);
for (Character each : sortedList) {
s.append(each + ", ");
}
}
return s.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((children == null) ? 0 : children.hashCode());
// result = prime * result + (isWordEnd() ? 1231 : 1237);
result = prime * result + ((types == null) ? 0 : getTypes().hashCode());
result = prime * result + value;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MultiTextNode other = (MultiTextNode) obj;
if (children == null) {
if (other.children != null)
return false;
// } else if (!childrenEquals(other))
} else if (!children.equals(other.getChildren()))
return false;
// if (isWordEnd != other.isWordEnd())
// return false;
if (types == null) {
if (other.types != null)
return false;
} else if (!typesEquals(other))
// } else if (!sources.equals(other.getSources()))
return false;
if (value != other.getValue())
return false;
return true;
}
/**
* Returns true, if the two MultiTextNodes have the same sources. That's true, when the sources
* contain the same strings.
*
* @param other
* The MultiTextNode, which is compared to this one.
* @return true, if if the two MultiTextNodes have the same sources, false otherwise.
*/
private boolean typesEquals(MultiTextNode other) {
if (getTypes() == null) {
return other.getTypes() == null;
}
for (String s : getTypes()) {
if (!other.getTypes().contains(s)) {
return false;
}
}
for (String s : other.getTypes()) {
if (!getTypes().contains(s)) {
return false;
}
}
return true;
}
}