
com.puresoltechnologies.parsers.parser.items.AbstractItemSet Maven / Gradle / Ivy
The newest version!
package com.puresoltechnologies.parsers.parser.items;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import com.puresoltechnologies.parsers.grammar.production.Construction;
/**
* This class is the base implementation of an item set. This abstract class can
* take different items of interface Item in dependence to the parser used.
*
* THIS CLASS IS NOT THREAD SAFE!!!
*
* @author Rick-Rainer Ludwig
*
* @param
* is the item type of interface Item to be used.
*/
public abstract class AbstractItemSet implements Serializable {
private static final long serialVersionUID = 4299654494281633726L;
/*
* The following fields have concurrent versions of lists and sets for
* iterating and manipulating values in different item calculations.
*/
private final Set allItems = new LinkedHashSet();
private final Set kernelItems = new LinkedHashSet();
private final Set nonKernelItems = new LinkedHashSet();
private boolean changed = true;
private int hashCode = 0;
/**
* This constructor takes a single kernel item.
*
* @param kernelItem
* is the first item to add.
*/
public AbstractItemSet(T kernelItem) {
kernelItems.add(kernelItem);
allItems.add(kernelItem);
}
/**
* This constructor takes a list of kernel items.
*
* @param kernelItems
* is a {@link Set} of kernel items to be added.
*/
public AbstractItemSet(Set kernelItems) {
this.kernelItems.addAll(kernelItems);
this.allItems.addAll(kernelItems);
}
/**
* This constructor takes an abstract item set and creates a new item set
* with base of the given item set.
*
* @param itemSet
* is an {@link AbstractItemSet} to be used as values.
*/
public AbstractItemSet(AbstractItemSet itemSet) {
this.kernelItems.addAll(itemSet.getKernelItems());
this.nonKernelItems.addAll(itemSet.getNonKernelItems());
this.allItems.addAll(itemSet.getKernelItems());
this.allItems.addAll(itemSet.getNonKernelItems());
}
public int getSize() {
return allItems.size();
}
public boolean containsItem(T item) {
if (kernelItems.contains(item)) {
return true;
}
if (nonKernelItems.contains(item)) {
return true;
}
return false;
}
public boolean addKernelItems(Set items) {
boolean result = false;
for (T item : items) {
if (addKernelItem(item)) {
result = true;
}
}
if (result) {
changed = true;
}
return result;
}
public boolean addKernelItem(T item) {
boolean result = false;
if (allItems.add(item)) {
kernelItems.add(item);
changed = true;
result = true;
}
return result;
}
public boolean removeItem(T item) {
if (!allItems.remove(item)) {
return false;
}
kernelItems.remove(item);
nonKernelItems.remove(item);
changed = true;
return true;
}
public boolean addNonKernelItems(Set items) {
boolean result = false;
for (T item : items) {
if (addNonKernelItem(item)) {
result = true;
}
}
if (result) {
changed = true;
}
return result;
}
public boolean addNonKernelItem(T item) {
boolean result = false;
if (allItems.add(item)) {
nonKernelItems.add(item);
result = true;
changed = true;
}
return result;
}
public Set getAllItems() {
return allItems;
}
public Set getKernelItems() {
return kernelItems;
}
public Set getNonKernelItems() {
return nonKernelItems;
}
/**
* This method returns all constructions which are next to be expected to be
* found.
*
* @return {@link List} of {@link Construction} is returned.
*/
public List getNextConstructions() {
List constructions = new ArrayList();
for (T item : kernelItems) {
Construction element = item.getNext();
if (element != null) {
constructions.add(element);
}
}
for (T item : nonKernelItems) {
Construction element = item.getNext();
if (element != null) {
constructions.add(element);
}
}
return constructions;
}
/**
* This method returns all items which have the given construction as next
* construction.
*
* @param construction
* is the {@link Construction} to be used to look up next items.
* @return A {@link List} of items is returned.
*/
public List getNextItems(Construction construction) {
List items = new ArrayList();
for (T item : allItems) {
if (construction.equals(item.getNext())) {
items.add(item);
}
}
return items;
}
public Set getAllGrammarSymbols() {
Set grammarSymbols = new LinkedHashSet();
for (Item item : allItems) {
for (Construction construction : item.getProduction()
.getConstructions()) {
grammarSymbols.add(construction);
}
}
return grammarSymbols;
}
@Override
public String toString() {
StringBuffer buffer = new StringBuffer();
for (T item : kernelItems) {
buffer.append(" ");
buffer.append(item);
buffer.append("\n");
}
for (T item : nonKernelItems) {
buffer.append("+ ");
buffer.append(item);
buffer.append("\n");
}
return buffer.toString();
}
@Override
public int hashCode() {
if (changed) {
final int prime = 31;
int result = 1;
result = prime * result
+ ((allItems == null) ? 0 : allItems.hashCode());
result = prime * result
+ ((kernelItems == null) ? 0 : kernelItems.hashCode());
result = prime
* result
+ ((nonKernelItems == null) ? 0 : nonKernelItems.hashCode());
hashCode = result;
changed = false;
}
return hashCode;
}
/**
* In this equals method the set allItems is used for check of equality.
* Kernel and NonKernel items should be always equal in normal circumstances
* and therefore is the reduced equality check suitable...
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AbstractItemSet> other = (AbstractItemSet>) obj;
if (this.hashCode() != other.hashCode()) {
return false;
}
if (allItems == null) {
if (other.allItems != null)
return false;
} else if (!allItems.equals(other.allItems))
return false;
return true;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy