Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.eclipse.epsilon.emc.graphml.GraphmlImporter Maven / Gradle / Ivy
/*******************************************************************************
* Copyright (c) 2014 The University of York.
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* Contributors:
* Dimitris Kolovos - initial API and implementation
******************************************************************************/
package org.eclipse.epsilon.emc.graphml;
import java.io.File;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import org.eclipse.epsilon.emc.muddle.BooleanType;
import org.eclipse.epsilon.emc.muddle.Feature;
import org.eclipse.epsilon.emc.muddle.IntegerType;
import org.eclipse.epsilon.emc.muddle.LinkElementType;
import org.eclipse.epsilon.emc.muddle.Muddle;
import org.eclipse.epsilon.emc.muddle.MuddleElement;
import org.eclipse.epsilon.emc.muddle.MuddleElementType;
import org.eclipse.epsilon.emc.muddle.MuddleFactory;
import org.eclipse.epsilon.emc.muddle.RealType;
import org.eclipse.epsilon.emc.muddle.Slot;
import org.eclipse.epsilon.emc.muddle.Type;
import org.eclipse.epsilon.eol.EolModule;
import org.jdom.Document;
import org.jdom.Element;
import org.jdom.Namespace;
import org.jdom.filter.Filter;
import org.jdom.input.SAXBuilder;
public class GraphmlImporter {
// Add support for node label patterns
protected Muddle graph = null;
protected HashMap nodeMap;
protected HashMap nodeElementMap;
protected Element graphElement = null;
protected Namespace namespace;
protected List orphanEdges;
protected GraphmlConfiguration configuration;
protected List referenceNodes;
public Muddle importGraph(File file) throws Exception {
return importGraph(file.toURI().toString());
}
public Muddle importGraph(String uri) throws Exception {
graph = MuddleFactory.eINSTANCE.createMuddle();
nodeMap = new HashMap();
nodeElementMap = new HashMap();
orphanEdges = new ArrayList();
referenceNodes = new ArrayList();
SAXBuilder builder = new SAXBuilder();
Document doc = builder.build(uri);
Element root = doc.getDocument().getRootElement();
namespace = root.getNamespace();
graphElement = root.getChild("graph", namespace);
configuration = new GraphmlConfiguration(root);
populateGraph();
adjustSlotPrototypeMultiplicitiesAndSlotValueTypes();
return graph;
}
protected void populateGraph() {
// Process node elements
for (Element nodeElement : getNodeElements()) {
String nodeTypeName = getElementData(nodeElement, configuration.getNodeTypeKey());
if (nodeTypeName == null) continue;
boolean isReference = false;
if (nodeTypeName.startsWith("@")) {
nodeTypeName = nodeTypeName.substring(1);
isReference = true;
}
// Create nodes only for typed node elements
MuddleElement node = MuddleFactory.eINSTANCE.createMuddleElement();
node.setId(nodeElement.getAttributeValue("id"));
nodeMap.put(node.getId(), node);
nodeElementMap.put(node, nodeElement);
if (isReference) {
referenceNodes.add(node);
}
graph.getElements().add(node);
node.setType(nodeTypeForName(nodeTypeName));
// If the node is a reference there's nothing
// else to do here
if (isReference) continue;
createPrimaryPrototypeSlot(node, nodeElement, configuration.getNodePrimarySlotPrototypeNameKey());
}
for (MuddleElement node : graph.getElements()) {
Element nodeElement = nodeElementMap.get(node);
populateSlots(node, nodeElement);
}
// Replace references with actual elements in the node map
for (MuddleElement referenceNode : referenceNodes) {
MuddleElement target = findReferenceTarget(referenceNode);
if (target != null) {
nodeMap.put(referenceNode.getId(), target);
}
}
// We don't need references any more
graph.getElements().removeAll(referenceNodes);
for (MuddleElement referenceNode : referenceNodes) {
annihilate(referenceNode);
}
// Process untyped edge elements
for (Element edgeElement : getEdgeElements()) {
String edgeTypeName = getElementData(edgeElement, configuration.getEdgeTypeKey());
if (edgeTypeName != null) continue;
MuddleElement source = nodeMap.get(edgeElement.getAttributeValue("source"));
MuddleElement target = nodeMap.get(edgeElement.getAttributeValue("target"));
String label = getFirstLabel(edgeElement);
if (label == null) {
orphanEdges.add(new OrphanLink(source, target));
continue;
}
Feature prototype = new LinkFeatureLabelParser(label).getFeature();
Slot slot = addSlot(source, prototype);
slot.setFeature(addSlotPrototype(source.getType(), prototype));
slot.getValues().add(target);
}
// Try to put orphan edge targets to suitable slots
for (OrphanLink orphanEdge : orphanEdges) {
Slot slot = findSuitableSlot(orphanEdge.getSource(), orphanEdge.getTarget());
if (slot != null) {
slot.getValues().add(orphanEdge.getTarget());
}
}
List typedEdgeNodes = new ArrayList();
// Create nodes for typed edges
for (Element edgeElement : getEdgeElements()) {
String edgeTypeName = getElementData(edgeElement, configuration.getEdgeTypeKey());
if (edgeTypeName == null) continue;
MuddleElement node = MuddleFactory.eINSTANCE.createMuddleElement();
node.setId(edgeElement.getAttributeValue("id"));
nodeElementMap.put(node, edgeElement);
graph.getElements().add(node);
typedEdgeNodes.add(node);
LinkElementType edgeType = edgeTypeForName(edgeTypeName);
node.setType(edgeType);
createPrimaryPrototypeSlot(node, edgeElement, configuration.getEdgePrimarySlotPrototypeNameKey());
Feature sourcePrototype = createEdgeTypeSlotPrototype(node, configuration.getEdgeSourceKey());
if (sourcePrototype != null && edgeType.getSourceFeature() == null) {
edgeType.setSourceFeature(sourcePrototype);
edgeType.getFeatures().add(sourcePrototype);
}
Feature targetPrototype = createEdgeTypeSlotPrototype(node, configuration.getEdgeTargetKey());
if (targetPrototype != null && edgeType.getTargetFeature() == null) {
edgeType.setTargetFeature(targetPrototype);
edgeType.getFeatures().add(targetPrototype);
}
Feature roleInSourcePrototype = createEdgeTypeSlotPrototype(node, configuration.getEdgeRoleInSourceKey());
if (roleInSourcePrototype != null && edgeType.getRoleInSourceFeature() == null) {
edgeType.setRoleInSourceFeature(roleInSourcePrototype);
}
Feature roleInTargetPrototype = createEdgeTypeSlotPrototype(node, configuration.getEdgeRoleInTargetKey());
if (roleInTargetPrototype != null && edgeType.getRoleInTargetFeature() == null) {
edgeType.setRoleInTargetFeature(roleInTargetPrototype);
}
}
// Populate nodes for typed edges
for (MuddleElement edgeNode : typedEdgeNodes) {
Element edgeElement = nodeElementMap.get(edgeNode);
populateSlots(edgeNode, edgeElement);
MuddleElement source = nodeMap.get(edgeElement.getAttributeValue("source"));
MuddleElement target = nodeMap.get(edgeElement.getAttributeValue("target"));
if (source != null) {
addEdgeNodeToNode(edgeNode, source, ((LinkElementType) edgeNode.getType()).getRoleInSourceFeature());
addNodeToEdgeNode(edgeNode, source, ((LinkElementType) edgeNode.getType()).getSourceFeature());
}
if (target != null) {
addEdgeNodeToNode(edgeNode, target, ((LinkElementType) edgeNode.getType()).getRoleInTargetFeature());
addNodeToEdgeNode(edgeNode, target, ((LinkElementType) edgeNode.getType()).getTargetFeature());
}
}
// Populate contents
for (MuddleElement muddleElement : graph.getElements()) {
if (muddleElement.getType() == null) continue;
Element element = nodeElementMap.get(muddleElement);
String contentsFeatureName = getElementData(element, configuration.getNodeContentsKey());
if (contentsFeatureName == null) continue;
Feature contentsFeature = getOrCreateFeature(muddleElement.getType(), contentsFeatureName);
contentsFeature.setMany(true);
Slot contentsSlot = findSlot(muddleElement, contentsFeature);
if (contentsSlot == null) {
contentsSlot = MuddleFactory.eINSTANCE.createSlot();
contentsSlot.setFeature(contentsFeature);
contentsSlot.setOwningElement(muddleElement);
}
for (Object child : element.getChildren()) {
if (child instanceof Element) {
Element childElement = (Element) child;
for (Object grandChild : childElement.getChildren()) {
if (grandChild instanceof Element) {
Element grandChildElement = (Element) grandChild;
MuddleElement contentsElement = nodeMap.get(grandChildElement.getAttributeValue("id"));
if (contentsElement != null) {
contentsSlot.getValues().add(contentsElement);
}
}
}
}
}
}
}
protected Feature getOrCreateFeature(MuddleElementType type, String featureName) {
Feature feature = null;
for (Feature candidateFeature : type.getFeatures()) {
if (candidateFeature.getName().equals(featureName)) {
feature = candidateFeature;
}
}
if (feature == null) {
feature = MuddleFactory.eINSTANCE.createFeature();
feature.setName(featureName);
feature.setOwningType(type);
}
return feature;
}
protected Feature createEdgeTypeSlotPrototype(MuddleElement edgeNode, String key) {
String slotPrototypeLabel = getNodeData(edgeNode, key);
if (slotPrototypeLabel == null) return null;
Feature prototype = new LinkFeatureLabelParser(slotPrototypeLabel).getFeature();
return prototype;
}
protected void addNodeToEdgeNode(MuddleElement edgeNode, MuddleElement node, Feature prototype) {
if (prototype == null) return;
Slot slot = addSlot(edgeNode, prototype);
slot.getValues().add(node);
}
protected void addEdgeNodeToNode(MuddleElement edgeNode, MuddleElement node, Feature prototype) {
if (prototype == null) return;
Slot slot = addSlot(node, addSlotPrototype(node.getType(), clone(prototype)));
slot.getValues().add(edgeNode);
}
protected String getNodeData(MuddleElement node, String key) {
return getElementData(nodeElementMap.get(node), key);
}
protected void populateSlots(MuddleElement node, Element element) {
for (String label : getLabels(element)) {
// Named slot value
if (isSlotValueLabel(label)) {
ValuedSlotFeatureLabelParser parser = new ValuedSlotFeatureLabelParser(label);
Slot slot = addSlot(node, parser.getFeature());
slot.setFeature(addSlotPrototype(node.getType(), parser.getFeature()));
slot.getValues().add(parser.getValue());
}
// Default slot value
else {
Slot primarySlot = getPrimarySlot(node);
if (primarySlot != null) primarySlot.getValues().add(label);
}
}
}
protected void createPrimaryPrototypeSlot(MuddleElement node, Element element, String defaultSlotPrototypeNameKey) {
// Create default prototype slot if exists
String defaultSlotPrototypeName = defaultSlotPrototypeNameKey;
if (defaultSlotPrototypeName == null) return;
String defaultSlotPrototypeLabel = getElementData(element, defaultSlotPrototypeName);
if (defaultSlotPrototypeLabel == null) return;
Feature prototype = new ValuedSlotFeatureLabelParser(defaultSlotPrototypeLabel + " = 0").getFeature();
prototype.setPrimary(true);
addSlotPrototype(node.getType(), prototype);
}
protected String getElementData(Element e, String key) {
for (Element descriptionElement : getDescendants(e, "data")) {
if (descriptionElement.getAttributeValue("key","").equals(key)) {
String data = descriptionElement.getText().trim();
if (data.length() == 0) return null;
else return data;
}
}
return null;
}
protected void annihilate(MuddleElement node) {
node.setType(null);
for (Slot slot : node.getSlots()) {
slot.setFeature(null);
slot.getValues().clear();
}
}
protected MuddleElement findReferenceTarget(MuddleElement referenceNode) {
for (MuddleElement node : referenceNode.getType().getInstances()) {
if (referenceNodes.contains(node)) continue;
if (matches(node, referenceNode)) {
return node;
}
}
return null;
}
protected boolean matches(MuddleElement node, MuddleElement referenceNode) {
for (Slot referenceSlot : referenceNode.getSlots()) {
Slot slot = findSlot(node, referenceSlot.getFeature());
if (slot == null) return false;
for (Object referenceValue : referenceSlot.getValues()) {
if (!slot.getValues().contains(referenceValue)) return false;
}
}
return true;
}
protected Slot findSlot(MuddleElement node, Feature slotPrototype) {
for (Slot slot : node.getSlots()) {
if (slot.getFeature().equals(slotPrototype)) return slot;
}
return null;
}
/**
* If single-valued slots are found to have
* multiple values, adjust the multiplicity accordingly.
* Also, adjust the type of slot values
*/
protected void adjustSlotPrototypeMultiplicitiesAndSlotValueTypes() {
for (MuddleElement node : graph.getElements()) {
for (Slot slot : node.getSlots()) {
if (!slot.getFeature().isMany() && slot.getValues().size() > 1) {
slot.getFeature().setMany(true);
}
if (slot.getValues().size() > 0) {
Type slotType = slot.getFeature().getType();
if (slotType instanceof IntegerType || slotType instanceof BooleanType || slotType instanceof RealType) {
List castedValues = new ArrayList();
for (Object value : slot.getValues()) {
castedValues.add(cast(value, slotType));
}
slot.getValues().clear();
slot.getValues().addAll(castedValues);
}
}
}
}
}
protected Object cast(Object object, Type type) {
if (type instanceof IntegerType) {
try {
return Integer.parseInt(object + "");
}
catch (Exception ex) { return 0; }
}
else if (type instanceof BooleanType) {
try {
return Boolean.parseBoolean(object + "");
}
catch (Exception ex) { return false; }
}
else if (type instanceof RealType) {
try {
return Float.parseFloat(object + "");
}
catch (Exception ex) { return 0.0f; }
}
else return object;
}
protected Slot findSuitableSlot(MuddleElement source, MuddleElement target) {
if (source == null || source.getType() == null) return null;
Feature slotPrototype = findSuitableSlotPrototype(source.getType(), target);
if (slotPrototype == null) return null;
for (Slot slot : source.getSlots()) {
if (slot.getFeature() == slotPrototype) {
return slot;
}
}
Slot slot = MuddleFactory.eINSTANCE.createSlot();
slot.setFeature(slotPrototype);
source.getSlots().add(slot);
return slot;
}
protected Feature findSuitableSlotPrototype(MuddleElementType type, MuddleElement value) {
for (Feature slotPrototype : type.getFeatures()) {
for (Slot slot : slotPrototype.getSlots()) {
for (Object existingValue : slot.getValues()) {
if (existingValue instanceof MuddleElement && ((MuddleElement) existingValue).getType().equals(value.getType())) {
return slotPrototype;
}
}
}
}
return null;
}
protected boolean isReferenceLabel(String label) {
return label.startsWith("@");
}
protected boolean isSlotValueLabel(String label) {
return label.indexOf('=') > -1;
}
protected Slot addSlot(MuddleElement node, Feature prototype) {
for (Slot existingSlot : node.getSlots()) {
if (existingSlot.getFeature().getName().equals(prototype.getName())) {
return existingSlot;
}
}
Slot slot = MuddleFactory.eINSTANCE.createSlot();
slot.setFeature(prototype);
node.getSlots().add(slot);
return slot;
}
protected Feature addSlotPrototype(MuddleElementType nodeType, Feature prototype) {
for (Feature existingPrototype : nodeType.getFeatures()) {
if (existingPrototype.getName().equals(prototype.getName())) {
if (existingPrototype.getType() == null) {
existingPrototype.setType(prototype.getType());
}
if (!existingPrototype.isMany()) {
existingPrototype.setMany(prototype.isMany());
}
if (!existingPrototype.isPrimary()) {
existingPrototype.setPrimary(prototype.isPrimary());
}
return existingPrototype;
}
}
nodeType.getFeatures().add(prototype);
return prototype;
}
protected Feature clone(Feature prototype) {
Feature clone = MuddleFactory.eINSTANCE.createFeature();
clone.setName(prototype.getName());
clone.setPrimary(prototype.isPrimary());
clone.setMany(prototype.isMany());
return clone;
}
protected Slot getPrimarySlot(MuddleElement node) {
Feature primaryFeature = null;
for (Feature prototype : node.getType().getFeatures()) {
if (prototype.isPrimary()) primaryFeature = prototype;
break;
}
if (primaryFeature == null) return null;
Slot primarySlot = null;
for (Slot slot : node.getSlots()) {
if (slot.getFeature().equals(primaryFeature)) {
primarySlot = slot;
break;
}
}
if (primarySlot == null) {
Slot slot = MuddleFactory.eINSTANCE.createSlot();
slot.setFeature(primaryFeature);
slot.setOwningElement(node);
return slot;
}
else {
return primarySlot;
}
}
protected String getFirstLabel(Element e) {
List labels = getLabels(e);
if (labels.size() > 0) return labels.get(0);
else return null;
}
protected List getLabels(Element e) {
String labelTag = "NodeLabel";
String propertiesKey = configuration.getNodePropertiesKey();
if (e.getName().equals("edge")) {
labelTag = "EdgeLabel";
propertiesKey = configuration.getEdgePropertiesKey();
}
List labels = new ArrayList();
for (Element labelElement : getDescendants(e, labelTag)) {
if (getFirstAncestor(labelElement, e.getName()) == e) {
labels.addAll(getLabels(labelElement.getText()));
}
}
for (Element descriptionElement : getDescendants(e, "data")) {
if (descriptionElement.getParentElement() != e) continue;
if (descriptionElement.getAttributeValue("key","").equals(propertiesKey)) {
labels.addAll(getLabels(descriptionElement.getText()));
}
}
return labels;
}
protected Element getFirstAncestor(Element element, String name) {
Element parentElement = element.getParentElement();
while (parentElement != null) {
if (parentElement.getName().equals(name)) {
return parentElement;
}
else {
parentElement = parentElement.getParentElement();
}
}
return null;
}
protected List getLabels(String s) {
List labels = new ArrayList();
s = s.trim();
for (String label : s.split("\\n")) {
if (label.trim().length() > 0) {
labels.add(label.trim());
}
}
return labels;
}
protected List getDescendants(Element node, final String name) {
List descendants = new ArrayList();
Iterator> iterator = node.getDescendants(new Filter() {
@Override
public boolean matches(Object o) {
return o instanceof Element && ((Element) o).getName().equals(name);
}
});
while (iterator.hasNext()) {
descendants.add((Element) iterator.next());
}
return descendants;
}
protected List getNodeElements() {
List elements = new ArrayList();
for (Object o : getDescendants(graphElement, "node") /*graphElement.getChildren("node", namespace)*/) {
elements.add((Element) o);
}
return elements;
}
protected List getEdgeElements() {
List elements = new ArrayList();
for (Object o : getDescendants(graphElement, "edge") /*graphElement.getChildren("edge", namespace)*/) {
elements.add((Element) o);
}
return elements;
}
protected LinkElementType edgeTypeForName(String name) {
return (LinkElementType) typeForName(name, true);
}
protected MuddleElementType nodeTypeForName(String name) {
return typeForName(name, false);
}
protected MuddleElementType typeForName(String name, boolean edgeType) {
int gt = name.indexOf(">");
if (gt > -1) {
String typeName = name.substring(0, gt).trim();
String superTypeName = name.substring(gt+1, name.length()).trim();
MuddleElementType type = typeForName(typeName, edgeType);
MuddleElementType superType = typeForName(superTypeName, edgeType);
if (!type.getSuperTypes().contains(superType)) {
type.getSuperTypes().add(superType);
}
return type;
}
for (Type type : graph.getTypes()) {
if (type instanceof MuddleElementType && type.getName().equals(name)) {
return (MuddleElementType) type;
}
}
MuddleElementType nodeType = null;
if (edgeType) {
nodeType = MuddleFactory.eINSTANCE.createLinkElementType();
}
else {
nodeType = MuddleFactory.eINSTANCE.createMuddleElementType();
}
nodeType.setName(name);
graph.getTypes().add(nodeType);
return nodeType;
}
public GraphmlConfiguration getConfiguration() {
return configuration;
}
}