package net.timbusproject.extractors.utils;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import net.sf.taverna.t2.activities.stringconstant.StringConstantActivity;
import net.sf.taverna.t2.workflowmodel.Processor;
import net.sf.taverna.t2.workflowmodel.processor.activity.Activity;
import uk.ac.bolton.archimate.model.FolderType;
import uk.ac.bolton.archimate.model.IAccessRelationship;
import uk.ac.bolton.archimate.model.IArchimateElement;
import uk.ac.bolton.archimate.model.IArchimateFactory;
import uk.ac.bolton.archimate.model.IArchimateModel;
import uk.ac.bolton.archimate.model.IArtifact;
import uk.ac.bolton.archimate.model.IBusinessProcess;
import uk.ac.bolton.archimate.model.IFolder;
import uk.ac.bolton.archimate.model.IRelationship;
import com.google.common.collect.Iterators;
import com.google.common.collect.UnmodifiableIterator;
public class ArchiUtils {
/**
* Group {@link IArchimateElement}s which have a relation of type {@link IAccessRelationship} between a source and a
* target element
*
* @param processors
* @param relationsList
* @return map containing source and target element (as keys) and a list of {@link IArchimateElement} between those
* two elements.
*/
public static Map<List<IArchimateElement>, List<IArchimateElement>> groupElements(
List<IArchimateElement> processors, List<IRelationship> relationsList) {
Map<List<IArchimateElement>, List<IArchimateElement>> map = new HashMap<List<IArchimateElement>, List<IArchimateElement>>();
for (IArchimateElement source : processors) {
for (IArchimateElement target : processors) {
if (!source.equals(target)) {
// get all access relations between a source and a target element
List<IArchimateElement> elementsInBetween = ArchiUtils.getElementsInBetween(source, target,
relationsList);
if (elementsInBetween.size() > 0) {
ArrayList<IArchimateElement> key = new ArrayList<IArchimateElement>();
key.add(source);
key.add(target);
map.put(key, elementsInBetween);
}
}
}
}
return map;
}
public static boolean isListComplete(List<IArchimateElement> testList, List<IArchimateElement> completeList) {
return testList.containsAll(completeList);
}
/**
* Return all {@link IArchimateElement}s which have a relation of type {@link IAccessRelationship} between a source
* and a target element
*
* @param source
* @param target
* @param relationsList
* All relations
* @return elements inbetween
*/
public static List<IArchimateElement> getElementsInBetween(IArchimateElement source, IArchimateElement target,
List<IRelationship> relationsList) {
List<IArchimateElement> elements = new ArrayList<IArchimateElement>();
List<IRelationship> sourceRelations = ofClass(relationsList, IAccessRelationship.class, source, true);
List<IRelationship> targetRelations = ofClass(relationsList, IAccessRelationship.class, target, false);
for (IRelationship sourceRelation : sourceRelations) {
for (IRelationship targetRelation : targetRelations) {
if (!sourceRelation.getClass().equals(targetRelation.getClass())) {
break;
}
if (sourceRelation.getTarget().equals(targetRelation.getTarget())) {
elements.add(sourceRelation.getTarget());
}
}
}
return elements;
}
public static <E extends IRelationship> List<E> ofClass(List<IRelationship> relationsList, Class<?> relation) {
return ArchiUtils.ofClass(relationsList, relation, null);
}
@SuppressWarnings("unchecked")
public static <E extends IArchimateElement> List<E> elementsOfClass(List<IArchimateElement> elements, Class<?> clazz) {
List<E> sublist = new ArrayList<E>();
UnmodifiableIterator<?> iter = Iterators.filter(elements.iterator(), clazz);
while (iter.hasNext()) {
sublist.add((E) iter.next());
}
return sublist;
}
@SuppressWarnings("unchecked")
public static <E extends IRelationship> List<E> ofClass(List<IRelationship> relationsList, Class<?> relation,
IArchimateElement element) {
List<E> sublist = new ArrayList<E>();
UnmodifiableIterator<?> iter = Iterators.filter(relationsList.iterator(), relation);
while (iter.hasNext()) {
E _relation = (E) iter.next();
// not considering a specific element
if (element == null) {
sublist.add(_relation);
}
// considering specific element
if (_relation.getSource().equals(element) || _relation.getTarget().equals(element)) {
sublist.add(_relation);
}
}
return sublist;
}
@SuppressWarnings("unchecked")
public static <E extends IRelationship> List<E> ofClass(List<IRelationship> relationsList, Class<?> relation,
IArchimateElement element, boolean isOutgoing) {
List<E> sublist = new ArrayList<E>();
UnmodifiableIterator<?> iter = Iterators.filter(relationsList.iterator(), relation);
while (iter.hasNext()) {
E _relation = (E) iter.next();
// special treatment
if (relation == IAccessRelationship.class) {
IAccessRelationship _accessRelation = (IAccessRelationship) _relation;
// if (_accessRelation.getSource() != null && _accessRelation.getTarget() != null) {
// outgoing access
if (isOutgoing && _accessRelation.getSource().equals(element)
&& _accessRelation.getAccessType() == IAccessRelationship.WRITE_ACCESS) {
sublist.add((E) _accessRelation);
}
// incoming access
if (!isOutgoing && _accessRelation.getSource().equals(element)
&& _accessRelation.getAccessType() == IAccessRelationship.READ_ACCESS) {
sublist.add((E) _accessRelation);
}
// }
}
// all other relations
else {
// if (_relation.getSource() != null && _relation.getTarget() != null) {
if (_relation.getSource().equals(element) || _relation.getTarget().equals(element)) {
// outgoing
if (isOutgoing && _relation.getSource().equals(element)) {
sublist.add(_relation);
}
// incoming
if (!isOutgoing && _relation.getTarget().equals(element)) {
sublist.add(_relation);
}
}
// }
}
}
return sublist;
}
public static List<IArchimateElement> getInputElementsOfProcess(IBusinessProcess process,
List<IRelationship> relationsList) {
List<IArchimateElement> elements = new ArrayList<IArchimateElement>();
for (IRelationship _relation : ArchiUtils.ofClass(relationsList, IAccessRelationship.class, process, false)) {
elements.add(_relation.getTarget());
}
return elements;
}
public static List<IArchimateElement> getOutputElementsOfProcess(IBusinessProcess process,
List<IRelationship> relationsList) {
List<IArchimateElement> elements = new ArrayList<IArchimateElement>();
for (IRelationship _relation : ArchiUtils.ofClass(relationsList, IAccessRelationship.class, process, true)) {
elements.add(_relation.getTarget());
}
return elements;
}
public static IRelationship initRelation(IRelationship relation, IArchimateElement source,
IArchimateElement target, IFolder folder) {
relation.setSource(source);
relation.setTarget(target);
// relation.setName(source.getName() + "-->" + target.getName());
folder.getElements().add(relation);
return relation;
}
public static void removeRelation(Collection<IRelationship> relationsToRemove, Collection<IRelationship> relations,
IFolder folder) {
relations.removeAll(relationsToRemove);
folder.getElements().removeAll(relationsToRemove);
}
public static <E extends IRelationship> E initRelation(E relation, IArchimateElement source,
IArchimateElement target, IFolder folder, List<IRelationship> relationsList) {
initRelation(relation, source, target, folder);
relationsList.add(relation);
return relation;
}
public static void redirectRelations(IArchimateElement parent, IArchimateElement source, IArchimateElement target,
List<IArchimateElement> childs, List<IRelationship> relations) {
List<IRelationship> markedToRemove = new ArrayList<IRelationship>();
for (IRelationship relation : relations) {
for (IArchimateElement _target : childs) {
if (relation.getSource().equals(source) && relation.getTarget().equals(_target)
|| relation.getSource().equals(target) && relation.getTarget().equals(_target)) {
markedToRemove.add(relation);
}
}
}
relations.removeAll(markedToRemove);
}
/**
* @param accessType
* one of {@link IAccessRelationship#READ_ACCESS}, {@link IAccessRelationship#WRITE_ACCESS},
* {@link IAccessRelationship#READ_WRITE_ACCESS}, {@link IAccessRelationship#UNSPECIFIED_ACCESS}
*/
public static <E extends IAccessRelationship> E initAccessRelation(E relation, IArchimateElement source,
IArchimateElement target, IFolder folder, List<IRelationship> relationsList, int accessType) {
IAccessRelationship accessRelation = initRelation(relation, source, target, folder, relationsList);
accessRelation.setAccessType(accessType);
return relation;
}
public static IRelationship initRelationNodeElement(IRelationship relation, IArchimateElement source,
IArchimateElement target, IFolder folder, List<IArchimateElement> elementList) {
initRelation(relation, source, target, folder);
elementList.add(relation);
return relation;
}
public static boolean containsRelation(IArchimateElement targetElement, IArchimateElement sourceElement,
Collection<IRelationship> relations) {
for (IRelationship r : relations) {
if (r.getSource() == sourceElement && r.getTarget() == targetElement) {
return true;
}
}
return false;
}
public static ArrayList<IArchimateElement> getElementsByname(String name, Collection<IArchimateElement> elements) {
ArrayList<IArchimateElement> matchingElements = new ArrayList<IArchimateElement>();
for (IArchimateElement item : elements) {
if (item.getName().equals(name)) {
matchingElements.add(item);
}
}
return matchingElements;
}
public static boolean isValueProcessor(Processor processor) {
if (processor.getActivityList().size() > 0) {
for (Activity<?> activity : processor.getActivityList()) {
if (!(activity instanceof StringConstantActivity)) {
return false;
}
}
return true;
} else {
return false;
}
}
public static <E extends IArchimateElement> E initElement(E element, String name, IFolder folder,
Container container) {
// create the archimate element
element.setName(name);
folder.getElements().add(element);
container.add(element);
return element;
}
public static <E extends IArchimateElement> E initElement(E element, String name, IFolder folder,
List<E> nodeElements) {
element.setName(name);
folder.getElements().add(element);
nodeElements.add(element);
return element;
}
public static List<IArchimateElement> getSourceElements(List<IRelationship> relations) {
List<IArchimateElement> elements = new ArrayList<IArchimateElement>();
for (IRelationship relation : relations) {
elements.add(relation.getSource());
}
return elements;
}
}