/*******************************************************************************
* Copyright (c) 2012-2015 INRIA.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Generoso Pagano - initial API and implementation
******************************************************************************/
package fr.inria.soctrace.lib.model;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Stack;
import fr.inria.soctrace.lib.model.utils.SoCTraceException;
/**
* Data for an analysis result of type group.
*
* @author "Generoso Pagano <generoso.pagano@inria.fr>"
*/
public class AnalysisResultGroupData extends AnalysisResultData {
/**
* Root of the groups hierarchy.
* Note: even for flat grouping with several groups
* A, B, C
* a root is needed, to save the grouping as a hierarchy.
* E.g.
* ROOT_GROUP
* | A, B, C
*/
private Group root;
/**
* The constructor. Set the correct type.
*/
public AnalysisResultGroupData(Group root) {
super();
this.type = AnalysisResultType.TYPE_GROUP;
this.root = root;
}
@Override
public void print() throws SoCTraceException {
root.print(0);
}
/**
* @return the root
*/
public Group getRoot() {
return root;
}
/**
* @param root the root to set
*/
public void setRoot(Group root) {
this.root = root;
}
/**
* Depth first iterator for the group tree.
* Get an instance of a sub-group iterator.
* Each time an iterator is requested, the tree consistency
* is checked (loop detection).
*
* @return the sub-groups iterator
* @throws SoCTraceException
*/
public DepthFirstIterator getDepthFirstIterator() throws SoCTraceException {
this.root.checkTree();
return new DepthFirstIterator();
}
/**
* It navigates only through the sub groups.
* It is used in the save visitor.
*/
public class DepthFirstIterator implements Iterator<Group> {
private Stack<Group> groupStack = new Stack<Group>();
public DepthFirstIterator() {
if (AnalysisResultGroupData.this.root != null) {
groupStack.push (AnalysisResultGroupData.this.root);
}
}
public boolean hasNext() {
return !groupStack.empty ( );
}
public Group next () {
if (!hasNext()) {
return null;
}
Group node = groupStack.pop();
Stack<Group> tmp = new Stack<Group>();
if(node instanceof OrderedGroup) {
Map<Integer, Group> groups = ((OrderedGroup) node).getSonGroups();
for (Group g: groups.values()) {
tmp.push(g);
}
} else {
List<Group> groups = ((UnorderedGroup) node).getSonGroups();
for (Group g: groups) {
tmp.push(g);
}
}
int size = tmp.size();
for (int i=0; i<size; ++i) {
groupStack.push(tmp.pop());
}
return node;
}
public void remove() {
throw new UnsupportedOperationException();
}
}
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((root == null) ? 0 : root.hashCode());
return result;
}
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof AnalysisResultGroupData))
return false;
AnalysisResultGroupData other = (AnalysisResultGroupData) obj;
if (root == null) {
if (other.root != null)
return false;
} else if (!root.equals(other.root))
return false;
return true;
}
}