blob: 0df599f0edf533d66feca70a2c3285fb3a42b1dc [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2014, 2018 Willink Transformations and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* E.D.Willink - initial API and implementation
*******************************************************************************/
package org.eclipse.ocl.examples.build.textile;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.emf.common.util.TreeIterator;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.ocl.pivot.Comment;
import org.eclipse.ocl.pivot.Constraint;
import org.eclipse.ocl.pivot.DataType;
import org.eclipse.ocl.pivot.Element;
import org.eclipse.ocl.pivot.Iteration;
import org.eclipse.ocl.pivot.Model;
import org.eclipse.ocl.pivot.Namespace;
import org.eclipse.ocl.pivot.Operation;
import org.eclipse.ocl.pivot.Property;
import org.eclipse.ocl.pivot.internal.prettyprint.PrettyPrintOptions;
import org.eclipse.ocl.pivot.internal.prettyprint.PrettyPrinter;
import org.eclipse.ocl.pivot.utilities.Nameable;
import org.eclipse.ocl.xtext.markup.MarkupUtils;
import org.eclipse.ocl.xtext.markupcs.FontElement;
import org.eclipse.ocl.xtext.markupcs.Markup;
import org.eclipse.ocl.xtext.markupcs.MarkupElement;
import org.eclipse.ocl.xtext.markupcs.NewLineElement;
import org.eclipse.ocl.xtext.markupcs.NullElement;
import org.eclipse.ocl.xtext.markupcs.OCLCodeElement;
import org.eclipse.ocl.xtext.markupcs.OCLTextElement;
import org.eclipse.ocl.xtext.markupcs.TextElement;
import org.eclipse.ocl.xtext.markupcs.util.MarkupSwitch;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.parser.IParseResult;
public abstract class GenerateTextileForLibraryUtils extends GenerateTextileForLibrary
{
protected final @NonNull Comparator<Nameable> nameableComparator = new Comparator<Nameable>()
{
public int compare(Nameable o1, Nameable o2) {
String m1 = o1.getName();
String m2 = o2.getName();
if (m1 == null) m1 = "";
if (m2 == null) m2 = "";
return m1.compareTo(m2);
}
};
protected final @NonNull Comparator<Iteration> iterationComparator = new Comparator<Iteration>()
{
public int compare(Iteration o1, Iteration o2) {
String m1 = o1.getName();
String m2 = o2.getName();
if (m1 == null) m1 = "";
if (m2 == null) m2 = "";
int diff = m1.compareTo(m2);
if (diff != 0) return diff;
int s1 = o1.getOwnedIterators().size();
int s2 = o2.getOwnedIterators().size();
return s1 - s2;
}
};
protected static final @NonNull Comparator<Operation> operationComparator = new OperationComparator();
protected static final class OperationComparator implements Comparator<Operation>
{
public static Map<String,String> nameMap = new HashMap<String, String>();
static {
nameMap.put("=", " 1");
nameMap.put("<>", " 2");
nameMap.put("<", " 3");
nameMap.put("<=", " 4");
nameMap.put(">=", " 5");
nameMap.put(">", " 6");
}
public int compare(Operation o1, Operation o2) {
String m1 = o1.getName();
String m2 = o2.getName();
if (m1 == null) m1 = "";
if (m2 == null) m2 = "";
String k1 = nameMap.get(m1);
String k2 = nameMap.get(m2);
if (k1 != null) m1 = k1;
if (k2 != null) m2 = k2;
int diff = m1.compareTo(m2);
if (diff != 0) return diff;
int s1 = o1.getOwnedParameters().size();
int s2 = o2.getOwnedParameters().size();
return s1 - s2;
}
}
protected static class MarkupToTextile extends MarkupSwitch<@Nullable String>
{
@SuppressWarnings("unused") private final Namespace scope;
private final StringBuilder s = new StringBuilder();
public MarkupToTextile(Namespace scope) {
this.scope = scope;
}
@Override
public String caseFontElement(FontElement element) {
String tag = element.getFont().equals("e") ? "_" : "*";
s.append(tag);
for (MarkupElement subElement : element.getElements()) {
doSwitch(subElement);
}
s.append(tag);
return s.toString();
}
@Override
public String caseMarkupElement(MarkupElement element) {
s.append("$$");
s.append(element.eClass().getName());
return s.toString();
}
@Override
public String caseNewLineElement(NewLineElement element) {
s.append(element.getText());
return s.toString();
}
@Override
public String caseNullElement(NullElement object) {
return s.toString();
}
@Override
public String caseOCLCodeElement(OCLCodeElement element) {
s.append("bc.. \n");
for (MarkupElement subElement : element.getElements()) {
doSwitch(subElement);
}
s.append("\n");
s.append("p. \n");
s.append("\n");
return s.toString();
}
@Override
public String caseOCLTextElement(OCLTextElement element) {
s.append("@");
for (MarkupElement subElement : element.getElements()) {
doSwitch(subElement);
}
s.append("@");
return s.toString();
}
@Override
public String caseTextElement(TextElement element) {
for (String text : element.getText()) {
s.append(text);
}
return s.toString();
}
};
public static PrettyPrintOptions.@NonNull Global createOptions(@Nullable Namespace scope) {
PrettyPrintOptions.Global options = new PrettyPrintOptions.Global(scope)
{
@Override
public @Nullable Set<String> getReservedNames() {
return null;
}
@Override
public @Nullable Set<String> getRestrictedNames() {
return null;
}
};
return options;
}
public Markup decode(@NonNull Comment comment, @Nullable Namespace scope) {
String body = comment.getBody();
if (body == null) {
throw new NullPointerException("Missing Comment body");
}
IParseResult parseResult = MarkupUtils.decode(body);
if (parseResult == null) {
throw new NullPointerException("Missing ParseResult for \"" + body + "\"");
}
Markup markup = (Markup) parseResult.getRootASTElement();
for (INode parseError : parseResult.getSyntaxErrors()) {
System.out.println(parseError);
}
if (markup == null) {
throw new NullPointerException("Missing prsed content for \"" + body + "\"");
}
return markup;
}
protected @NonNull List<Property> getSortedAssociations(org.eclipse.ocl.pivot.@NonNull Class asClass) {
Set<Property> allElements = new HashSet<Property>();
for (Property asProperty : asClass.getOwnedProperties()) {
// [let pAssociations : Sequence(Property) = pClass.ownedAttribute->select(e | not e.type.oclIsKindOf(DataType) and e.type.owningTemplateParameter->isEmpty())->asSequence()]
if (!(asProperty.getType() instanceof DataType)) {
allElements.add(asProperty);
}
}
List<Property> sortedElements = new ArrayList<Property>(allElements);
Collections.sort(sortedElements, nameableComparator);
return sortedElements;
}
protected @NonNull List<Property> getSortedAttributes(org.eclipse.ocl.pivot.@NonNull Class asClass) {
Set<Property> allElements = new HashSet<Property>();
for (Property asProperty : asClass.getOwnedProperties()) {
if (asProperty.getType() instanceof DataType) {
allElements.add(asProperty);
}
}
List<Property> sortedElements = new ArrayList<Property>(allElements);
Collections.sort(sortedElements, nameableComparator);
return sortedElements;
}
protected @NonNull List<org.eclipse.ocl.pivot.Class> getSortedClasses(@NonNull Model model) {
Set<org.eclipse.ocl.pivot.Class> allElements = new HashSet<org.eclipse.ocl.pivot.Class>();
TreeIterator<EObject> tit = model.eAllContents();
while (tit.hasNext()) {
EObject eObject = tit.next();
if (eObject instanceof org.eclipse.ocl.pivot.Class) {
allElements.add((org.eclipse.ocl.pivot.Class)eObject);
}
}
List<org.eclipse.ocl.pivot.Class> sortedElements = new ArrayList<org.eclipse.ocl.pivot.Class>(allElements);
Collections.sort(sortedElements, nameableComparator);
return sortedElements;
}
protected @NonNull List<Constraint> getSortedConstraints(@NonNull Operation asOperation) {
Set<Constraint> allElements = new HashSet<Constraint>();
for (Constraint asConstraint : asOperation.getOwnedConstraints()) {
allElements.add(asConstraint);
}
List<Constraint> sortedElements = new ArrayList<Constraint>(allElements);
Collections.sort(sortedElements, nameableComparator);
return sortedElements;
}
protected @NonNull List<Iteration> getSortedIterations(org.eclipse.ocl.pivot.@NonNull Class asClass) {
Set<Iteration> allElements = new HashSet<Iteration>();
for (Operation asOperation : asClass.getOwnedOperations()) {
if (asOperation instanceof Iteration) {
allElements.add((Iteration) asOperation);
}
}
List<Iteration> sortedElements = new ArrayList<Iteration>(allElements);
Collections.sort(sortedElements, iterationComparator);
return sortedElements;
}
protected @NonNull List<Operation> getSortedOperations(org.eclipse.ocl.pivot.@NonNull Class asClass) {
Set<Operation> allElements = new HashSet<Operation>();
for (Operation asOperation : asClass.getOwnedOperations()) {
if (!(asOperation instanceof Iteration)) {
allElements.add(asOperation);
}
}
List<Operation> sortedElements = new ArrayList<Operation>(allElements);
Collections.sort(sortedElements, operationComparator);
return sortedElements;
}
protected @NonNull List<Constraint> getSortedPostconditions(@NonNull Operation asOperation) {
Set<Constraint> allElements = new HashSet<Constraint>(asOperation.getOwnedPostconditions());
List<Constraint> sortedElements = new ArrayList<Constraint>(allElements);
Collections.sort(sortedElements, nameableComparator);
return sortedElements;
}
protected @NonNull List<Constraint> getSortedPreconditions(@NonNull Operation asOperation) {
Set<Constraint> allElements = new HashSet<Constraint>(asOperation.getOwnedPreconditions());
List<Constraint> sortedElements = new ArrayList<Constraint>(allElements);
Collections.sort(sortedElements, nameableComparator);
return sortedElements;
}
protected String prettyPrint(@NonNull Comment comment, Namespace scope) {
Markup markup = decode(comment, scope);
StringBuilder s = new StringBuilder();
for (MarkupElement element : markup.getElements()) {
s.append(prettyPrint(element, scope));
}
return s.toString();
}
protected String prettyPrint(@NonNull Constraint constraint, Namespace scope) {
PrettyPrintOptions options = createOptions(scope);
// PrettyPrintExprVisitor visitor = new PrettyPrintExprVisitor(options);
PrettyPrinter printer = PrettyPrinter.createPrinter(constraint, options);
try {
printer.appendElement(constraint);
String string = printer.toString(options.getIndentStep(), options.getLinelength());
// System.out.println("Expr-prettyPrint : " + element.eClass().getName() + "/" + element.eClass().getName() + " => " + string);
return string;
}
catch (Exception e) {
e.printStackTrace();
return printer.toString() + " ... " + e.getClass().getName() + " - " + e.getLocalizedMessage();
}
}
protected String prettyPrint(@NonNull Element element, Namespace scope) {
PrettyPrintOptions options = createOptions(scope);
PrettyPrinter printer = PrettyPrinter.createNamePrinter(element, options);
try {
printer.appendElement(element);
String string = printer.toString(options.getIndentStep(), options.getLinelength());
// System.out.println("Name-prettyPrint : " + element.eClass().getName() + "/" + element.eClass().getName() + " => " + string);
return string;
}
catch (Exception e) {
e.printStackTrace();
return printer.toString() + " ... " + e.getClass().getName() + " - " + e.getLocalizedMessage();
}
}
protected String prettyPrint(MarkupElement element, Namespace scope) {
return new MarkupToTextile(scope).doSwitch(element);
}
}