Skip to content
Snippets Groups Projects
Commit a42fa93f authored by Johannes Mey's avatar Johannes Mey
Browse files

update parser, reference resolution and tests

parent ef29fc1a
Branches
No related tags found
No related merge requests found
...@@ -3,24 +3,79 @@ aspect XMIPathConstruction { ...@@ -3,24 +3,79 @@ aspect XMIPathConstruction {
syn String EModelElement.xmiReference() = xmiPath() + localName(); syn String EModelElement.xmiReference() = xmiPath() + localName();
eq EClass.xmiReference() {
if (getParent() == null) {
if (this == eObject())
return "ecore:EClass http://www.eclipse.org/emf/2002/Ecore#//EObject";
else
throw new RuntimeException("Unable to create reference to EClass " + getName());
} else {
return super.xmiReference();
}
}
eq EDataType.xmiReference() { eq EDataType.xmiReference() {
if (getParent() == null) { if (getParent() == null) {
switch (getName()) { if (this == eInt())
case "EInt": return "ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt";
return "ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EInt"; else if (this == eString())
case "EString": return "ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString";
return "ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"; else if (this == eBoolean())
case "EBoolean": return "ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean";
return "ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"; else if (this == eJavaObject())
case "EJavaObject": return "ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EJavaObject";
return "ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EJavaObject"; else if (this == eEnumerator())
case "EEnumerator": return "ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EEnumerator";
return "ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EEnumerator"; else if (this == eResource())
case "EResource": return "ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EResource";
return "ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EResource"; else if (this == xmlDateTime())
default: return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//DateTime";
throw new RuntimeException("Unable to create reference to EDataType " + getName()); else if (this == xmlBoolean())
} return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//Boolean";
else if (this == xmlByte())
return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//Byte";
else if (this == xmlNormalizedString())
return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//NormalizedString";
else if (this == xmlString())
return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//String";
else if (this == xmlInteger())
return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//Integer";
else if (this == xmlDate())
return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//Date";
else if (this == xmlDecimal())
return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//Decimal";
else if (this == xmlDuration())
return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//Duration";
else if (this == xmlLanguage())
return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//Language";
else if (this == xmlInt())
return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//Int";
else if (this == xmlLong())
return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//Long";
else if (this == xmlAnyURI())
return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//AnyURI";
else if (this == xmlBase64Binary())
return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//Base64Binary";
else if (this == xmlNegativeInteger())
return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//NegativeInteger";
else if (this == xmlNonNegativeInteger())
return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//NonNegativeInteger";
else if (this == xmlNonPositiveInteger())
return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//NonPositiveInteger";
else if (this == xmlToken())
return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//Token";
else if (this == xmlPositiveInteger())
return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//PositiveInteger";
else if (this == xmlShort())
return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//Short";
else if (this == xmlTime())
return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//Time";
else if (this == xmlUnsignedByte())
return "ecore:EDataType http://www.eclipse.org/emf/2003/XMLType#//UnsignedByte";
else
throw new RuntimeException("Unable to create reference to EDataType " + getName());
} else { } else {
return super.xmiReference(); return super.xmiReference();
} }
...@@ -31,7 +86,20 @@ aspect XMIPathConstruction { ...@@ -31,7 +86,20 @@ aspect XMIPathConstruction {
if (getParent() != null) { if (getParent() != null) {
return xmiPath() + localName(); return xmiPath() + localName();
} else { } else {
return "#/"; if (this instanceof EPackage) {
EPackage ePackage = ((EPackage)this);
int numPackages = ePackage.getPackageList().size();
if (numPackages > 1) {
for (int index = 0; index < numPackages; index++) {
if (ePackage.getPackageList().get(index) == this) return "/" + index;
}
throw new RuntimeException("Unable to create reference to EPackage, because it is not in the list of packages.");
} else {
return "#/";
}
} else {
return "#/";
}
} }
} }
......
...@@ -22,6 +22,15 @@ aspect XMIPathResolution { ...@@ -22,6 +22,15 @@ aspect XMIPathResolution {
return (EClassifier) resolve(id); return (EClassifier) resolve(id);
} }
private static EClass EClass.eObject;
public static final EClass EClass.eObject() {
if (eObject == null) {
eObject = new EClass();
eObject.setName("EObject");
}
return eObject;
}
private static EDataType EDataType.eInt; private static EDataType EDataType.eInt;
public static final EDataType EDataType.eInt() { public static final EDataType EDataType.eInt() {
if (eInt == null) { if (eInt == null) {
...@@ -82,11 +91,239 @@ aspect XMIPathResolution { ...@@ -82,11 +91,239 @@ aspect XMIPathResolution {
return eResource; return eResource;
} }
private static EDataType EDataType.xmlDateTime;
public static final EDataType EDataType.xmlDateTime() {
if (xmlDateTime == null) {
xmlDateTime = new EDataType();
xmlDateTime.setInstanceClassName("javax.xml.datatype.XMLGregorianCalendar");
xmlDateTime.setName("DateTime");
}
return xmlDateTime;
}
private static EDataType EDataType.xmlBoolean;
public static final EDataType EDataType.xmlBoolean() {
if (xmlBoolean == null) {
xmlBoolean = new EDataType();
xmlBoolean.setInstanceClassName("boolean");
xmlBoolean.setName("Boolean");
}
return xmlBoolean;
}
private static EDataType EDataType.xmlByte;
public static final EDataType EDataType.xmlByte() {
if (xmlByte == null) {
xmlByte = new EDataType();
xmlByte.setInstanceClassName("byte");
xmlByte.setName("Byte");
}
return xmlBoolean;
}
private static EDataType EDataType.xmlNormalizedString;
public static final EDataType EDataType.xmlNormalizedString() {
if (xmlNormalizedString == null) {
xmlNormalizedString = new EDataType();
xmlNormalizedString.setInstanceClassName("java.lang.String");
xmlNormalizedString.setName("NormalizedString");
}
return xmlNormalizedString;
}
private static EDataType EDataType.xmlString;
public static final EDataType EDataType.xmlString() {
if (xmlString == null) {
xmlString = new EDataType();
xmlString.setInstanceClassName("java.lang.String");
xmlString.setName("String");
}
return xmlString;
}
private static EDataType EDataType.xmlInteger;
public static final EDataType EDataType.xmlInteger() {
if (xmlInteger == null) {
xmlInteger = new EDataType();
xmlInteger.setInstanceClassName("java.lang.Integer");
xmlInteger.setName("Integer");
}
return xmlInteger;
}
private static EDataType EDataType.xmlDate;
public static final EDataType EDataType.xmlDate() {
if (xmlDate == null) {
xmlDate = new EDataType();
xmlDate.setInstanceClassName("javax.xml.datatype.XMLGregorianCalendar");
xmlDate.setName("Date");
}
return xmlDate;
}
private static EDataType EDataType.xmlDecimal;
public static final EDataType EDataType.xmlDecimal() {
if (xmlDecimal == null) {
xmlDecimal = new EDataType();
xmlDecimal.setInstanceClassName("java.math.BigDecimal");
xmlDecimal.setName("Decimal");
}
return xmlDecimal;
}
private static EDataType EDataType.xmlDuration;
public static final EDataType EDataType.xmlDuration() {
if (xmlDuration == null) {
xmlDuration = new EDataType();
xmlDuration.setInstanceClassName("javax.xml.datatype.Duration");
xmlDuration.setName("Duration");
}
return xmlDuration;
}
private static EDataType EDataType.xmlLanguage;
public static final EDataType EDataType.xmlLanguage() {
if (xmlLanguage == null) {
xmlLanguage = new EDataType();
xmlLanguage.setInstanceClassName("java.lang.String");
xmlLanguage.setName("Language");
}
return xmlLanguage;
}
private static EDataType EDataType.xmlInt;
public static final EDataType EDataType.xmlInt() {
if (xmlInt == null) {
xmlInt = new EDataType();
xmlInt.setInstanceClassName("int");
xmlInt.setName("Int");
}
return xmlInt;
}
private static EDataType EDataType.xmlLong;
public static final EDataType EDataType.xmlLong() {
if (xmlLong == null) {
xmlLong = new EDataType();
xmlLong.setInstanceClassName("long");
xmlLong.setName("Long");
}
return xmlLong;
}
private static EDataType EDataType.xmlAnyURI;
public static final EDataType EDataType.xmlAnyURI() {
if (xmlAnyURI == null) {
xmlAnyURI = new EDataType();
xmlAnyURI.setInstanceClassName("java.lang.String");
xmlAnyURI.setName("AnyURI");
}
return xmlAnyURI;
}
private static EDataType EDataType.xmlBase64Binary;
public static final EDataType EDataType.xmlBase64Binary() {
if (xmlBase64Binary == null) {
xmlBase64Binary = new EDataType();
xmlBase64Binary.setInstanceClassName("byte[]");
xmlBase64Binary.setName("Base64Binary");
}
return xmlBase64Binary;
}
private static EDataType EDataType.xmlNegativeInteger;
public static final EDataType EDataType.xmlNegativeInteger() {
if (xmlNegativeInteger == null) {
xmlNegativeInteger = new EDataType();
xmlNegativeInteger.setInstanceClassName("java.math.BigInteger");
xmlNegativeInteger.setName("NegativeInteger");
}
return xmlNegativeInteger;
}
private static EDataType EDataType.xmlNonNegativeInteger;
public static final EDataType EDataType.xmlNonNegativeInteger() {
if (xmlNonNegativeInteger == null) {
xmlNonNegativeInteger = new EDataType();
xmlNonNegativeInteger.setInstanceClassName("java.math.BigInteger");
xmlNonNegativeInteger.setName("NonNegativeInteger");
}
return xmlNonNegativeInteger;
}
private static EDataType EDataType.xmlPositiveInteger;
public static final EDataType EDataType.xmlPositiveInteger() {
if (xmlPositiveInteger == null) {
xmlPositiveInteger = new EDataType();
xmlPositiveInteger.setInstanceClassName("java.math.BigInteger");
xmlPositiveInteger.setName("PositiveInteger");
}
return xmlPositiveInteger;
}
private static EDataType EDataType.xmlNonPositiveInteger;
public static final EDataType EDataType.xmlNonPositiveInteger() {
if (xmlNonPositiveInteger == null) {
xmlNonPositiveInteger = new EDataType();
xmlNonPositiveInteger.setInstanceClassName("java.math.BigInteger");
xmlNonPositiveInteger.setName("NonPositiveInteger");
}
return xmlNonPositiveInteger;
}
private static EDataType EDataType.xmlToken;
public static final EDataType EDataType.xmlToken() {
if (xmlToken == null) {
xmlToken = new EDataType();
xmlToken.setInstanceClassName("java.lang.String");
xmlToken.setName("Token");
}
return xmlToken;
}
private static EDataType EDataType.xmlShort;
public static final EDataType EDataType.xmlShort() {
if (xmlShort == null) {
xmlShort = new EDataType();
xmlShort.setInstanceClassName("short");
xmlShort.setName("Short");
}
return xmlShort;
}
private static EDataType EDataType.xmlTime;
public static final EDataType EDataType.xmlTime() {
if (xmlTime == null) {
xmlTime = new EDataType();
xmlTime.setInstanceClassName("javax.xml.datatype.XMLGregorianCalendar");
xmlTime.setName("Time");
}
return xmlTime;
}
private static EDataType EDataType.xmlUnsignedByte;
public static final EDataType EDataType.xmlUnsignedByte() {
if (xmlUnsignedByte == null) {
xmlUnsignedByte = new EDataType();
xmlUnsignedByte.setInstanceClassName("short");
xmlUnsignedByte.setName("UnsignedByte");
}
return xmlUnsignedByte;
}
syn ASTNode ASTNode.resolve(String uriString) { syn ASTNode ASTNode.resolve(String uriString) {
// built-in data types // built-in data types
if (uriString.startsWith("ecore:EDataType ")) { if (uriString.startsWith("ecore:EClass ")) {
switch (uriString.substring(13)) {
case "http://www.eclipse.org/emf/2002/Ecore#//EObject":
return EClass.eObject();
default:
throw new RuntimeException("Unable to resolve built-in class '" + uriString + "'");
}
} else if (uriString.startsWith("ecore:EDataType ")) {
switch (uriString.substring(16)) { switch (uriString.substring(16)) {
case "http://www.eclipse.org/emf/2002/Ecore#//EObject":
case "http://www.eclipse.org/emf/2002/Ecore#//EInt": case "http://www.eclipse.org/emf/2002/Ecore#//EInt":
return EDataType.eInt(); return EDataType.eInt();
case "http://www.eclipse.org/emf/2002/Ecore#//EString": case "http://www.eclipse.org/emf/2002/Ecore#//EString":
...@@ -99,6 +336,48 @@ aspect XMIPathResolution { ...@@ -99,6 +336,48 @@ aspect XMIPathResolution {
return EDataType.eEnumerator(); return EDataType.eEnumerator();
case "http://www.eclipse.org/emf/2002/Ecore#//EResource": case "http://www.eclipse.org/emf/2002/Ecore#//EResource":
return EDataType.eResource(); return EDataType.eResource();
case "http://www.eclipse.org/emf/2003/XMLType#//DateTime":
return EDataType.xmlDateTime();
case "http://www.eclipse.org/emf/2003/XMLType#//Boolean":
return EDataType.xmlBoolean();
case "http://www.eclipse.org/emf/2003/XMLType#//Byte":
return EDataType.xmlByte();
case "http://www.eclipse.org/emf/2003/XMLType#//Integer":
return EDataType.xmlInteger();
case "http://www.eclipse.org/emf/2003/XMLType#//Date":
return EDataType.xmlDate();
case "http://www.eclipse.org/emf/2003/XMLType#//Decimal":
return EDataType.xmlDecimal();
case "http://www.eclipse.org/emf/2003/XMLType#//Duration":
return EDataType.xmlDuration();
case "http://www.eclipse.org/emf/2003/XMLType#//Language":
return EDataType.xmlLanguage();
case "http://www.eclipse.org/emf/2003/XMLType#//Int":
return EDataType.xmlInt();
case "http://www.eclipse.org/emf/2003/XMLType#//Long":
return EDataType.xmlLong();
case "http://www.eclipse.org/emf/2003/XMLType#//AnyURI":
return EDataType.xmlAnyURI();
case "http://www.eclipse.org/emf/2003/XMLType#//Base64Binary":
return EDataType.xmlBase64Binary();
case "http://www.eclipse.org/emf/2003/XMLType#//NegativeInteger":
return EDataType.xmlNegativeInteger();
case "http://www.eclipse.org/emf/2003/XMLType#//NonNegativeInteger":
return EDataType.xmlNonNegativeInteger();
case "http://www.eclipse.org/emf/2003/XMLType#//NonPositiveInteger":
return EDataType.xmlNonPositiveInteger();
case "http://www.eclipse.org/emf/2003/XMLType#//Token":
return EDataType.xmlToken();
case "http://www.eclipse.org/emf/2003/XMLType#//PositiveInteger":
return EDataType.xmlPositiveInteger();
case "http://www.eclipse.org/emf/2003/XMLType#//Short":
return EDataType.xmlShort();
case "http://www.eclipse.org/emf/2003/XMLType#//UnsignedByte":
return EDataType.xmlUnsignedByte();
case "http://www.eclipse.org/emf/2003/XMLType#//NormalizedString":
return EDataType.xmlNormalizedString();
case "http://www.eclipse.org/emf/2003/XMLType#//String":
return EDataType.xmlString();
default: default:
throw new RuntimeException("Unable to resolve built-in data type '" + uriString + "'"); throw new RuntimeException("Unable to resolve built-in data type '" + uriString + "'");
} }
...@@ -158,7 +437,19 @@ aspect XMIPathResolution { ...@@ -158,7 +437,19 @@ aspect XMIPathResolution {
syn ASTNode ASTNode.resolvePathRootFragment(String fragment) { syn ASTNode ASTNode.resolvePathRootFragment(String fragment) {
// This method is only relevant if there are multiple roots, and in this case, in general, it is not possible to // This method is only relevant if there are multiple roots, and in this case, in general, it is not possible to
// select the right one (because we cannot navigate to them) // select the right one (because we cannot navigate to them)
return root();
ASTNode root = root();
if (root instanceof EPackage) {
EPackage ownPackage = (EPackage) root;
if (ownPackage.getPackageList().size() == 1) {
return root;
} else {
return ownPackage.getPackageList().get(Integer.valueOf(fragment));
}
} else {
return root;
}
} }
syn ASTNode ASTNode.resolvePathFragment(String fragment) { syn ASTNode ASTNode.resolvePathFragment(String fragment) {
...@@ -257,7 +548,7 @@ aspect XMIPathResolution { ...@@ -257,7 +548,7 @@ aspect XMIPathResolution {
} }
} }
throw new RuntimeException("Unable to find number '" + index + "'child with name '" + name + "'"); throw new RuntimeException("Unable to find child number '" + index + "' with name '" + name + "'");
} }
// public static String getID(EObject eObject) { // public static String getID(EObject eObject) {
......
...@@ -7,20 +7,38 @@ aspect XMIWriter { ...@@ -7,20 +7,38 @@ aspect XMIWriter {
} }
public void EPackage.writeXMI(StringBuilder b) { public void EPackage.writeXMI(StringBuilder b) {
b.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"); writeXMI(b, "UTF-8");
this.writeXMI(b, null, 0);
} }
void ASTNode.startXMIElement(StringBuilder b, String type, String context) { public void EPackage.writeXMI(StringBuilder b, String encoding) {
b.append("<?xml version=\"1.0\" encoding=\"" + encoding + "\"?>\n");
if (getPackageList().size() > 1) {
b.append("<xmi:XMI xmi:version=\"2.0\"" +
" xmlns:xmi=\"http://www.omg.org/XMI\"" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
" xmlns:ecore=\"http://www.eclipse.org/emf/2002/Ecore\">\n");
for (EPackage p : getPackageList()) {
p.writeXMI(b, null, 1, false, false);
}
b.append("</xmi:XMI>\n");
} else {
this.writeXMI(b, null, 0, true, false);
}
}
void ASTNode.startXMIElement(StringBuilder b, String type, String context, boolean topLevel, boolean requiresType) {
if (context == null) { if (context == null) {
// we have a top-level element that is not contained in anything b.append(type);
b.append(type).append(" xmi:version=\"2.0\"" + if (topLevel) {
" xmlns:xmi=\"http://www.omg.org/XMI\"" + // we have a top-level element that is not contained in anything
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" + b.append(" xmi:version=\"2.0\"" +
" xmlns:ecore=\"http://www.eclipse.org/emf/2002/Ecore\""); " xmlns:xmi=\"http://www.omg.org/XMI\"" +
" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"" +
" xmlns:ecore=\"http://www.eclipse.org/emf/2002/Ecore\"");
}
} else { } else {
b.append(context); b.append(context);
if (!"".equals(type)) { if (requiresType) {
// TODO whether to print the type can be determined by static analysis! // TODO whether to print the type can be determined by static analysis!
b.append(" xsi:type=\"").append(type).append("\""); b.append(" xsi:type=\"").append(type).append("\"");
} }
...@@ -31,17 +49,22 @@ aspect XMIWriter { ...@@ -31,17 +49,22 @@ aspect XMIWriter {
b.append((context == null) ? type : context); b.append((context == null) ? type : context);
} }
void EPackage.writeXMI(StringBuilder b, String context, int indentationLevel) { void EPackage.writeXMI(StringBuilder b, String context, int indentationLevel, boolean topLevel, boolean requiresType) {
// opening tag // opening tag
b.append(indentString(indentationLevel)).append("<"); b.append(indentString(indentationLevel)).append("<");
startXMIElement(b, "ecore:EPackage", context); startXMIElement(b, "ecore:EPackage", context, topLevel, requiresType);
// attributes // attributes
// from ENamedElement // from ENamedElement
b.append(" name=\"").append(getName()).append("\""); b.append(" name=\"").append(getName()).append("\"");
// from EPackage // from EPackage
b.append(" nsURI=\"").append(getNsURI()).append("\"") if (getNsURI() != null && !getNsURI().equals("")) {
.append(" nsPrefix=\"").append(getNsPrefix()).append("\""); b.append(" nsURI=\"").append(getNsURI()).append("\"");
}
if (getNsPrefix() != null && !getNsPrefix().equals("")) {
b.append(" nsPrefix=\"").append(getNsPrefix()).append("\"");
}
if (numContainedChildren() == 0) { if (numContainedChildren() == 0) {
b.append("/>\n"); b.append("/>\n");
return; return;
...@@ -51,14 +74,14 @@ aspect XMIWriter { ...@@ -51,14 +74,14 @@ aspect XMIWriter {
// child nodes // child nodes
// from EModelElement // from EModelElement
for (EAnnotation eAnnotation : getEAnnotationList()) { for (EAnnotation eAnnotation : getEAnnotationList()) {
eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1); eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1, false, false);
} }
// from EPackage // from EPackage
for (EClassifier eClassifier : getEClassifierList()) { for (EClassifier eClassifier : getEClassifierList()) {
eClassifier.writeXMI(b, "eClassifiers", indentationLevel + 1); eClassifier.writeXMI(b, "eClassifiers", indentationLevel + 1, false, true);
} }
for (EPackage eSubpackage : getESubPackageList()) { for (EPackage eSubpackage : getESubPackageList()) {
eSubpackage.writeXMI(b, "eSubpackages", indentationLevel + 1); eSubpackage.writeXMI(b, "eSubpackages", indentationLevel + 1, false, false);
} }
// closing tag // closing tag
...@@ -67,11 +90,11 @@ aspect XMIWriter { ...@@ -67,11 +90,11 @@ aspect XMIWriter {
b.append(">\n"); b.append(">\n");
} }
abstract void EClassifier.writeXMI(StringBuilder b, String context, int indentationLevel); abstract void EClassifier.writeXMI(StringBuilder b, String context, int indentationLevel, boolean topLevel, boolean requiresType);
void EClass.writeXMI(StringBuilder b, String context, int indentationLevel) { void EClass.writeXMI(StringBuilder b, String context, int indentationLevel, boolean topLevel, boolean requiresType) {
b.append(indentString(indentationLevel)).append("<"); b.append(indentString(indentationLevel)).append("<");
startXMIElement(b, "ecore:EClass", context); startXMIElement(b, "ecore:EClass", context, topLevel, requiresType);
// attributes // attributes
// from ENamedElement // from ENamedElement
b.append(" name=\"").append(getName()).append("\""); b.append(" name=\"").append(getName()).append("\"");
...@@ -108,21 +131,21 @@ aspect XMIWriter { ...@@ -108,21 +131,21 @@ aspect XMIWriter {
// child nodes // child nodes
// from EModelElement // from EModelElement
for (EAnnotation eAnnotation : getEAnnotationList()) { for (EAnnotation eAnnotation : getEAnnotationList()) {
eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1); eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1, false, false);
} }
// from EClassifier // from EClassifier
for (ETypeParameter eTypeParameter : getETypeParameterList()) { for (ETypeParameter eTypeParameter : getETypeParameterList()) {
eTypeParameter.writeXMI(b, "eTypeParameters", indentationLevel + 1); eTypeParameter.writeXMI(b, "eTypeParameters", indentationLevel + 1, false, false);
} }
// from EClass // from EClass
for (EOperation eOperation : getEOperationList()) { for (EOperation eOperation : getEOperationList()) {
eOperation.writeXMI(b, "eOperations", indentationLevel + 1); eOperation.writeXMI(b, "eOperations", indentationLevel + 1, false, false);
} }
for (EStructuralFeature eStructuralFeature : getEStructuralFeatureList()) { for (EStructuralFeature eStructuralFeature : getEStructuralFeatureList()) {
eStructuralFeature.writeXMI(b, "eStructuralFeatures", indentationLevel + 1); eStructuralFeature.writeXMI(b, "eStructuralFeatures", indentationLevel + 1, false, true);
} }
for (EGenericType eGenericSuperType : getEGenericSuperTypeList()) { for (EGenericType eGenericSuperType : getEGenericSuperTypeList()) {
eGenericSuperType.writeXMI(b, "eGenericSuperTypes", indentationLevel + 1); eGenericSuperType.writeXMI(b, "eGenericSuperTypes", indentationLevel + 1, false, false);
} }
// closing tag // closing tag
...@@ -131,9 +154,9 @@ aspect XMIWriter { ...@@ -131,9 +154,9 @@ aspect XMIWriter {
b.append(">\n"); b.append(">\n");
} }
void EDataType.writeXMI(StringBuilder b, String context, int indentationLevel) { void EDataType.writeXMI(StringBuilder b, String context, int indentationLevel, boolean topLevel, boolean requiresType) {
b.append(indentString(indentationLevel)).append("<"); b.append(indentString(indentationLevel)).append("<");
startXMIElement(b, "ecore:EDataType", context); startXMIElement(b, "ecore:EDataType", context, topLevel, requiresType);
// attributes // attributes
b.append(" name=\"").append(getName()).append("\""); b.append(" name=\"").append(getName()).append("\"");
// from EClassifier // from EClassifier
...@@ -154,11 +177,11 @@ aspect XMIWriter { ...@@ -154,11 +177,11 @@ aspect XMIWriter {
// child nodes // child nodes
// from EModelElement // from EModelElement
for (EAnnotation eAnnotation : getEAnnotationList()) { for (EAnnotation eAnnotation : getEAnnotationList()) {
eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1); eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1, false, false);
} }
// from EClassifier // from EClassifier
for (ETypeParameter eTypeParameter : getETypeParameterList()) { for (ETypeParameter eTypeParameter : getETypeParameterList()) {
eTypeParameter.writeXMI(b, "eTypeParameters", indentationLevel + 1); eTypeParameter.writeXMI(b, "eTypeParameters", indentationLevel + 1, false, false);
} }
// closing tag // closing tag
...@@ -167,9 +190,78 @@ aspect XMIWriter { ...@@ -167,9 +190,78 @@ aspect XMIWriter {
b.append(">\n"); b.append(">\n");
} }
void EGenericType.writeXMI(StringBuilder b, String context, int indentationLevel) { void EEnum.writeXMI(StringBuilder b, String context, int indentationLevel, boolean topLevel, boolean requiresType) {
b.append(indentString(indentationLevel)).append("<");
startXMIElement(b, "ecore:EEnum", context, topLevel, requiresType);
// attributes
b.append(" name=\"").append(getName()).append("\"");
// from EClassifier
if (getInstanceClassName() != "") {
b.append(" instanceClassName=\"").append(getInstanceClassName()).append("\"");
}
// from EDataType
if (getSerializable() == false) {
b.append(" serializable=\"false\"");
}
if (numContainedChildren() == 0) {
b.append("/>\n");
return;
}
b.append(">\n");
// child nodes
// from EModelElement
for (EAnnotation eAnnotation : getEAnnotationList()) {
eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1, false, false);
}
// from EClassifier
for (ETypeParameter eTypeParameter : getETypeParameterList()) {
eTypeParameter.writeXMI(b, "eTypeParameters", indentationLevel + 1, false, false);
}
// from EEnum
for (EEnumLiteral eLiteral : getELiteralList()) {
eLiteral.writeXMI(b, "eLiterals", indentationLevel + 1, false, false);
}
// closing tag
b.append(indentString(indentationLevel)).append("</");
endXMIElement(b, "ecore:EEnum", context);
b.append(">\n");
}
void EEnumLiteral.writeXMI(StringBuilder b, String context, int indentationLevel, boolean topLevel, boolean requiresType) {
b.append(indentString(indentationLevel)).append("<");
startXMIElement(b, "", context, topLevel, requiresType);
// attributes
// from ENamedElement
if (getName() != null && !getName().equals("")) {
b.append(" name=\"").append(getName()).append("\"");
}
// from ENamedElement
b.append(" value=\"").append(getValue()).append("\"");
if (numContainedChildren() == 0) {
b.append("/>\n");
return;
}
b.append(">\n");
// child nodes
// from EModelElement
for (EAnnotation eAnnotation : getEAnnotationList()) {
eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1, false, false);
}
// closing tag
b.append(indentString(indentationLevel)).append("</");
endXMIElement(b, "", context);
b.append(">\n");
}
void EGenericType.writeXMI(StringBuilder b, String context, int indentationLevel, boolean topLevel, boolean requiresType) {
b.append(indentString(indentationLevel)).append("<"); b.append(indentString(indentationLevel)).append("<");
startXMIElement(b, "", context); startXMIElement(b, "", context, topLevel, requiresType);
// attributes // attributes
if (hasETypeParameter()) { if (hasETypeParameter()) {
b.append(" eTypeParameter=\"").append(getETypeParameter().xmiReference()).append("\""); b.append(" eTypeParameter=\"").append(getETypeParameter().xmiReference()).append("\"");
...@@ -185,13 +277,13 @@ aspect XMIWriter { ...@@ -185,13 +277,13 @@ aspect XMIWriter {
// child nodes // child nodes
// from EGenericType // from EGenericType
if (hasEUpperBound()) { if (hasEUpperBound()) {
getEUpperBound().writeXMI(b, "eUpperBound", indentationLevel + 1); getEUpperBound().writeXMI(b, "eUpperBound", indentationLevel + 1, false, false);
} }
if (hasELowerBound()) { if (hasELowerBound()) {
getELowerBound().writeXMI(b, "eLowerBound", indentationLevel + 1); getELowerBound().writeXMI(b, "eLowerBound", indentationLevel + 1, false, false);
} }
for (EGenericType eTypeArgument : getETypeArgumentList()) { for (EGenericType eTypeArgument : getETypeArgumentList()) {
eTypeArgument.writeXMI(b, "eTypeArguments", indentationLevel + 1); eTypeArgument.writeXMI(b, "eTypeArguments", indentationLevel + 1, false, false);
} }
// closing tag // closing tag
...@@ -200,9 +292,9 @@ aspect XMIWriter { ...@@ -200,9 +292,9 @@ aspect XMIWriter {
b.append(">\n"); b.append(">\n");
} }
void EOperation.writeXMI(StringBuilder b, String context, int indentationLevel) { void EOperation.writeXMI(StringBuilder b, String context, int indentationLevel, boolean topLevel, boolean requiresType) {
b.append(indentString(indentationLevel)).append("<"); b.append(indentString(indentationLevel)).append("<");
startXMIElement(b, "", context); startXMIElement(b, "", context, topLevel, requiresType);
// attributes // attributes
// from ENamedElement // from ENamedElement
b.append(" name=\"").append(getName()).append("\""); b.append(" name=\"").append(getName()).append("\"");
...@@ -234,21 +326,21 @@ aspect XMIWriter { ...@@ -234,21 +326,21 @@ aspect XMIWriter {
// child nodes // child nodes
// from EModelElement // from EModelElement
for (EAnnotation eAnnotation : getEAnnotationList()) { for (EAnnotation eAnnotation : getEAnnotationList()) {
eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1); eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1, false, false);
} }
// from ETypedElement // from ETypedElement
if (hasEGenericType()) { if (hasEGenericType()) {
getEGenericType().writeXMI(b, "eGenericType", indentationLevel + 1); getEGenericType().writeXMI(b, "eGenericType", indentationLevel + 1, false, false);
} }
// from EOperation // from EOperation
for (EGenericType eGenericException : getEGenericExceptionList()) { for (EGenericType eGenericException : getEGenericExceptionList()) {
eGenericException.writeXMI(b, "eGenericExceptions", indentationLevel + 1); eGenericException.writeXMI(b, "eGenericExceptions", indentationLevel + 1, false, false);
} }
for (ETypeParameter eTypeParameter : getETypeParameterList()) { for (ETypeParameter eTypeParameter : getETypeParameterList()) {
eTypeParameter.writeXMI(b, "eTypeParameters", indentationLevel + 1); eTypeParameter.writeXMI(b, "eTypeParameters", indentationLevel + 1, false, false);
} }
for (EParameter eParameter : getEParameterList()) { for (EParameter eParameter : getEParameterList()) {
eParameter.writeXMI(b, "eParameters", indentationLevel + 1); eParameter.writeXMI(b, "eParameters", indentationLevel + 1, false, false);
} }
// closing tag // closing tag
...@@ -257,9 +349,9 @@ aspect XMIWriter { ...@@ -257,9 +349,9 @@ aspect XMIWriter {
b.append(">\n"); b.append(">\n");
} }
void EParameter.writeXMI(StringBuilder b, String context, int indentationLevel) { void EParameter.writeXMI(StringBuilder b, String context, int indentationLevel, boolean topLevel, boolean requiresType) {
b.append(indentString(indentationLevel)).append("<"); b.append(indentString(indentationLevel)).append("<");
startXMIElement(b, "", context); startXMIElement(b, "", context, topLevel, requiresType);
// attributes // attributes
// from ENamedElement // from ENamedElement
b.append(" name=\"").append(getName()).append("\""); b.append(" name=\"").append(getName()).append("\"");
...@@ -287,11 +379,11 @@ aspect XMIWriter { ...@@ -287,11 +379,11 @@ aspect XMIWriter {
// child nodes // child nodes
// from EModelElement // from EModelElement
for (EAnnotation eAnnotation : getEAnnotationList()) { for (EAnnotation eAnnotation : getEAnnotationList()) {
eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1); eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1, false, false);
} }
// from ETypedElement // from ETypedElement
if (hasEGenericType()) { if (hasEGenericType()) {
getEGenericType().writeXMI(b, "eGenericType", indentationLevel + 1); getEGenericType().writeXMI(b, "eGenericType", indentationLevel + 1, false, false);
} }
// closing tag // closing tag
...@@ -301,11 +393,11 @@ aspect XMIWriter { ...@@ -301,11 +393,11 @@ aspect XMIWriter {
} }
abstract void EStructuralFeature.writeXMI(StringBuilder b, String context, int indentationLevel); abstract void EStructuralFeature.writeXMI(StringBuilder b, String context, int indentationLevel, boolean topLevel, boolean requiresType);
void EReference.writeXMI(StringBuilder b, String context, int indentationLevel) { void EReference.writeXMI(StringBuilder b, String context, int indentationLevel, boolean topLevel, boolean requiresType) {
b.append(indentString(indentationLevel)).append("<"); b.append(indentString(indentationLevel)).append("<");
startXMIElement(b, "ecore:EReference", context); startXMIElement(b, "ecore:EReference", context, topLevel, requiresType);
// attributes // attributes
// from ENamedElement // from ENamedElement
b.append(" name=\"").append(getName()).append("\""); b.append(" name=\"").append(getName()).append("\"");
...@@ -362,11 +454,11 @@ aspect XMIWriter { ...@@ -362,11 +454,11 @@ aspect XMIWriter {
// child nodes // child nodes
// from EModelElement // from EModelElement
for (EAnnotation eAnnotation : getEAnnotationList()) { for (EAnnotation eAnnotation : getEAnnotationList()) {
eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1); eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1, false, false);
} }
// from ETypedElement // from ETypedElement
if (hasEGenericType()) { if (hasEGenericType()) {
getEGenericType().writeXMI(b, "eGenericType", indentationLevel + 1); getEGenericType().writeXMI(b, "eGenericType", indentationLevel + 1, false, false);
} }
// closing tag // closing tag
...@@ -375,9 +467,9 @@ aspect XMIWriter { ...@@ -375,9 +467,9 @@ aspect XMIWriter {
b.append(">\n"); b.append(">\n");
} }
void EAttribute.writeXMI(StringBuilder b, String context, int indentationLevel) { void EAttribute.writeXMI(StringBuilder b, String context, int indentationLevel, boolean topLevel, boolean requiresType) {
b.append(indentString(indentationLevel)).append("<"); b.append(indentString(indentationLevel)).append("<");
startXMIElement(b, "ecore:EAttribute", context); startXMIElement(b, "ecore:EAttribute", context, topLevel, requiresType);
// attributes // attributes
// from ENamedElement // from ENamedElement
b.append(" name=\"").append(getName()).append("\""); b.append(" name=\"").append(getName()).append("\"");
...@@ -428,11 +520,11 @@ aspect XMIWriter { ...@@ -428,11 +520,11 @@ aspect XMIWriter {
// child nodes // child nodes
// from EModelElement // from EModelElement
for (EAnnotation eAnnotation : getEAnnotationList()) { for (EAnnotation eAnnotation : getEAnnotationList()) {
eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1); eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1, false, false);
} }
// from ETypedElement // from ETypedElement
if (hasEGenericType()) { if (hasEGenericType()) {
getEGenericType().writeXMI(b, "eGenericType", indentationLevel + 1); getEGenericType().writeXMI(b, "eGenericType", indentationLevel + 1, false, false);
} }
// closing tag // closing tag
...@@ -441,9 +533,9 @@ aspect XMIWriter { ...@@ -441,9 +533,9 @@ aspect XMIWriter {
b.append(">\n"); b.append(">\n");
} }
void EAnnotation.writeXMI(StringBuilder b, String context, int indentationLevel) { void EAnnotation.writeXMI(StringBuilder b, String context, int indentationLevel, boolean topLevel, boolean requiresType) {
b.append(indentString(indentationLevel)).append("<"); b.append(indentString(indentationLevel)).append("<");
startXMIElement(b, "", context); startXMIElement(b, "", context, topLevel, requiresType);
// attributes // attributes
b.append(" source=\"").append(getSource()).append("\""); b.append(" source=\"").append(getSource()).append("\"");
...@@ -454,7 +546,7 @@ aspect XMIWriter { ...@@ -454,7 +546,7 @@ aspect XMIWriter {
b.append(">\n"); b.append(">\n");
// child nodes // child nodes
for (EStringToStringMapEntry detail : getDetailList()) { for (EStringToStringMapEntry detail : getDetailList()) {
detail.writeXMI(b, "details", indentationLevel + 1); detail.writeXMI(b, "details", indentationLevel + 1, false, false);
} }
// closing tag // closing tag
...@@ -463,9 +555,9 @@ aspect XMIWriter { ...@@ -463,9 +555,9 @@ aspect XMIWriter {
b.append(">\n"); b.append(">\n");
} }
void EStringToStringMapEntry.writeXMI(StringBuilder b, String context, int indentationLevel) { void EStringToStringMapEntry.writeXMI(StringBuilder b, String context, int indentationLevel, boolean topLevel, boolean requiresType) {
b.append(indentString(indentationLevel)).append("<"); b.append(indentString(indentationLevel)).append("<");
startXMIElement(b, "", context); startXMIElement(b, "", context, topLevel, requiresType);
// attributes // attributes
b.append(" key=\"").append(getKey()).append("\""); b.append(" key=\"").append(getKey()).append("\"");
b.append(" value=\"").append(getValue()).append("\""); b.append(" value=\"").append(getValue()).append("\"");
...@@ -473,9 +565,9 @@ aspect XMIWriter { ...@@ -473,9 +565,9 @@ aspect XMIWriter {
b.append("/>\n"); b.append("/>\n");
} }
void ETypeParameter.writeXMI(StringBuilder b, String context, int indentationLevel) { void ETypeParameter.writeXMI(StringBuilder b, String context, int indentationLevel, boolean topLevel, boolean requiresType) {
b.append(indentString(indentationLevel)).append("<"); b.append(indentString(indentationLevel)).append("<");
startXMIElement(b, "", context); startXMIElement(b, "", context, topLevel, requiresType);
// attributes // attributes
// from ENamedElement // from ENamedElement
b.append(" name=\"").append(getName()).append("\""); b.append(" name=\"").append(getName()).append("\"");
...@@ -487,11 +579,11 @@ aspect XMIWriter { ...@@ -487,11 +579,11 @@ aspect XMIWriter {
// child nodes // child nodes
// from EModelElement // from EModelElement
for (EAnnotation eAnnotation : getEAnnotationList()) { for (EAnnotation eAnnotation : getEAnnotationList()) {
eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1); eAnnotation.writeXMI(b, "eAnnotations", indentationLevel + 1, false, false);
} }
// from ETypeParameter // from ETypeParameter
for (EGenericType eGenericType : getEBoundList()) { for (EGenericType eGenericType : getEBoundList()) {
eGenericType.writeXMI(b, "eTypeParameters", indentationLevel + 1); eGenericType.writeXMI(b, "eTypeParameters", indentationLevel + 1, false, false);
} }
// closing tag // closing tag
......
...@@ -14,10 +14,7 @@ import javax.xml.stream.events.Namespace; ...@@ -14,10 +14,7 @@ import javax.xml.stream.events.Namespace;
import javax.xml.stream.events.StartElement; import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent; import javax.xml.stream.events.XMLEvent;
import java.io.InputStream; import java.io.InputStream;
import java.util.Collections; import java.util.*;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class EcoreParser { public class EcoreParser {
...@@ -27,7 +24,7 @@ public class EcoreParser { ...@@ -27,7 +24,7 @@ public class EcoreParser {
private static Logger logger = LogManager.getLogger(EcoreParser.class); private static Logger logger = LogManager.getLogger(EcoreParser.class);
private final XMLInputFactory factory = XMLInputFactory.newInstance(); private final XMLInputFactory factory = XMLInputFactory.newInstance();
public EObject parse(InputStream stream) throws XMIParseException { public List<EObject> parse(InputStream stream) throws XMIParseException {
try { try {
final XMLEventReader reader = factory.createXMLEventReader(stream); final XMLEventReader reader = factory.createXMLEventReader(stream);
...@@ -43,8 +40,12 @@ public class EcoreParser { ...@@ -43,8 +40,12 @@ public class EcoreParser {
StartElement root = event.asStartElement(); StartElement root = event.asStartElement();
switch (root.getName().getLocalPart()) { switch (root.getName().getLocalPart()) {
case "XMI":
return parseXMI(reader, Collections.EMPTY_MAP);
case "EPackage": case "EPackage":
return parseEPackage(reader, Collections.EMPTY_MAP); EPackage ePackage = parseEPackage(reader, Collections.EMPTY_MAP);
ePackage.addPackage(ePackage);
return Collections.singletonList(ePackage);
default: default:
throw new XMIParseException("Unable to parse root element " + root.getName().toString()); throw new XMIParseException("Unable to parse root element " + root.getName().toString());
} }
...@@ -75,6 +76,76 @@ public class EcoreParser { ...@@ -75,6 +76,76 @@ public class EcoreParser {
return result; return result;
} }
private List<EPackage> parseXMI(final XMLEventReader reader, Map<String, String> nameSpaces) throws XMLStreamException {
List<EPackage> contents = new ArrayList<>();
// get all the properties out of the element
StartElement startElement = reader.nextEvent().asStartElement();
nameSpaces = parseNameSpaces(startElement, nameSpaces);
for (Iterator attributeIterator = startElement.getAttributes(); attributeIterator.hasNext(); ) {
Attribute attribute = (Attribute) attributeIterator.next();
switch (attribute.getName().getLocalPart()) {
default:
logger.warn("ignoring attribute {}:{}", attribute.getName().getPrefix(), attribute.getName().getLocalPart());
}
}
// parse the contained elements
while (reader.hasNext()) {
XMLEvent nextEvent = reader.peek();
// logger.debug("looking at ({}:{}) :'{};.", nextEvent.getLocation().getLineNumber(), nextEvent.getLocation().getColumnNumber(), nextEvent);
if (nextEvent.isStartElement()) {
if (nextEvent.isStartDocument()) {
reader.nextEvent();
} else if (nextEvent.isStartElement()) {
StartElement root = nextEvent.asStartElement();
switch (root.getName().getLocalPart()) {
case "EPackage":
contents.add(parseEPackage(reader, Collections.EMPTY_MAP));
break;
default:
throw new XMIParseException("Unable to parse root element " + root.getName().toString());
}
} else {
logger.error("the element is a {}", nextEvent.getEventType());
throw new XMIParseException("Element is not a start element!");
}
} else if (nextEvent.isEndElement() && nextEvent.asEndElement().getName().equals(startElement.getName())) {
reader.nextEvent();
for (EPackage ePackage: contents) {
for (EPackage sibling : contents) {
ePackage.addPackage(sibling);
}
}
return contents;
} else {
// ignore all other events
if (nextEvent.getEventType() != XMLStreamConstants.CHARACTERS)
logger.warn("ignoring event at ({}:{}) {}", nextEvent.getLocation().getLineNumber(), nextEvent.getLocation().getColumnNumber(), nextEvent);
reader.nextEvent();
}
}
// TODO throw exception
for (EPackage ePackage: contents) {
for (EPackage sibling : contents) {
ePackage.addPackage(sibling);
}
}
return contents;
}
private EPackage parseEPackage(final XMLEventReader reader, Map<String, String> nameSpaces) throws XMLStreamException { private EPackage parseEPackage(final XMLEventReader reader, Map<String, String> nameSpaces) throws XMLStreamException {
EPackage ePackage = new EPackage(); EPackage ePackage = new EPackage();
...@@ -115,6 +186,10 @@ public class EcoreParser { ...@@ -115,6 +186,10 @@ public class EcoreParser {
case "eAnnotations": case "eAnnotations":
ePackage.addEAnnotation(parseEAnnotation(reader, nameSpaces)); ePackage.addEAnnotation(parseEAnnotation(reader, nameSpaces));
break; break;
// from EPackage
case "eSubpackages":
ePackage.addESubPackage(parseEPackage(reader, nameSpaces));
break;
default: default:
logger.warn("ignoring element at ({}:{}) {}:{}", nextEvent.getLocation().getLineNumber(), nextEvent.getLocation().getColumnNumber(), nextElement.getName().getPrefix(), nextElement.getName().getLocalPart()); logger.warn("ignoring element at ({}:{}) {}:{}", nextEvent.getLocation().getLineNumber(), nextEvent.getLocation().getColumnNumber(), nextElement.getName().getPrefix(), nextElement.getName().getLocalPart());
} }
...@@ -378,9 +453,142 @@ public class EcoreParser { ...@@ -378,9 +453,142 @@ public class EcoreParser {
} }
} }
private EClassifier parseEEnum(final XMLEventReader reader, Map<String, String> nameSpaces) throws XMLStreamException { private EEnum parseEEnum(final XMLEventReader reader, Map<String, String> nameSpaces) throws XMLStreamException {
// TODO implement
return null; EEnum eEnum = new EEnum();
// set default values
eEnum.setSerializable(true);
// get all the properties out of the element
StartElement startElement = reader.nextEvent().asStartElement();
nameSpaces = parseNameSpaces(startElement, nameSpaces);
for (Iterator attributeIterator = startElement.getAttributes(); attributeIterator.hasNext(); ) {
Attribute attribute = (Attribute) attributeIterator.next();
if (attribute.getName().equals(XSI_TYPE)) {
if (!attribute.getValue().equals("ecore:EEnum")) {
throw new XMIParseException("Expected ecore:EEnum but found " + attribute.getValue(), attribute.getLocation());
}
} else {
switch (attribute.getName().getLocalPart()) {
// from ENamedElement
case "name":
eEnum.setName(attribute.getValue());
break;
// from EClassifier
case "instanceClassName":
eEnum.setInstanceClassName(attribute.getValue());
break;
case "instanceClass":
logger.warn("ignoring transient attribute 'instanceClass' with value '{}'", attribute.getValue());
break;
case "defaultValue":
logger.warn("ignoring transient attribute 'defaultValue' with value '{}'", attribute.getValue());
break;
case "ePackage":
logger.warn("ignoring parent relation 'ePackage' with value '{}'", attribute.getValue());
break;
// from EDataType
case "serializable":
eEnum.setSerializable(Boolean.valueOf(attribute.getValue()));
break;
default:
logger.warn("ignoring attribute {}:{}", attribute.getName().getPrefix(), attribute.getName().getLocalPart());
}
}
}
// parse the contained elements
XMLEvent nextEvent = reader.peek();
while (true) {
if (nextEvent.isStartElement()) {
final StartElement nextElement = nextEvent.asStartElement();
switch (nextElement.getName().getLocalPart()) {
case "eTypeParameters":
eEnum.addETypeParameter(parseETypeParameter(reader, nameSpaces));
break;
case "eAnnotations":
eEnum.addEAnnotation(parseEAnnotation(reader, nameSpaces));
break;
case "eLiterals":
eEnum.addELiteral(parseEEnumLiteral(reader, nameSpaces));
break;
default:
logger.warn("ignoring element {}:{}", nextElement.getName().getPrefix(), nextElement.getName().getLocalPart());
}
} else if (nextEvent.isEndElement() && nextEvent.asEndElement().getName().equals(startElement.getName())) {
reader.nextEvent();
return eEnum;
} else {
// ignore all other events
if (nextEvent.getEventType() != XMLStreamConstants.CHARACTERS)
logger.warn("in start element {}: ignoring event {}: '{}'",startElement.getName(), nextEvent.getEventType(), nextEvent.toString().replace("\n", "\\n"));
}
reader.nextEvent();
nextEvent = reader.peek();
}
}
private EEnumLiteral parseEEnumLiteral(final XMLEventReader reader, Map<String, String> nameSpaces) throws XMLStreamException {
EEnumLiteral eEnumLiteral = new EEnumLiteral();
// get all the properties out of the element
StartElement startElement = reader.nextEvent().asStartElement();
nameSpaces = parseNameSpaces(startElement, nameSpaces);
for (Iterator attributeIterator = startElement.getAttributes(); attributeIterator.hasNext(); ) {
Attribute attribute = (Attribute) attributeIterator.next();
if (attribute.getName().equals(XSI_TYPE)) {
if (!attribute.getValue().equals("ecore:EEnumLiteral")) {
throw new XMIParseException("Expected ecore:EEnumLiteral but found " + attribute.getValue(), attribute.getLocation());
}
} else {
switch (attribute.getName().getLocalPart()) {
// from ENamedElement
case "name":
eEnumLiteral.setName(attribute.getValue());
break;
// from EEnumLiteral
case "value":
eEnumLiteral.setValue(Integer.valueOf(attribute.getValue()));
break;
default:
logger.warn("ignoring attribute {}:{}", attribute.getName().getPrefix(), attribute.getName().getLocalPart());
}
}
}
// parse the contained elements
XMLEvent nextEvent = reader.peek();
while (true) {
if (nextEvent.isStartElement()) {
final StartElement nextElement = nextEvent.asStartElement();
switch (nextElement.getName().getLocalPart()) {
case "eAnnotations":
eEnumLiteral.addEAnnotation(parseEAnnotation(reader, nameSpaces));
break;
default:
logger.warn("ignoring element {}:{}", nextElement.getName().getPrefix(), nextElement.getName().getLocalPart());
}
} else if (nextEvent.isEndElement() && nextEvent.asEndElement().getName().equals(startElement.getName())) {
reader.nextEvent();
return eEnumLiteral;
} else {
// ignore all other events
if (nextEvent.getEventType() != XMLStreamConstants.CHARACTERS)
logger.warn("in start element {}: ignoring event {}: '{}'",startElement.getName(), nextEvent.getEventType(), nextEvent.toString().replace("\n", "\\n"));
}
reader.nextEvent();
nextEvent = reader.peek();
}
} }
private ETypeParameter parseETypeParameter(final XMLEventReader reader, Map<String, String> nameSpaces) throws XMLStreamException { private ETypeParameter parseETypeParameter(final XMLEventReader reader, Map<String, String> nameSpaces) throws XMLStreamException {
......
...@@ -2,16 +2,61 @@ package de.tudresden.inf.st.e2j.parser; ...@@ -2,16 +2,61 @@ package de.tudresden.inf.st.e2j.parser;
import de.tudresden.inf.st.e2j.jastadd.model.EObject; import de.tudresden.inf.st.e2j.jastadd.model.EObject;
import de.tudresden.inf.st.e2j.jastadd.model.EPackage; import de.tudresden.inf.st.e2j.jastadd.model.EPackage;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtensionContext;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.ArgumentsProvider;
import org.junit.jupiter.params.provider.ArgumentsSource;
import java.io.FileNotFoundException; import java.io.*;
import java.io.IOException; import java.nio.charset.StandardCharsets;
import java.io.InputStream; import java.util.stream.Stream;
import java.io.PrintWriter;
class ParserTest { class ParserTest {
private static Logger logger = LogManager.getLogger(ParserTest.class);
@ParameterizedTest
@ArgumentsSource(EcoreFileProvider.class)
void parseEcore(String fileName) {
logger.info("Parsing file src/test/resources/ecore/zoo/{}", fileName);
EObject ePackage = null;
EcoreParser parser = new EcoreParser();
try (InputStream stream = this.getClass().getResourceAsStream("/ecore/zoo/" + fileName)) {
Assertions.assertNotNull(stream, "unable to load resource '" + fileName + "'");
ePackage = parser.parse(stream).get(0);
} catch (IOException | XMIParseException e) {
Assertions.fail(e);
}
Assertions.assertNotNull(ePackage);
Assertions.assertTrue(ePackage instanceof EPackage);
EPackage p = (EPackage) ePackage;
StringBuilder b = new StringBuilder();
logger.info("writing {} packages", p.getPackageList().size());
p.writeXMI(b, "ISO-8859-1");
try (PrintWriter out = new PrintWriter("src/test/resources/ecore/zoo-gen/" + fileName, StandardCharsets.ISO_8859_1.name())) {
out.print(b.toString());
} catch (FileNotFoundException | UnsupportedEncodingException e) {
Assertions.fail("unable to write output file", e);
}
}
@Test @Test
void parseBigraph() { void parseBigraph() {
...@@ -23,7 +68,7 @@ class ParserTest { ...@@ -23,7 +68,7 @@ class ParserTest {
try (InputStream stream = this.getClass().getResourceAsStream(fileName)) { try (InputStream stream = this.getClass().getResourceAsStream(fileName)) {
Assertions.assertNotNull(stream, "unable to load resource '" + fileName + "'"); Assertions.assertNotNull(stream, "unable to load resource '" + fileName + "'");
ePackage = parser.parse(stream); ePackage = parser.parse(stream).get(0);
} catch (IOException | XMIParseException e) { } catch (IOException | XMIParseException e) {
Assertions.fail(e); Assertions.fail(e);
} }
...@@ -58,7 +103,7 @@ class ParserTest { ...@@ -58,7 +103,7 @@ class ParserTest {
try (InputStream stream = this.getClass().getResourceAsStream(fileName)) { try (InputStream stream = this.getClass().getResourceAsStream(fileName)) {
Assertions.assertNotNull(stream, "unable to load resource '" + fileName + "'"); Assertions.assertNotNull(stream, "unable to load resource '" + fileName + "'");
ePackage = parser.parse(stream); ePackage = parser.parse(stream).get(0);
} catch (IOException | XMIParseException e) { } catch (IOException | XMIParseException e) {
Assertions.fail(e); Assertions.fail(e);
} }
...@@ -82,4 +127,23 @@ class ParserTest { ...@@ -82,4 +127,23 @@ class ParserTest {
System.out.println(b.toString()); System.out.println(b.toString());
} }
public static class EcoreFileProvider implements ArgumentsProvider {
@Override
public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
try (InputStream stream = this.getClass().getResourceAsStream("/ecore/zoo")) {
return new BufferedReader(new InputStreamReader(stream))
.lines()
.filter(fileName -> fileName.endsWith(".ecore"))
.map(Arguments::of);
} catch (IOException e) {
Assertions.fail(e);
}
// no stream if something fails
return Stream.empty();
}
}
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment